feat: advertise address for 5G NFs (#825)

This commit is contained in:
Sukchan Lee 2021-03-19 21:01:38 +09:00
parent 09780e3fed
commit 182a680d51
7 changed files with 123 additions and 39 deletions

View File

@ -64,21 +64,21 @@ logger:
# o Provide custom SGW-U GTP-U address to be advertised inside S1AP messages # o Provide custom SGW-U GTP-U address to be advertised inside S1AP messages
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_addr: 172.24.15.30 # advertise: 172.24.15.30
# #
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_addr: # advertise:
# - 127.0.0.1 # - 127.0.0.1
# - ::1 # - ::1
# #
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_name: sgw1.epc.mnc001.mcc001.3gppnetwork.org # advertise: sgw1.epc.mnc001.mcc001.3gppnetwork.org
# #
# gtpu: # gtpu:
# - dev: ens3 # - dev: ens3
# advertise_name: sgw1.epc.mnc001.mcc001.3gppnetwork.org # advertise: sgw1.epc.mnc001.mcc001.3gppnetwork.org
# #
sgwu: sgwu:
pfcp: pfcp:

View File

@ -64,21 +64,21 @@ logger:
# o Provide custom UPF GTP-U address to be advertised inside NGAP messages # o Provide custom UPF GTP-U address to be advertised inside NGAP messages
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_addr: 172.24.15.30 # advertise: 172.24.15.30
# #
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_addr: # advertise:
# - 127.0.0.1 # - 127.0.0.1
# - ::1 # - ::1
# #
# gtpu: # gtpu:
# - addr: 10.4.128.21 # - addr: 10.4.128.21
# advertise_name: upf1.5gc.mnc001.mcc001.3gppnetwork.org # advertise: upf1.5gc.mnc001.mcc001.3gppnetwork.org
# #
# gtpu: # gtpu:
# - dev: ens3 # - dev: ens3
# advertise_name: upf1.5gc.mnc001.mcc001.3gppnetwork.org # advertise: upf1.5gc.mnc001.mcc001.3gppnetwork.org
# #
# <Subnet for UE network> # <Subnet for UE network>
# #

View File

@ -215,10 +215,10 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
do { do {
int family = AF_UNSPEC; int family = AF_UNSPEC;
int i, num = 0; int i, num_of_hostname = 0;
int adv_num = 0;
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME]; const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
const char *adv_hostname[OGS_MAX_NUM_OF_HOSTNAME]; int num_of_advertise = 0;
const char *advertise[OGS_MAX_NUM_OF_HOSTNAME];
uint16_t port = self.gtpu_port; uint16_t port = self.gtpu_port;
const char *dev = NULL; const char *dev = NULL;
ogs_sockaddr_t *addr = NULL; ogs_sockaddr_t *addr = NULL;
@ -283,35 +283,34 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
break; break;
} }
ogs_assert(num < OGS_MAX_NUM_OF_HOSTNAME); ogs_assert(num_of_hostname <
hostname[num++] = OGS_MAX_NUM_OF_HOSTNAME);
hostname[num_of_hostname++] =
ogs_yaml_iter_value(&hostname_iter); ogs_yaml_iter_value(&hostname_iter);
} while ( } while (
ogs_yaml_iter_type(&hostname_iter) == ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE); YAML_SEQUENCE_NODE);
} else if (!strcmp(gtpu_key, "advertise_addr") || } else if (!strcmp(gtpu_key, "advertise")) {
!strcmp(gtpu_key, "advertise_name")) { ogs_yaml_iter_t advertise_iter;
ogs_yaml_iter_t adv_hostname_iter;
ogs_yaml_iter_recurse( ogs_yaml_iter_recurse(
&gtpu_iter, &adv_hostname_iter); &gtpu_iter, &advertise_iter);
ogs_assert(ogs_yaml_iter_type( ogs_assert(ogs_yaml_iter_type(
&adv_hostname_iter) != YAML_MAPPING_NODE); &advertise_iter) != YAML_MAPPING_NODE);
do { do {
if (ogs_yaml_iter_type( if (ogs_yaml_iter_type(&advertise_iter) ==
&adv_hostname_iter) ==
YAML_SEQUENCE_NODE) { YAML_SEQUENCE_NODE) {
if (!ogs_yaml_iter_next( if (!ogs_yaml_iter_next(
&adv_hostname_iter)) &advertise_iter))
break; break;
} }
ogs_assert(adv_num < ogs_assert(num_of_advertise <
OGS_MAX_NUM_OF_HOSTNAME); OGS_MAX_NUM_OF_HOSTNAME);
adv_hostname[adv_num++] = advertise[num_of_advertise++] =
ogs_yaml_iter_value(&adv_hostname_iter); ogs_yaml_iter_value(&advertise_iter);
} while ( } while (
ogs_yaml_iter_type(&adv_hostname_iter) == ogs_yaml_iter_type(&advertise_iter) ==
YAML_SEQUENCE_NODE); YAML_SEQUENCE_NODE);
} else if (!strcmp(gtpu_key, "port")) { } else if (!strcmp(gtpu_key, "port")) {
const char *v = ogs_yaml_iter_value(&gtpu_iter); const char *v = ogs_yaml_iter_value(&gtpu_iter);
@ -338,7 +337,7 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
} }
addr = NULL; addr = NULL;
for (i = 0; i < num; i++) { for (i = 0; i < num_of_hostname; i++) {
rv = ogs_addaddrinfo(&addr, rv = ogs_addaddrinfo(&addr,
family, hostname[i], port, 0); family, hostname[i], port, 0);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
@ -364,9 +363,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
} }
adv_addr = NULL; adv_addr = NULL;
for (i = 0; i < adv_num; i++) { for (i = 0; i < num_of_advertise; i++) {
rv = ogs_addaddrinfo(&adv_addr, rv = ogs_addaddrinfo(&adv_addr,
family, adv_hostname[i], port, 0); family, advertise[i], port, 0);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
} }
rv = ogs_copyaddrinfo(&adv_addr6, adv_addr); rv = ogs_copyaddrinfo(&adv_addr6, adv_addr);

View File

@ -146,14 +146,17 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
ogs_yaml_iter_t sbi_array, sbi_iter; ogs_yaml_iter_t sbi_array, sbi_iter;
ogs_yaml_iter_recurse(&local_iter, &sbi_array); ogs_yaml_iter_recurse(&local_iter, &sbi_array);
do { do {
int family = AF_UNSPEC; int i, family = AF_UNSPEC;
int i, num = 0; int num = 0;
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME]; const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
int num_of_advertise = 0;
const char *advertise[OGS_MAX_NUM_OF_HOSTNAME];
const char *key = NULL;
const char *pem = NULL;
uint16_t port = self.http_port; uint16_t port = self.http_port;
const char *dev = NULL; const char *dev = NULL;
ogs_sockaddr_t *addr = NULL; ogs_sockaddr_t *addr = NULL;
const char *key = NULL;
const char *pem = NULL;
if (ogs_yaml_iter_type(&sbi_array) == if (ogs_yaml_iter_type(&sbi_array) ==
YAML_MAPPING_NODE) { YAML_MAPPING_NODE) {
@ -207,6 +210,28 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
} while ( } while (
ogs_yaml_iter_type(&hostname_iter) == ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE); YAML_SEQUENCE_NODE);
} else if (!strcmp(sbi_key, "advertise")) {
ogs_yaml_iter_t advertise_iter;
ogs_yaml_iter_recurse(&sbi_iter,
&advertise_iter);
ogs_assert(ogs_yaml_iter_type(
&advertise_iter) != YAML_MAPPING_NODE);
do {
if (ogs_yaml_iter_type(&advertise_iter) ==
YAML_SEQUENCE_NODE) {
if (!ogs_yaml_iter_next(
&advertise_iter))
break;
}
ogs_assert(num_of_advertise <
OGS_MAX_NUM_OF_HOSTNAME);
advertise[num_of_advertise++] =
ogs_yaml_iter_value(&advertise_iter);
} while (
ogs_yaml_iter_type(&advertise_iter) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(sbi_key, "port")) { } else if (!strcmp(sbi_key, "port")) {
const char *v = ogs_yaml_iter_value(&sbi_iter); const char *v = ogs_yaml_iter_value(&sbi_iter);
if (v) { if (v) {
@ -261,12 +286,23 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
} }
addr = NULL;
for (i = 0; i < num_of_advertise; i++) {
rv = ogs_addaddrinfo(&addr,
family, advertise[i], port, 0);
ogs_assert(rv == OGS_OK);
}
node = ogs_list_first(&list); node = ogs_list_first(&list);
if (node) { if (node) {
ogs_sbi_server_t *server = ogs_sbi_server_t *server =
ogs_sbi_server_add(node->addr); ogs_sbi_server_add(node->addr);
ogs_assert(server); ogs_assert(server);
if (addr && ogs_app()->parameter.no_ipv4 == 0)
ogs_sbi_server_set_advertise(
server, AF_INET, addr);
if (key) server->tls.key = key; if (key) server->tls.key = key;
if (pem) server->tls.pem = pem; if (pem) server->tls.pem = pem;
} }
@ -276,12 +312,20 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
ogs_sbi_server_add(node6->addr); ogs_sbi_server_add(node6->addr);
ogs_assert(server); ogs_assert(server);
if (addr && ogs_app()->parameter.no_ipv6 == 0)
ogs_sbi_server_set_advertise(
server, AF_INET6, addr);
if (key) server->tls.key = key; if (key) server->tls.key = key;
if (pem) server->tls.pem = pem; if (pem) server->tls.pem = pem;
} }
if (addr)
ogs_freeaddrinfo(addr);
ogs_socknode_remove_all(&list); ogs_socknode_remove_all(&list);
ogs_socknode_remove_all(&list6); ogs_socknode_remove_all(&list6);
} while (ogs_yaml_iter_type(&sbi_array) == } while (ogs_yaml_iter_type(&sbi_array) ==
YAML_SEQUENCE_NODE); YAML_SEQUENCE_NODE);
@ -395,6 +439,8 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
} else } else
ogs_warn("unknown key `%s`", tls_key); ogs_warn("unknown key `%s`", tls_key);
} }
} else if (!strcmp(sbi_key, "advertise")) {
/* Nothing in client */
} else } else
ogs_warn("unknown key `%s`", sbi_key); ogs_warn("unknown key `%s`", sbi_key);
} }
@ -781,18 +827,23 @@ void ogs_sbi_nf_instance_build_default(
hostname = NULL; hostname = NULL;
ogs_list_for_each(&ogs_sbi_self()->server_list, server) { ogs_list_for_each(&ogs_sbi_self()->server_list, server) {
ogs_assert(server->node.addr); ogs_sockaddr_t *advertise = NULL;
advertise = server->advertise;
if (!advertise)
advertise = server->node.addr;
ogs_assert(advertise);
/* First FQDN is selected */ /* First FQDN is selected */
if (!hostname) { if (!hostname) {
hostname = ogs_gethostname(server->node.addr); hostname = ogs_gethostname(advertise);
if (hostname) if (hostname)
continue; continue;
} }
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) { if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
ogs_sockaddr_t *addr = NULL; ogs_sockaddr_t *addr = NULL;
ogs_copyaddrinfo(&addr, server->node.addr); ogs_copyaddrinfo(&addr, advertise);
ogs_assert(addr); ogs_assert(addr);
if (addr->ogs_sa_family == AF_INET) { if (addr->ogs_sa_family == AF_INET) {
@ -840,11 +891,16 @@ ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
hostname = NULL; hostname = NULL;
ogs_list_for_each(&ogs_sbi_self()->server_list, server) { ogs_list_for_each(&ogs_sbi_self()->server_list, server) {
ogs_assert(server->node.addr); ogs_sockaddr_t *advertise = NULL;
advertise = server->advertise;
if (!advertise)
advertise = server->node.addr;
ogs_assert(advertise);
/* First FQDN is selected */ /* First FQDN is selected */
if (!hostname) { if (!hostname) {
hostname = ogs_gethostname(server->node.addr); hostname = ogs_gethostname(advertise);
if (hostname) if (hostname)
continue; continue;
} }
@ -852,7 +908,7 @@ ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) { if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
int port = 0; int port = 0;
ogs_sockaddr_t *addr = NULL; ogs_sockaddr_t *addr = NULL;
ogs_copyaddrinfo(&addr, server->node.addr); ogs_copyaddrinfo(&addr, advertise);
ogs_assert(addr); ogs_assert(addr);
port = OGS_PORT(addr); port = OGS_PORT(addr);

View File

@ -67,6 +67,7 @@ char *ogs_uridup(bool https, ogs_sockaddr_t *addr, ogs_sbi_header_t *h)
char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h) char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h)
{ {
ogs_sockaddr_t *advertise = NULL;
bool https = false; bool https = false;
ogs_assert(server); ogs_assert(server);
@ -75,7 +76,13 @@ char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h)
if (server->tls.key && server->tls.pem) if (server->tls.key && server->tls.pem)
https = true; https = true;
return ogs_uridup(https, server->node.addr, h); advertise = server->advertise;
if (!advertise)
advertise = server->node.addr;
ogs_assert(advertise);
return ogs_uridup(https, advertise, h);
} }
char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h) char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h)

View File

@ -78,6 +78,8 @@ void ogs_sbi_server_remove(ogs_sbi_server_t *server)
ogs_assert(server->node.addr); ogs_assert(server->node.addr);
ogs_freeaddrinfo(server->node.addr); ogs_freeaddrinfo(server->node.addr);
if (server->advertise)
ogs_freeaddrinfo(server->advertise);
ogs_pool_free(&server_pool, server); ogs_pool_free(&server_pool, server);
} }
@ -90,6 +92,22 @@ void ogs_sbi_server_remove_all(void)
ogs_sbi_server_remove(server); ogs_sbi_server_remove(server);
} }
void ogs_sbi_server_set_advertise(
ogs_sbi_server_t *server, int family, ogs_sockaddr_t *advertise)
{
ogs_sockaddr_t *addr = NULL;
ogs_assert(server);
ogs_assert(advertise);
ogs_copyaddrinfo(&addr, advertise);
if (family != AF_UNSPEC)
ogs_filteraddrinfo(&addr, family);
if (addr)
server->advertise = addr;
}
void ogs_sbi_server_start_all( void ogs_sbi_server_start_all(
int (*cb)(ogs_sbi_request_t *request, void *data)) int (*cb)(ogs_sbi_request_t *request, void *data))
{ {

View File

@ -32,6 +32,7 @@ typedef struct ogs_sbi_stream_s ogs_sbi_stream_t;
typedef struct ogs_sbi_server_s { typedef struct ogs_sbi_server_s {
ogs_socknode_t node; ogs_socknode_t node;
ogs_sockaddr_t *advertise;
struct { struct {
const char *key; const char *key;
@ -65,6 +66,9 @@ ogs_sbi_server_t *ogs_sbi_server_add(ogs_sockaddr_t *addr);
void ogs_sbi_server_remove(ogs_sbi_server_t *server); void ogs_sbi_server_remove(ogs_sbi_server_t *server);
void ogs_sbi_server_remove_all(void); void ogs_sbi_server_remove_all(void);
void ogs_sbi_server_set_advertise(
ogs_sbi_server_t *server, int family, ogs_sockaddr_t *advertise);
void ogs_sbi_server_start_all( void ogs_sbi_server_start_all(
int (*cb)(ogs_sbi_request_t *request, void *data)); int (*cb)(ogs_sbi_request_t *request, void *data));
void ogs_sbi_server_stop_all(void); void ogs_sbi_server_stop_all(void);