[PFCP] Support pfcp advertise address

This commit is contained in:
mitmitmitm 2023-02-23 08:59:59 +01:00 committed by Sukchan Lee
parent 10477ecdc9
commit 1d8324af9f
17 changed files with 128 additions and 38 deletions

View File

@ -70,6 +70,13 @@ logger:
# option:
# so_bindtodevice: vrf-blue
#
# o Provide custom PFCP address to be advertised in PFCP association
# request/respond
# sgwc:
# pfcp:
# - addr: 0.0.0.0
# advertise: open5gs-smf.svc.local
#
sgwc:
gtpc:
- addr: 127.0.0.3

View File

@ -45,6 +45,13 @@ logger:
# option:
# so_bindtodevice: vrf-blue
#
# o Provide custom PFCP address to be advertised in PFCP association
# request/respond
# sgwc:
# pfcp:
# - addr: 0.0.0.0
# advertise: open5gs-smf.svc.local
#
# <GTP-U Server>
#
# o GTP-U Server(127.0.0.6:2152, [::1]:2152)

View File

@ -274,6 +274,13 @@ sbi:
# option:
# so_bindtodevice: vrf-blue
#
# o Provide custom PFCP address to be advertised to UPF in PFCP association
# request/respond
# smf:
# pfcp:
# - addr: 0.0.0.0
# advertise: open5gs-smf.svc.local
#
# <GTP-C Server>
#
# o GTP-C Server(127.0.0.4:2123, [fd69:f21d:873c:fa::3]:2123)

View File

@ -45,6 +45,13 @@ logger:
# option:
# so_bindtodevice: vrf-blue
#
# o Provide custom PFCP address to be advertised to SMF in PFCP association
# request/respond
# upf:
# pfcp:
# - addr: 0.0.0.0
# advertise: open5gs-smf.svc.local
#
# <GTP-U Server>>
#
# o GTP-U Server(127.0.0.7:2152, [::1]:2152)

View File

@ -94,10 +94,7 @@ ogs_pkbuf_t *ogs_pfcp_cp_build_association_setup_request(uint8_t type)
req = &pfcp_message->pfcp_association_setup_request;
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &node_id_len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &node_id_len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);
@ -142,10 +139,7 @@ ogs_pkbuf_t *ogs_pfcp_cp_build_association_setup_response(uint8_t type,
rsp = &pfcp_message->pfcp_association_setup_response;
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &node_id_len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &node_id_len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);
@ -197,10 +191,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_request(uint8_t type)
req = &pfcp_message->pfcp_association_setup_request;
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &node_id_len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &node_id_len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);
@ -268,10 +259,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type,
rsp = &pfcp_message->pfcp_association_setup_response;
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &node_id_len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &node_id_len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);

View File

@ -165,6 +165,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
int family = AF_UNSPEC;
int i, num = 0;
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
int num_of_advertise = 0;
const char *advertise[OGS_MAX_NUM_OF_HOSTNAME];
uint16_t port = self.pfcp_port;
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
@ -224,6 +226,27 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
} while (
ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(pfcp_key, "advertise")) {
ogs_yaml_iter_t hostname_iter;
ogs_yaml_iter_recurse(&pfcp_iter,
&hostname_iter);
ogs_assert(ogs_yaml_iter_type(&hostname_iter) !=
YAML_MAPPING_NODE);
do {
if (ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE) {
if (!ogs_yaml_iter_next(
&hostname_iter))
break;
}
ogs_assert(num < OGS_MAX_NUM_OF_HOSTNAME);
advertise[num_of_advertise++] =
ogs_yaml_iter_value(&hostname_iter);
} while (
ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(pfcp_key, "port")) {
const char *v = ogs_yaml_iter_value(&pfcp_iter);
if (v) {
@ -263,6 +286,27 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
ogs_freeaddrinfo(addr);
}
addr = NULL;
for (i = 0; i < num_of_advertise; i++) {
rv = ogs_addaddrinfo(&addr,
family, advertise[i], port, 0);
ogs_assert(rv == OGS_OK);
}
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0 &&
!self.pfcp_advertise) {
ogs_copyaddrinfo(&self.pfcp_advertise, addr);
ogs_filteraddrinfo(&self.pfcp_advertise, AF_INET);
}
if (ogs_app()->parameter.no_ipv6 == 0 &&
!self.pfcp_advertise6) {
ogs_copyaddrinfo(&self.pfcp_advertise6, addr);
ogs_filteraddrinfo(&self.pfcp_advertise6, AF_INET);
}
ogs_freeaddrinfo(addr);
}
if (dev) {
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ?
@ -465,6 +509,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
} while (
ogs_yaml_iter_type(&hostname_iter) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(pfcp_key, "advertise")) {
/* Nothing in client */
} else if (!strcmp(pfcp_key, "port")) {
const char *v = ogs_yaml_iter_value(&pfcp_iter);
if (v) port = atoi(v);

View File

@ -48,6 +48,8 @@ typedef struct ogs_pfcp_context_s {
ogs_list_t pfcp_list; /* PFCP IPv4 Server List */
ogs_list_t pfcp_list6; /* PFCP IPv6 Server List */
ogs_sockaddr_t *pfcp_advertise; /* PFCP Advertise Addr */
ogs_sockaddr_t *pfcp_advertise6;
ogs_sock_t *pfcp_sock; /* PFCP IPv4 Socket */
ogs_sock_t *pfcp_sock6; /* PFCP IPv6 Socket */
ogs_sockaddr_t *pfcp_addr; /* PFCP IPv4 Address */

View File

@ -19,17 +19,45 @@
#include "ogs-pfcp.h"
int ogs_pfcp_sockaddr_to_node_id(
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, int prefer_ipv4,
ogs_pfcp_node_id_t *node_id, int *len)
int ogs_pfcp_sockaddr_to_node_id(ogs_pfcp_node_id_t *node_id, int *len)
{
const int hdr_len = 1;
char *hostname = NULL;
ogs_sockaddr_t *advertise = ogs_pfcp_self()->pfcp_advertise;
ogs_sockaddr_t *advertise6 = ogs_pfcp_self()->pfcp_advertise6;
ogs_sockaddr_t *addr = ogs_pfcp_self()->pfcp_addr;
ogs_sockaddr_t *addr6 = ogs_pfcp_self()->pfcp_addr6;
int prefer_ipv4 = ogs_app()->parameter.prefer_ipv4;
ogs_assert(node_id);
memset(node_id, 0, sizeof *node_id);
if (advertise || advertise6) {
hostname = ogs_gethostname(advertise ? advertise : advertise6);
if (hostname) {
node_id->type = OGS_PFCP_NODE_ID_FQDN;
*len = ogs_fqdn_build(node_id->fqdn,
hostname, strlen(hostname)) + hdr_len;
return OGS_OK;
}
}
if (advertise && (prefer_ipv4 || !advertise6)) {
node_id->type = OGS_PFCP_NODE_ID_IPV4;
node_id->addr = advertise->sin.sin_addr.s_addr;
*len = OGS_IPV4_LEN + hdr_len;
return OGS_OK;
}
if (advertise6) {
node_id->type = OGS_PFCP_NODE_ID_IPV6;
memcpy(node_id->addr6, advertise6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
*len = OGS_IPV6_LEN + hdr_len;
return OGS_OK;
}
if (addr) {
hostname = ogs_gethostname(addr);
if (hostname) {

View File

@ -28,9 +28,7 @@
extern "C" {
#endif
int ogs_pfcp_sockaddr_to_node_id(
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, int prefer_ipv4,
ogs_pfcp_node_id_t *node_id, int *len);
int ogs_pfcp_sockaddr_to_node_id(ogs_pfcp_node_id_t *node_id, int *len);
int ogs_pfcp_f_seid_to_sockaddr(
ogs_pfcp_f_seid_t *f_seid, uint16_t port, ogs_sockaddr_t **list);

View File

@ -156,6 +156,9 @@ void sgwc_pfcp_close(void)
ogs_list_for_each(&ogs_pfcp_self()->pfcp_peer_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise6);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

View File

@ -48,10 +48,7 @@ ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request(
req = &pfcp_message->pfcp_session_establishment_request;
/* Node ID */
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);

View File

@ -156,6 +156,9 @@ void sgwu_pfcp_close(void)
ogs_list_for_each(&ogs_pfcp_self()->pfcp_peer_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise6);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

View File

@ -43,10 +43,7 @@ ogs_pkbuf_t *sgwu_sxa_build_session_establishment_response(uint8_t type,
rsp = &pfcp_message->pfcp_session_establishment_response;
/* Node ID */
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);

View File

@ -56,10 +56,7 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request(
req = &pfcp_message->pfcp_session_establishment_request;
/* Node ID */
rv = ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &len);
rv = ogs_pfcp_sockaddr_to_node_id(&node_id, &len);
if (rv != OGS_OK) {
ogs_error("ogs_pfcp_sockaddr_to_node_id() failed");
ogs_free(pfcp_message);

View File

@ -196,6 +196,9 @@ void smf_pfcp_close(void)
ogs_list_for_each(&ogs_pfcp_self()->pfcp_peer_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise6);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

View File

@ -44,10 +44,7 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type,
rsp = &pfcp_message->pfcp_session_establishment_response;
/* Node ID */
ogs_pfcp_sockaddr_to_node_id(
ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6,
ogs_app()->parameter.prefer_ipv4,
&node_id, &len);
ogs_pfcp_sockaddr_to_node_id(&node_id, &len);
rsp->node_id.presence = 1;
rsp->node_id.data = &node_id;
rsp->node_id.len = len;

View File

@ -159,6 +159,9 @@ void upf_pfcp_close(void)
ogs_list_for_each(&ogs_pfcp_self()->pfcp_peer_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise);
ogs_freeaddrinfo(ogs_pfcp_self()->pfcp_advertise6);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}