Initial proposal CUPS using PFCP

This commit is contained in:
Sukchan Lee 2020-04-26 15:36:05 -04:00
parent 37a69e6332
commit ae75f43a88
206 changed files with 21116 additions and 3406 deletions

View file

@ -34,16 +34,17 @@ ogs_sock_t *ogs_pfcp_server(ogs_socknode_t *node)
return pfcp;
}
int ogs_pfcp_connect(ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *gnode)
int ogs_pfcp_connect(
ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *node)
{
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(ipv4 || ipv6);
ogs_assert(gnode);
ogs_assert(gnode->sa_list);
ogs_assert(node);
ogs_assert(node->sa_list);
addr = gnode->sa_list;
addr = node->sa_list;
while (addr) {
ogs_sock_t *sock = NULL;
@ -55,11 +56,11 @@ int ogs_pfcp_connect(ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *gnode)
ogs_assert_if_reached();
if (sock) {
ogs_info("pfcp_connect() [%s]:%d",
ogs_info("ogs_pfcp_connect() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
gnode->sock = sock;
memcpy(&gnode->remote_addr, addr, sizeof gnode->remote_addr);
node->sock = sock;
memcpy(&node->addr, addr, sizeof node->addr);
break;
}
@ -67,23 +68,23 @@ int ogs_pfcp_connect(ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *gnode)
}
if (addr == NULL) {
ogs_log_message(OGS_LOG_WARN, ogs_socket_errno,
"pfcp_connect() [%s]:%d failed",
OGS_ADDR(gnode->sa_list, buf), OGS_PORT(gnode->sa_list));
ogs_error("ogs_pfcp_connect() [%s]:%d failed",
OGS_ADDR(node->sa_list, buf), OGS_PORT(node->sa_list));
ogs_error("Please check the IP version between SMF and UPF nodes.");
return OGS_ERROR;
}
return OGS_OK;
}
int ogs_pfcp_send(ogs_pfcp_node_t *gnode, ogs_pkbuf_t *pkbuf)
int ogs_pfcp_send(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
{
ssize_t sent;
ogs_sock_t *sock = NULL;
ogs_assert(gnode);
ogs_assert(node);
ogs_assert(pkbuf);
sock = gnode->sock;
sock = node->sock;
ogs_assert(sock);
sent = ogs_send(sock->fd, pkbuf->data, pkbuf->len, 0);
@ -95,24 +96,125 @@ int ogs_pfcp_send(ogs_pfcp_node_t *gnode, ogs_pkbuf_t *pkbuf)
return OGS_OK;
}
int ogs_pfcp_sendto(ogs_pfcp_node_t *gnode, ogs_pkbuf_t *pkbuf)
int ogs_pfcp_sendto(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
{
ssize_t sent;
ogs_sock_t *sock = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(gnode);
ogs_assert(node);
ogs_assert(pkbuf);
sock = gnode->sock;
sock = node->sock;
ogs_assert(sock);
addr = &gnode->remote_addr;
addr = &node->addr;
ogs_assert(addr);
sent = ogs_sendto(sock->fd, pkbuf->data, pkbuf->len, 0, addr);
if (sent < 0 || sent != pkbuf->len) {
ogs_error("ogs_send() failed");
ogs_error("ogs_sendto() failed");
return OGS_ERROR;
}
return OGS_OK;
}
void ogs_pfcp_send_heartbeat_response(ogs_pfcp_xact_t *xact)
{
int rv;
ogs_pkbuf_t *n4buf = NULL;
ogs_pfcp_header_t h;
ogs_assert(xact);
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_HEARTBEAT_RESPONSE_TYPE;
h.seid = 0;
n4buf = ogs_pfcp_n4_build_heartbeat_response(h.type);
ogs_expect_or_return(n4buf);
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value)
{
int rv;
ogs_pfcp_message_t errmsg;
ogs_pfcp_tlv_cause_t *cause = NULL;
ogs_pfcp_tlv_offending_ie_t *offending_ie = NULL;
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(xact);
memset(&errmsg, 0, sizeof(ogs_pfcp_message_t));
errmsg.h.seid = seid;
errmsg.h.type = type;
switch (type) {
case OGS_PFCP_PFD_MANAGEMENT_RESPONSE_TYPE:
cause = &errmsg.pfcp_pfd_management_response.cause;
offending_ie = &errmsg.pfcp_pfd_management_response.offending_ie;
break;
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
cause = &errmsg.pfcp_association_setup_response.cause;
break;
case OGS_PFCP_ASSOCIATION_UPDATE_RESPONSE_TYPE:
cause = &errmsg.pfcp_association_update_response.cause;
break;
case OGS_PFCP_ASSOCIATION_RELEASE_RESPONSE_TYPE:
cause = &errmsg.pfcp_association_release_response.cause;
break;
case OGS_PFCP_NODE_REPORT_RESPONSE_TYPE:
cause = &errmsg.pfcp_node_report_response.cause;
offending_ie = &errmsg.pfcp_node_report_response.offending_ie;
break;
case OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE:
cause = &errmsg.pfcp_session_set_deletion_response.cause;
offending_ie = &errmsg.pfcp_session_set_deletion_response.offending_ie;
break;
case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
cause = &errmsg.pfcp_session_establishment_response.cause;
offending_ie = &errmsg.pfcp_session_establishment_response.offending_ie;
break;
case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE:
cause = &errmsg.pfcp_session_modification_response.cause;
offending_ie = &errmsg.pfcp_session_modification_response.offending_ie;
break;
case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
cause = &errmsg.pfcp_session_deletion_response.cause;
offending_ie = &errmsg.pfcp_session_deletion_response.offending_ie;
break;
case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE:
cause = &errmsg.pfcp_session_report_response.cause;
offending_ie = &errmsg.pfcp_session_report_response.offending_ie;
break;
default:
ogs_assert_if_reached();
return;
}
ogs_assert(cause);
cause->presence = 1;
cause->u8 = cause_value;
if (offending_ie && offending_ie_value) {
offending_ie->presence = 1;
offending_ie->u16 = offending_ie_value;
}
pkbuf = ogs_pfcp_build_msg(&errmsg);
ogs_expect_or_return(pkbuf);
rv = ogs_pfcp_xact_update_tx(xact, &errmsg.h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}