Now ping works

This commit is contained in:
James Park 2017-04-18 18:24:37 +09:00
parent 563e98a345
commit 20e6a2c9a5
12 changed files with 303 additions and 95 deletions

View File

@ -98,3 +98,83 @@ status_t gtp_send(net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
return CORE_OK;
}
pkbuf_t *gtp_handle_echo_req(pkbuf_t *pkb)
{
gtp_header_t *gtph = NULL;
pkbuf_t *pkb_resp;NULL;
gtp_header_t *gtph_resp;NULL;
c_uint16_t length;
int idx;
d_assert(pkb, return NULL, "pkt is NULL");
gtph = (gtp_header_t *)pkb->payload;
/* Check GTP version. Now only support GTPv1(version = 1) */
if ((gtph->flags >> 5) != 1)
{
return NULL;
}
if (gtph->type != GTPU_MSGTYPE_ECHO_REQ)
{
return NULL;
}
d_trace(1, "gtp_handle_without_teid(ECHO_REQ)\n");
pkb_resp = pkbuf_alloc(0, 100 /* enough for ECHO_RSP; use smaller buffer */);
d_assert(pkb_resp, return NULL, "Can't allocate pkbuf");
gtph_resp = (gtp_header_t *)pkb_resp->payload;
/* reply back immediately */
gtph_resp->flags = (1 << 5); /* set version */
gtph_resp->flags |= (1 << 4); /* set PT */
gtph_resp->type = GTPU_MSGTYPE_ECHO_RSP;
length = 0; /* length of Recovery IE */
gtph_resp->length = htons(length); /* to be overwriten */
gtph_resp->teid = 0;
idx = 8;
if (gtph->flags & (GTPU_FLAGS_PN | GTPU_FLAGS_S))
{
length += 4;
if (gtph->flags & GTPU_FLAGS_S)
{
/* sequence exists */
gtph_resp->flags |= GTPU_FLAGS_S;
*((c_uint8_t *)pkb_resp->payload + idx) = *((c_uint8_t *)pkb->payload + idx);
*((c_uint8_t *)pkb_resp->payload + idx + 1) = *((c_uint8_t *)pkb->payload + idx + 1);
}
else
{
*((c_uint8_t *)pkb_resp->payload + idx) = 0;
*((c_uint8_t *)pkb_resp->payload + idx + 1) = 0;
}
idx += 2;
if (gtph->flags & GTPU_FLAGS_PN)
{
/* sequence exists */
gtph_resp->flags |= GTPU_FLAGS_PN;
*((c_uint8_t *)pkb_resp->payload + idx) = *((c_uint8_t *)pkb->payload + idx);
}
else
{
*((c_uint8_t *)pkb_resp->payload + idx) = 0;
}
idx++;
*((c_uint8_t *)pkb_resp->payload + idx) = 0; /* next-extension header */
idx++;
}
/* fill Recovery IE */
length += 2;
*((c_uint8_t *)pkb_resp->payload + idx) = 14; idx++; /* type */
*((c_uint8_t *)pkb_resp->payload + idx) = 0; idx++; /* restart counter */
gtph_resp->length = htons(length);
pkb_resp->len = idx; /* buffer length */
return pkb_resp;
}

View File

@ -55,6 +55,7 @@ CORE_DECLARE(pkbuf_t *) gtp_read(net_sock_t *sock);
CORE_DECLARE(status_t) gtp_send(net_sock_t *sock,
gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(pkbuf_t*) gtp_handle_echo_req(pkbuf_t *pkt);
#ifdef __cplusplus
}
#endif /* __cplusplus */

7
main.c
View File

@ -60,7 +60,6 @@ static int check_signal(int signum)
return 0;
}
int main(int argc, char *argv[])
{
/**************************************************************************
@ -117,6 +116,12 @@ int main(int argc, char *argv[])
{
#if 0
extern int _sgw_path;
d_trace_level(&_sgw_path, 100);
extern int _pgw_path;
d_trace_level(&_pgw_path, 100);
extern int _pgw_context;
d_trace_level(&_pgw_context, 100);
extern int _gtp_xact;
d_trace_level(&_gtp_xact, 100);
extern int _mme_sm;

View File

@ -17,8 +17,6 @@
#define MIN_EPS_BEARER_ID 5
#define MAX_EPS_BEARER_ID 15
#define DEFAULT_IP_ADDR "127.0.0.1"
static mme_context_t self;
pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_SGW);
@ -30,8 +28,26 @@ pool_declare(mme_pdn_pool, pdn_t, MAX_NUM_OF_UE_PDN);
static int context_initialized = 0;
/* FIXME : Global IP information and port.
* This should be read from configuration file or arguments
*/
#if 0
static char g_mme_ip_addr[20] = "127.0.0.1";
static unsigned int g_mme_gtp_c_port = GTPV2_C_UDP_PORT;
static char g_sgw_s11_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s11_port = GTPV2_C_UDP_PORT + 1;
#else
static char g_mme_ip_addr[20] = "10.1.35.215";
static unsigned int g_mme_gtp_c_port = GTPV2_C_UDP_PORT;
static char g_sgw_s11_ip_addr[20] = "10.1.35.216";
static unsigned int g_sgw_s11_port = GTPV2_C_UDP_PORT;
#endif
status_t mme_context_init()
{
d_assert(context_initialized == 0, return CORE_ERROR,
"MME context already has been context_initialized");
@ -48,7 +64,7 @@ status_t mme_context_init()
index_init(&mme_bearer_pool, MAX_NUM_OF_UE_BEARER);
pool_init(&mme_pdn_pool, MAX_NUM_OF_UE_PDN);
self.mme_addr = inet_addr(DEFAULT_IP_ADDR);
self.mme_addr = inet_addr(g_mme_ip_addr);
self.mme_ue_s1ap_id_hash = hash_make();
@ -59,11 +75,11 @@ status_t mme_context_init()
d_assert(sgw, return CORE_ERROR, "Can't add SGW context");
self.s11_addr = self.mme_addr;
self.s11_port = GTPV2_C_UDP_PORT;
self.s11_port = g_mme_gtp_c_port;
/* FIXME : It should be removed */
sgw->gnode.addr = inet_addr(DEFAULT_IP_ADDR);
sgw->gnode.port = GTPV2_C_UDP_PORT+1;
/* FIXME : It should be removed : Peer SGW ?*/
sgw->gnode.addr = inet_addr(g_sgw_s11_ip_addr);
sgw->gnode.port = g_sgw_s11_port;
/* MCC : 001, MNC : 01 */
plmn_id_build(&self.plmn_id, 1, 1, 2);

View File

@ -10,8 +10,6 @@
#include <netinet/ip.h>
#define DEFAULT_IP_ADDR "127.0.0.1"
static pgw_context_t self;
index_declare(pgw_sess_pool, pgw_sess_t, MAX_NUM_OF_UE);
@ -21,6 +19,29 @@ pool_declare(pgw_pdn_pool, pdn_t, MAX_NUM_OF_UE_PDN);
static int context_initiaized = 0;
/* FIXME : Global IP information and port.
* This should be read from configuration file or arguments
*/
/* loop back */
#if 0
static char g_sgw_s5c_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s5c_port = GTPV2_C_UDP_PORT + 2;
static char g_pgw_s5c_ip_addr[20] = "127.0.0.1";
static unsigned int g_pgw_s5c_port = GTPV2_C_UDP_PORT + 3;
static char g_pgw_ip_addr[20] = "127.0.0.1";
static unsigned int g_pgw_s5u_port = GTPV1_U_UDP_PORT + 2;
#else
static char g_sgw_s5c_ip_addr[20] = "10.1.35.217";
static unsigned int g_sgw_s5c_port = GTPV2_C_UDP_PORT;
static char g_pgw_ip_addr[20] = "10.1.35.219";
static unsigned int g_pgw_s5c_port = GTPV2_C_UDP_PORT;
static unsigned int g_pgw_s5u_port = GTPV1_U_UDP_PORT;
#endif
status_t pgw_context_init()
{
d_assert(context_initiaized == 0, return CORE_ERROR,
@ -34,21 +55,19 @@ status_t pgw_context_init()
pool_init(&pgw_pdn_pool, MAX_NUM_OF_UE_PDN);
self.pgw_addr = inet_addr(DEFAULT_IP_ADDR);
self.pgw_addr = inet_addr(g_pgw_ip_addr);
self.s5c_addr = self.pgw_addr;
self.s5c_port = GTPV2_C_UDP_PORT + 3;
/* FIXME : It shoud be removed */
self.s5c_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s5c_node.port = GTPV2_C_UDP_PORT + 2;
self.s5c_port = g_pgw_s5c_port;
/* FIXME : It shoud be removed : Peer SGW ?*/
self.s5c_node.addr = inet_addr(g_sgw_s5c_ip_addr);
self.s5c_node.port = g_sgw_s5c_port;
list_init(&self.s5c_node.local_list);
list_init(&self.s5c_node.remote_list);
self.s5u_addr = self.pgw_addr;
self.s5u_port = GTPV1_U_UDP_PORT + 1;
/* FIXME : It shoud be removed */
self.s5u_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s5u_node.port = GTPV1_U_UDP_PORT;
self.s5u_port = g_pgw_s5u_port;
self.primary_dns_addr = inet_addr("8.8.8.8");
self.secondary_dns_addr = inet_addr("4.4.4.4");
@ -330,6 +349,8 @@ pgw_bearer_t* pgw_bearer_find_by_packet(pkbuf_t *pkt)
pgw_bearer_t *iter_bearer = NULL;
pdn_t *iter_pdn = NULL;
struct iphdr *iph = NULL;
char buf1[INET_ADDRSTRLEN];
char buf2[INET_ADDRSTRLEN];
d_assert(pkt, return NULL, "pkt is NULL");
@ -341,6 +362,11 @@ pgw_bearer_t* pgw_bearer_find_by_packet(pkbuf_t *pkt)
return NULL;
}
d_trace(50,"Src(%s)-> Dst(%s), Protocol: %d\n",
INET_NTOP(&iph->saddr,buf1),
INET_NTOP(&iph->daddr,buf2),
iph->protocol);
/* FIXME: Need API to find the bearer with packet filter */
/* Iterate session */
for (iter_session = pgw_sess_first(); iter_session ;
@ -356,16 +382,15 @@ pgw_bearer_t* pgw_bearer_find_by_packet(pkbuf_t *pkt)
iter_pdn;
iter_pdn = pgw_pdn_next(iter_pdn))
{
char buf1[INET_ADDRSTRLEN];
char buf2[INET_ADDRSTRLEN];
d_trace(3,"Src_IP(%s) in Pkt : PAA(%s) in PDN\n",
INET_NTOP(iph->saddr,buf1),
INET_NTOP(iter_pdn->paa.ipv4_addr, buf2));
d_trace(3,"Dst(%s) in Pkt : PAA(%s) in PDN\n",
INET_NTOP(&iph->daddr,buf1),
INET_NTOP(&iter_pdn->paa.ipv4_addr, buf2));
if (iph->saddr == iter_pdn->paa.ipv4_addr)
if (iph->daddr == iter_pdn->paa.ipv4_addr)
{
/* Found */
d_trace(3,"Found bearer(id = %d)\n",iter_bearer->id);
return iter_bearer;
}

View File

@ -26,7 +26,6 @@ typedef struct _pgw_context_t {
c_uint32_t s5u_addr; /* PGW S5-U local address */
c_uint32_t s5u_port; /* PGW S5-U local port */
net_sock_t* s5u_sock; /* PGW S5-U local listen socket */
gtp_node_t s5u_node; /* PGW S5-U remote GTPv1-U node */
msgq_id queue_id; /* Qsesssess for processing PGW control plane */
tm_service_t tm_service; /* Timer Service */

View File

@ -28,12 +28,18 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
return -1;
}
recvbuf->len = n;
d_trace(1, "PDU received from TunTap\n");
d_trace_hex(1, recvbuf->payload, recvbuf->len);
/* Find the bearer by packet filter */
bearer = pgw_bearer_find_by_packet(recvbuf);
if (bearer)
{
gtp_header_t *gtp_h = NULL;
gtp_node_t gnode;
char buf[INET_ADDRSTRLEN];
/* Add GTP-U header */
rv = pkbuf_header(recvbuf, sizeof(gtp_header_t));
@ -44,6 +50,7 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
return -1;
}
gtp_h = (gtp_header_t *)recvbuf->payload;
/* Bits 8 7 6 5 4 3 2 1
* +--+--+--+--+--+--+--+--+
* |version |PT| 1| E| S|PN|
@ -52,12 +59,15 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
*/
gtp_h->flags = 0x30;
gtp_h->type = GTPU_MSGTYPE_GPDU;
gtp_h->length = n;
gtp_h->teid = bearer->sgw_s5u_teid;
gtp_h->length = htons(n);
gtp_h->teid = htonl(bearer->sgw_s5u_teid);
/* Send to SGW */
gnode.addr = bearer->sgw_s5u_addr;
gnode.port = GTPV1_U_UDP_PORT;
d_trace(1, "Send S5U PDU (teid = 0x%x)to SGW(%s)\n",
bearer->sgw_s5u_teid,
INET_NTOP(&gnode.addr, buf));
rv = gtp_send(pgw_self()->s5u_sock, &gnode, recvbuf);
}
@ -125,7 +135,7 @@ static int _gtpv1_u_recv_cb(net_sock_t *sock, void *data)
return -1;
}
d_trace(1, "S5-U PDU received from GTP\n");
d_trace(1, "S5-U PDU received from SGW\n");
d_trace_hex(1, pkbuf->payload, pkbuf->len);
/* Remove GTP header and send packets to TUN interface */
@ -160,7 +170,7 @@ status_t pgw_path_open()
}
rv = gtp_listen(&pgw_self()->s5u_sock, _gtpv1_u_recv_cb,
pgw_self()->s5u_addr, pgw_self()->s5u_port, &pgw_self()->s5u_node);
pgw_self()->s5u_addr, pgw_self()->s5u_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S5-U Path for PGW");
@ -228,7 +238,7 @@ status_t pgw_path_close()
#if LINUX == 1
net_unregister_link(pgw_self()->tun_link);
net_link_close(pgw_self()->tun_link);
net_tuntap_close(pgw_self()->tun_link);
#endif
return CORE_OK;
@ -246,8 +256,3 @@ status_t pgw_s5c_send_to_sgw(
return CORE_OK;
}
status_t pgw_s5u_send_to_sgw(pkbuf_t *pkbuf)
{
d_assert(pkbuf, return CORE_ERROR, "Null param");
return gtp_send(pgw_self()->s5u_sock, &pgw_self()->s5u_node, pkbuf);
}

View File

@ -12,7 +12,6 @@ CORE_DECLARE(status_t) pgw_path_close();
CORE_DECLARE(status_t) pgw_s5c_send_to_sgw(
gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) pgw_s5u_send_to_sgw(pkbuf_t *pkbuf);
#ifdef __cplusplus
}

View File

@ -9,8 +9,6 @@
#include "sgw_context.h"
#define DEFAULT_IP_ADDR "127.0.0.1"
static sgw_context_t self;
index_declare(sgw_sess_pool, sgw_sess_t, MAX_NUM_OF_UE);
@ -18,6 +16,47 @@ index_declare(sgw_bearer_pool, sgw_bearer_t, MAX_NUM_OF_UE_BEARER);
static int context_initialized = 0;
/* FIXME : Global IP information and port.
* This should be read from configuration file or arguments
*/
#if 0
static char g_mme_ip_addr[20] = "127.0.0.1";
static unsigned int g_mme_gtp_c_port = GTPV2_C_UDP_PORT;
static char g_sgw_s11_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s11_port = GTPV2_C_UDP_PORT + 1;
static char g_sgw_s5c_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s5c_port = GTPV2_C_UDP_PORT + 2;
static char g_pgw_ip_addr[20] = "127.0.0.1";
static unsigned int g_pgw_s5c_port = GTPV2_C_UDP_PORT + 3;
static char g_sgw_s1u_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s1u_port = GTPV1_U_UDP_PORT;
static char g_sgw_s5u_ip_addr[20] = "127.0.0.1";
static unsigned int g_sgw_s5u_port = GTPV1_U_UDP_PORT + 1;
#else
static char g_mme_ip_addr[20] = "10.1.35.215";
static unsigned int g_mme_gtp_c_port = GTPV2_C_UDP_PORT;
static char g_sgw_s11_ip_addr[20] = "10.1.35.216";
static unsigned int g_sgw_s11_port = GTPV2_C_UDP_PORT;
static char g_sgw_s5c_ip_addr[20] = "10.1.35.217";
static unsigned int g_sgw_s5c_port = GTPV2_C_UDP_PORT;
static char g_pgw_ip_addr[20] = "10.1.35.219";
static unsigned int g_pgw_s5c_port = GTPV2_C_UDP_PORT;
static char g_sgw_s1u_ip_addr[20] = "10.1.35.216";/* same as g_sgw_s11_ip_addr */
static unsigned int g_sgw_s1u_port = GTPV1_U_UDP_PORT;
static char g_sgw_s5u_ip_addr[20] = "10.1.35.217"; /* same as g_sgw_s5c_ip_addr */
static unsigned int g_sgw_s5u_port = GTPV1_U_UDP_PORT;
#endif
status_t sgw_context_init()
{
d_assert(context_initialized == 0, return CORE_ERROR,
@ -29,36 +68,35 @@ status_t sgw_context_init()
index_init(&sgw_bearer_pool, MAX_NUM_OF_UE_BEARER);
list_init(&self.sess_list);
self.sgw_addr = inet_addr(DEFAULT_IP_ADDR);
self.sgw_addr = inet_addr(g_sgw_s11_ip_addr);
self.s11_addr = self.sgw_addr;
self.s11_port = GTPV2_C_UDP_PORT + 1;
/* FIXME : It shoud be removed */
self.s11_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s11_node.port = GTPV2_C_UDP_PORT;
/* S11 address and port of SGW */
self.s11_addr = inet_addr(g_sgw_s11_ip_addr);
self.s11_port = g_sgw_s11_port;
/* FIXME : It shoud be removed : Peer MME ? */
self.s11_node.addr = inet_addr(g_mme_ip_addr);
self.s11_node.port = g_mme_gtp_c_port;
list_init(&self.s11_node.local_list);
list_init(&self.s11_node.remote_list);
self.s5c_addr = self.sgw_addr;
self.s5c_port = GTPV2_C_UDP_PORT + 2;
/* FIXME : It shoud be removed */
self.s5c_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s5c_node.port = GTPV2_C_UDP_PORT + 3;
/* S5C address and port of SGW */
self.s5c_addr = inet_addr(g_sgw_s5c_ip_addr);
self.s5c_port = g_sgw_s5c_port;
/* FIXME : It shoud be removed : Peer PGW ? */
self.s5c_node.addr = inet_addr(g_pgw_ip_addr);
self.s5c_node.port = g_pgw_s5c_port;
list_init(&self.s5c_node.local_list);
list_init(&self.s5c_node.remote_list);
self.s1u_addr = self.sgw_addr;
self.s1u_port = GTPV1_U_UDP_PORT;
/* FIXME : It shoud be removed */
self.s1u_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s1u_node.port = GTPV1_U_UDP_PORT;
/* S1U address and port of SGW */
self.s1u_addr = inet_addr(g_sgw_s1u_ip_addr);
self.s1u_port = g_sgw_s1u_port;
self.s5u_addr = inet_addr(g_sgw_s5u_ip_addr);
self.s5u_port = g_sgw_s5u_port;
self.s5u_addr = self.sgw_addr;
self.s5u_port = GTPV1_U_UDP_PORT;
/* FIXME : It shoud be removed */
self.s5u_node.addr = inet_addr(DEFAULT_IP_ADDR);
self.s5u_node.port = GTPV1_U_UDP_PORT + 1;
context_initialized = 1;
return CORE_OK;
@ -212,7 +250,9 @@ status_t sgw_bearer_remove_all(sgw_sess_t *sess)
sgw_bearer_t* sgw_bearer_find(index_t index)
{
d_assert(index, return NULL, "Invalid Index");
d_assert(index && index < MAX_NUM_OF_UE_BEARER, return NULL,
"Invalid Index(%d)",index);
return index_find(&sgw_bearer_pool, index);
}

View File

@ -31,12 +31,12 @@ typedef struct _sgw_context_t {
c_uint32_t s1u_addr; /* SGW S1-U local address */
c_uint32_t s1u_port; /* SGW S1-U local port */
net_sock_t* s1u_sock; /* SGW S1-U local listen socket */
gtp_node_t s1u_node; /* PGW S1-U remote GTPv1-U node */
//gtp_node_t s1u_node; /* PGW S1-U remote GTPv1-U node */
c_uint32_t s5u_addr; /* SGW S5-U local address */
c_uint32_t s5u_port; /* SGW S5-U local port */
net_sock_t* s5u_sock; /* SGW S5-U local listen socket */
gtp_node_t s5u_node; /* PGW S5-U remote GTPv1-U node */
//gtp_node_t s5u_node; /* PGW S5-U remote GTPv1-U node */
msgq_id queue_id; /* Queue for processing SGW control plane */
tm_service_t tm_service; /* Timer Service */

View File

@ -77,22 +77,45 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
return -1;
}
d_trace(1, "S5-U PDU received from GTP\n");
d_trace(1, "S5-U PDU received from PGW\n");
d_trace_hex(1, pkbuf->payload, pkbuf->len);
gtp_h = (gtp_header_t *)pkbuf->payload;
teid = ntohl(gtp_h->teid);
bearer = sgw_bearer_find_by_sgw_s5u_teid(ntohl(teid));
if (bearer)
if (gtp_h->type == GTPU_MSGTYPE_ECHO_REQ)
{
/* Convert Teid and send to enodeB via s1u */
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
pkbuf_t *echo_rsp;
gtp_send(sgw_self()->s1u_sock, &gnode, pkbuf);
d_trace(1,"Received echo-req");
echo_rsp = gtp_handle_echo_req(pkbuf);
if (echo_rsp)
{
/* Echo reply */
d_trace(1,"Send echo-rsp to peer(PGW) ");
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gtp_send(sgw_self()->s5u_sock, &gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
else if (gtp_h->type == GTPU_MSGTYPE_GPDU)
{
teid = ntohl(gtp_h->teid);
d_trace(1,"Recv GPDU (teid = 0x%x)",teid);
bearer = sgw_bearer_find_by_sgw_s5u_teid(teid);
if (bearer)
{
/* Convert Teid and send to enodeB via s1u */
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gtp_send(sgw_self()->s1u_sock, &gnode, pkbuf);
}
}
pkbuf_free(pkbuf);
@ -118,22 +141,44 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
return -1;
}
d_trace(1, "S1-U PDU received from GTP\n");
d_trace(1, "S1-U PDU received from ENB\n");
d_trace_hex(1, pkbuf->payload, pkbuf->len);
gtp_h = (gtp_header_t *)pkbuf->payload;
teid = ntohl(gtp_h->teid);
bearer = sgw_bearer_find_by_sgw_s1u_teid(ntohl(teid));
if (bearer)
if (gtp_h->type == GTPU_MSGTYPE_ECHO_REQ)
{
/* Convert Teid and send to PGW via s5u */
gtp_h->teid = htonl(bearer->pgw_s5u_teid);
gnode.addr = bearer->pgw_s5u_addr;
gnode.port = GTPV1_U_UDP_PORT;
pkbuf_t *echo_rsp;
gtp_send(sgw_self()->s5u_sock, &gnode, pkbuf);
d_trace(1,"Received echo-req\n");
echo_rsp = gtp_handle_echo_req(pkbuf);
if (echo_rsp)
{
/* Echo reply */
d_trace(1,"Send echo-rsp to peer(ENB)\n");
gnode.addr = sock->remote.sin_addr.s_addr;
gnode.port = GTPV1_U_UDP_PORT;
gtp_send(sgw_self()->s1u_sock, &gnode, echo_rsp);
pkbuf_free(echo_rsp);
}
}
else if (gtp_h->type == GTPU_MSGTYPE_GPDU)
{
teid = ntohl(gtp_h->teid);
d_trace(1,"Recv GPDU (teid = 0x%x) from ENB\n",teid);
bearer = sgw_bearer_find_by_sgw_s1u_teid(teid);
if (bearer)
{
/* Convert Teid and send to PGW via s5u */
gtp_h->teid = htonl(bearer->pgw_s5u_teid);
gnode.addr = bearer->pgw_s5u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gtp_send(sgw_self()->s5u_sock, &gnode, pkbuf);
}
}
pkbuf_free(pkbuf);
@ -161,7 +206,7 @@ status_t sgw_path_open()
}
rv = gtp_listen(&sgw_self()->s5u_sock, _gtpv1_s5u_recv_cb,
sgw_self()->s5u_addr, sgw_self()->s5u_port, &sgw_self()->s5u_node);
sgw_self()->s5u_addr, sgw_self()->s5u_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S5-U Path for SGW");
@ -169,7 +214,7 @@ status_t sgw_path_open()
}
rv = gtp_listen(&sgw_self()->s1u_sock, _gtpv1_s1u_recv_cb,
sgw_self()->s1u_addr, sgw_self()->s1u_port, &sgw_self()->s1u_node);
sgw_self()->s1u_addr, sgw_self()->s1u_port, NULL);
if (rv != CORE_OK)
{
d_error("Can't establish S1-U Path for SGW");
@ -236,9 +281,3 @@ status_t sgw_s5c_send_to_pgw(
return CORE_OK;
}
status_t sgw_s5u_send_to_pgw(pkbuf_t *pkbuf)
{
d_assert(pkbuf, return CORE_ERROR, "Null param");
return gtp_send(sgw_self()->s5u_sock, &sgw_self()->s5u_node, pkbuf);
}

View File

@ -14,7 +14,6 @@ CORE_DECLARE(status_t) sgw_s11_send_to_mme(
gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) sgw_s5c_send_to_pgw(
gtp_xact_t *assoc_xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) sgw_s5u_send_to_pgw(pkbuf_t *pkbuf);
#ifdef __cplusplus
}