MME GTPC Server done

This commit is contained in:
Sukchan Lee 2017-12-02 00:44:07 +09:00
parent 8287db900c
commit c300d2b99a
9 changed files with 92 additions and 22 deletions

View File

@ -1,3 +1,5 @@
#define TRACE_MODULE _gtp_node
#include "core_debug.h"
#include "gtp_node.h"

View File

@ -4,6 +4,8 @@
#include "core_list.h"
#include "core_network.h"
#include "gtp_types.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

View File

@ -342,6 +342,7 @@ CORE_DECLARE(c_int16_t) gtp_build_uli(
#define GTP_F_TEID_IPV4_LEN 9
#define GTP_F_TEID_IPV6_LEN 21
#define GTP_F_TEID_IPV4_AND_IPV6_LEN 25
typedef struct _gtp_f_teid_t {
ED3(c_uint8_t ipv4:1;,
c_uint8_t ipv6:1;,
@ -350,6 +351,10 @@ ED3(c_uint8_t ipv4:1;,
union {
c_uint32_t ipv4_addr;
c_uint8_t ipv6_addr[IPV6_LEN];
struct {
c_uint32_t ipv4_addr;
c_uint8_t ipv6_addr[IPV6_LEN];
} both;
};
} __attribute__ ((packed)) gtp_f_teid_t;

View File

@ -86,6 +86,17 @@ static status_t context_prepare()
return CORE_OK;
}
static status_t context_validation()
{
if (self.parameter.no_ipv4 == 1 && self.parameter.no_ipv6 == 1)
{
d_error("Both `no_ipv4` and `no_ipv6` set to `true` in `%s`",
context_self()->config.path);
return CORE_ERROR;
}
return CORE_OK;
}
status_t context_parse_config()
{
status_t rv;
@ -239,6 +250,10 @@ status_t context_parse_config()
}
}
}
rv = context_validation();
if (rv != CORE_OK) return rv;
return CORE_OK;
}

View File

@ -148,7 +148,9 @@ static status_t mme_context_validation()
context_self()->config.path);
return CORE_ERROR;
}
if (self.gtpc_addr == 0)
if (list_first(&self.gtpc4_list) == NULL &&
list_first(&self.gtpc6_list) == NULL)
{
d_error("No mme.gtpc in '%s'",
context_self()->config.path);
@ -382,10 +384,6 @@ status_t mme_context_parse_config()
else if (!strcmp(gtpc_key, "hostname"))
{
hostname = yaml_iter_value(&gtpc_iter);
#if 1
if (hostname)
self.gtpc_addr = inet_addr(hostname);
#endif
}
else if (!strcmp(gtpc_key, "port"))
{
@ -1525,7 +1523,8 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
list_init(&mme_ue->sess_list);
mme_ue->mme_s11_teid = mme_ue->index;
mme_ue->mme_s11_addr = mme_self()->gtpc_addr;
mme_ue->mme_s11_ipv4 = mme_self()->gtpc4_addr;
mme_ue->mme_s11_ipv6 = mme_self()->gtpc6_addr;
/* Create t3413 timer */
mme_ue->t3413 = timer_create(&self.tm_service, MME_EVT_EMM_T3413,

View File

@ -57,13 +57,14 @@ typedef struct _mme_context_t {
const char *fd_conf_path; /* MME freeDiameter conf path */
list_t s1ap_list; /* MME S1AP Server List */
c_socklist_t gtpc4_list; /* MME GTPC IPv4 Server List */
c_socklist_t gtpc6_list; /* MME GTPC IPv6 Server List */
list_t sgw_list; /* SGW GTPC Client List */
c_uint32_t gtpc_addr; /* MME GTPC local address */
c_uint16_t gtpc_port; /* MME GTPC local port */
sock_id gtpc_sock; /* MME GTPC local listen socket */
c_uint16_t gtpc_port; /* Default GTPC Port */
c_socklist_t gtpc4_list; /* MME GTPC IPv4 Server List */
c_sockaddr_t *gtpc4_addr; /* MME GTPC IPv4 Address */
c_socklist_t gtpc6_list; /* MME GTPC IPv6 Server List */
c_sockaddr_t *gtpc6_addr; /* MME GTPC IPv6 Address */
c_uint32_t s5c_addr; /* PGW S5C remote address */
c_uint16_t s5c_port; /* PGW S5C remote port */
@ -193,7 +194,8 @@ struct _mme_ue_t {
/* IMPORTANT!
* MME-S11-TEID is same with an index */
c_uint32_t mme_s11_teid;
c_uint32_t mme_s11_addr;
c_sockaddr_t *mme_s11_ipv4; /* MME S11 IPv4 Address */
c_sockaddr_t *mme_s11_ipv6; /* MME S11 IPv6 Address */
c_uint32_t sgw_s11_teid;
c_uint32_t sgw_s11_addr;

View File

@ -61,7 +61,16 @@ status_t mme_gtp_open()
temp = node->sock; /* FIXME ADDR : Shoud be removed */
}
#if 0
for (node = list_first(&mme_self()->gtpc4_list);
node; node = list_next(node))
{
mme_self()->gtpc4_addr = sock_local_addr(node->sock);
if (mme_self()->gtpc4_addr)
{
break;
}
}
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
{
@ -72,7 +81,19 @@ status_t mme_gtp_open()
return rv;
}
}
#endif
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
{
mme_self()->gtpc6_addr = sock_local_addr(node->sock);
if (mme_self()->gtpc6_addr)
{
break;
}
}
d_assert(mme_self()->gtpc4_addr || mme_self()->gtpc6_addr,
return CORE_ERROR, "No GTP Server");
/* FIXME : socket descriptor needs in gnode when packet is sending initilly */
while(sgw)
@ -94,13 +115,11 @@ status_t mme_gtp_close()
sock_delete(node->sock);
}
#if 0
for (node = list_first(&mme_self()->gtpc6_list);
node; node = list_next(node))
{
sock_delete(node->sock);
}
#endif
return CORE_OK;
}

View File

@ -71,13 +71,39 @@ status_t mme_s11_build_create_session_request(
req->rat_type.u8 = GTP_RAT_TYPE_EUTRAN;
memset(&mme_s11_teid, 0, sizeof(gtp_f_teid_t));
mme_s11_teid.ipv4 = 1;
mme_s11_teid.interface_type = GTP_F_TEID_S11_MME_GTP_C;
mme_s11_teid.teid = htonl(mme_ue->mme_s11_teid);
mme_s11_teid.ipv4_addr = mme_ue->mme_s11_addr;
if (mme_ue->mme_s11_ipv4 && mme_ue->mme_s11_ipv6)
{
mme_s11_teid.ipv4 = 1;
mme_s11_teid.both.ipv4_addr = mme_ue->mme_s11_ipv4->sin.sin_addr.s_addr;
mme_s11_teid.ipv6 = 1;
memcpy(mme_s11_teid.both.ipv6_addr,
mme_ue->mme_s11_ipv6->sin6.sin6_addr.s6_addr,
sizeof(mme_s11_teid.ipv6_addr));
req->sender_f_teid_for_control_plane.len =
GTP_F_TEID_IPV4_AND_IPV6_LEN;
}
else if (mme_ue->mme_s11_ipv4)
{
mme_s11_teid.ipv4 = 1;
mme_s11_teid.ipv4_addr = mme_ue->mme_s11_ipv4->sin.sin_addr.s_addr;
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV4_LEN;
}
else if (mme_ue->mme_s11_ipv6)
{
mme_s11_teid.ipv4 = 1;
mme_s11_teid.both.ipv4_addr = mme_ue->mme_s11_ipv4->sin.sin_addr.s_addr;
mme_s11_teid.ipv6 = 1;
memcpy(mme_s11_teid.ipv6_addr,
mme_ue->mme_s11_ipv6->sin6.sin6_addr.s6_addr,
sizeof(mme_s11_teid.ipv6_addr));
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV6_LEN;
}
else
d_assert(0, return CORE_ERROR,);
req->sender_f_teid_for_control_plane.presence = 1;
req->sender_f_teid_for_control_plane.data = &mme_s11_teid;
req->sender_f_teid_for_control_plane.len = GTP_F_TEID_IPV4_LEN;
memset(&pgw_s5c_teid, 0, sizeof(gtp_f_teid_t));
pgw_s5c_teid.ipv4 = 1;

View File

@ -50,11 +50,11 @@ status_t testgtpu_enb_connect(sock_id *new)
if (test_only_control_plane) return CORE_OK;
d_assert(mme, return CORE_ERROR,);
d_assert(mme->gtpc4_addr, return CORE_ERROR,);
if (!mme) return CORE_ERROR;
memset(&addr, 0, sizeof(c_sockaddr_t));
addr.sin.sin_addr.s_addr = mme->gtpc_addr;
addr.c_sa_family = AF_INET;
memcpy(&addr, mme->gtpc4_addr, sizeof(c_sockaddr_t));
addr.c_sa_port = htons(GTPV1_U_UDP_PORT);
rv = udp_socket(new, AF_INET);