Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-SMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-SMF
Commits
9aa6f728
Commit
9aa6f728
authored
Mar 26, 2019
by
gauthier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GTPU ECHO_RESPONSE
parent
149aa8b6
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
573 additions
and
142 deletions
+573
-142
src/common/msg/itti_msg_s1u.hpp
src/common/msg/itti_msg_s1u.hpp
+7
-34
src/gtpv1u/3gpp_29.281.cpp
src/gtpv1u/3gpp_29.281.cpp
+90
-0
src/gtpv1u/3gpp_29.281.hpp
src/gtpv1u/3gpp_29.281.hpp
+69
-26
src/gtpv1u/CMakeLists.txt
src/gtpv1u/CMakeLists.txt
+1
-0
src/gtpv1u/gtpv1u.cpp
src/gtpv1u/gtpv1u.cpp
+34
-6
src/gtpv1u/gtpv1u.hpp
src/gtpv1u/gtpv1u.hpp
+1
-4
src/gtpv1u/msg_gtpv1u.hpp
src/gtpv1u/msg_gtpv1u.hpp
+48
-11
src/spgwu/simpleswitch/spgwu_s1u.cpp
src/spgwu/simpleswitch/spgwu_s1u.cpp
+214
-0
src/spgwu/simpleswitch/spgwu_s1u.hpp
src/spgwu/simpleswitch/spgwu_s1u.hpp
+76
-0
src/spgwu/spgwu_app.cpp
src/spgwu/spgwu_app.cpp
+28
-13
src/spgwu/spgwu_app.hpp
src/spgwu/spgwu_app.hpp
+5
-48
No files found.
src/common/msg/itti_msg_s1u.hpp
View file @
9aa6f728
...
...
@@ -40,47 +40,20 @@ namespace oai::cn::core::itti {
class
itti_s1u_msg
:
public
itti_msg
{
public:
itti_s1u_msg
(
const
itti_msg_type_t
msg_type
,
const
task_id_t
orig
,
const
task_id_t
dest
)
:
itti_msg
(
msg_type
,
orig
,
dest
)
{
l_endpoint
=
{};
l_endpoint_addr_len
=
sizeof
(
l_endpoint
);
r_endpoint
=
{};
r_endpoint_addr_len
=
sizeof
(
r_endpoint
);
teid
=
UNASSIGNED_TEID
;
gtpu_tx_id
=
0
;
}
itti_msg
(
msg_type
,
orig
,
dest
)
{}
itti_s1u_msg
&
operator
=
(
itti_s1u_msg
other
)
{
this
->
itti_msg
::
operator
=
(
other
);
std
::
swap
(
l_endpoint
,
other
.
l_endpoint
);
std
::
swap
(
l_endpoint_addr_len
,
other
.
l_endpoint_addr_len
);
std
::
swap
(
r_endpoint
,
other
.
r_endpoint
);
std
::
swap
(
r_endpoint_addr_len
,
other
.
r_endpoint_addr_len
);
std
::
swap
(
teid
,
other
.
teid
);
std
::
swap
(
gtpu_tx_id
,
other
.
gtpu_tx_id
);
return
*
this
;
}
itti_s1u_msg
(
const
itti_s1u_msg
&
i
)
:
itti_msg
(
i
)
{
l_endpoint
=
i
.
l_endpoint
;
l_endpoint_addr_len
=
i
.
l_endpoint_addr_len
;
r_endpoint
=
i
.
r_endpoint
;
r_endpoint_addr_len
=
i
.
r_endpoint_addr_len
;
teid
=
i
.
teid
;
gtpu_tx_id
=
i
.
gtpu_tx_id
;
}
itti_s1u_msg
(
const
itti_s1u_msg
&
i
)
:
itti_msg
(
i
)
{}
itti_s1u_msg
(
const
itti_s1u_msg
&
i
,
const
task_id_t
orig
,
const
task_id_t
dest
)
:
itti_s1u_msg
(
i
)
{
origin
=
orig
;
destination
=
dest
;
}
struct
sockaddr_storage
l_endpoint
;
socklen_t
l_endpoint_addr_len
;
struct
sockaddr_storage
r_endpoint
;
socklen_t
r_endpoint_addr_len
;
teid_t
teid
;
uint64_t
gtpu_tx_id
;
};
//------------------------------------------------------------------------------
class
itti_s1u_echo_request
:
public
itti_s1u_msg
{
...
...
@@ -101,7 +74,7 @@ public:
itti_s1u_msg
(
i
,
orig
,
dest
)
{
gtp_ies
=
i
.
gtp_ies
;
}
const
char
*
get_msg_name
()
{
return
typeid
(
itti_s1u_echo_request
).
name
()
;};
const
char
*
get_msg_name
()
{
return
"S1U_ECHO_REQUEST"
;};
proto
::
gtpv1u
::
gtpv1u_echo_request
gtp_ies
;
};
...
...
@@ -124,7 +97,7 @@ public:
itti_s1u_msg
(
i
,
orig
,
dest
)
{
gtp_ies
=
i
.
gtp_ies
;
}
const
char
*
get_msg_name
()
{
return
typeid
(
itti_s1u_echo_response
).
name
()
;};
const
char
*
get_msg_name
()
{
return
"S1U_ECHO_RESPONSE"
;};
proto
::
gtpv1u
::
gtpv1u_echo_response
gtp_ies
;
};
...
...
@@ -147,7 +120,7 @@ public:
itti_s1u_msg
(
i
,
orig
,
dest
)
{
gtp_ies
=
i
.
gtp_ies
;
}
const
char
*
get_msg_name
()
{
return
typeid
(
itti_s1u_error_indication
).
name
()
;};
const
char
*
get_msg_name
()
{
return
"S1U_ERROR_INDICATION"
;};
proto
::
gtpv1u
::
gtpv1u_error_indication
gtp_ies
;
};
...
...
@@ -170,7 +143,7 @@ public:
itti_s1u_msg
(
i
,
orig
,
dest
)
{
gtp_ies
=
i
.
gtp_ies
;
}
const
char
*
get_msg_name
()
{
return
typeid
(
itti_s1u_supported_extension_headers_notification
).
name
()
;};
const
char
*
get_msg_name
()
{
return
"S1U_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION"
;};
proto
::
gtpv1u
::
gtpv1u_supported_extension_headers_notification
gtp_ies
;
};
...
...
@@ -195,7 +168,7 @@ public:
itti_s1u_msg
(
i
,
orig
,
dest
)
{
gtp_ies
=
i
.
gtp_ies
;
}
const
char
*
get_msg_name
()
{
return
typeid
(
itti_s1u_end_marker
).
name
()
;};
const
char
*
get_msg_name
()
{
return
"S1U_END_MARKER"
;};
proto
::
gtpv1u
::
gtpv1u_end_marker
gtp_ies
;
};
...
...
src/gtpv1u/3gpp_29.281.cpp
0 → 100644
View file @
9aa6f728
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file 3gpp_29.281.cpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "3gpp_29.281.hpp"
#include <string>
#include <string.h>
using
namespace
oai
::
cn
::
proto
::
gtpv1u
;
using
namespace
oai
::
cn
::
core
;
//------------------------------------------------------------------------------
gtpv1u_ie
*
gtpv1u_ie
::
new_gtpv1u_ie_from_stream
(
std
::
istream
&
is
)
{
gtpv1u_tlv
tlv
;
tlv
.
load_from
(
is
);
if
(
tlv
.
length
)
{
switch
(
tlv
.
type
)
{
case
GTPU_IE_RECOVERY
:
{
gtpv1u_recovery_ie
*
ie
=
new
gtpv1u_recovery_ie
(
tlv
);
ie
->
load_from
(
is
);
return
ie
;
}
break
;
case
GTPU_IE_TUNNEL_ENDPOINT_IDENTIFIER_DATA_I
:
{
gtpv1u_tunnel_endpoint_identifier_data_i_ie
*
ie
=
new
gtpv1u_tunnel_endpoint_identifier_data_i_ie
(
tlv
);
ie
->
load_from
(
is
);
return
ie
;
}
break
;
case
GTPU_IE_GTP_U_PEER_ADDRESS
:
{
gtpv1u_gtp_u_peer_address_ie
*
ie
=
new
gtpv1u_gtp_u_peer_address_ie
(
tlv
);
ie
->
load_from
(
is
);
return
ie
;
}
break
;
case
GTPU_IE_PRIVATE_EXTENSION
:
{
gtpv1u_private_extension_ie
*
ie
=
new
gtpv1u_private_extension_ie
(
tlv
);
ie
->
load_from
(
is
);
return
ie
;
}
break
;
default:
Logger
::
gtpv1_u
().
error
(
"Unknown GTP IE type %d (length %d)"
,
tlv
.
get_type
(),
tlv
.
get_length
());
return
nullptr
;
}
}
else
{
Logger
::
gtpv1_u
().
error
(
"GTP IE type %d length %d"
,
tlv
.
get_type
(),
tlv
.
get_length
());
return
nullptr
;
}
}
//------------------------------------------------------------------------------
gtpv1u_msg
::
gtpv1u_msg
(
const
gtpv1u_echo_request
&
gtp_ies
)
:
gtpv1u_msg_header
()
{
ies
=
{};
set_message_type
(
GTPU_ECHO_REQUEST
);
if
(
gtp_ies
.
private_extension
.
first
)
{
std
::
shared_ptr
<
gtpv1u_private_extension_ie
>
sie
(
new
gtpv1u_private_extension_ie
(
gtp_ies
.
private_extension
.
second
));
add_ie
(
sie
);}
}
//------------------------------------------------------------------------------
gtpv1u_msg
::
gtpv1u_msg
(
const
gtpv1u_echo_response
&
gtp_ies
)
:
gtpv1u_msg_header
()
{
ies
=
{};
set_message_type
(
GTPU_ECHO_RESPONSE
);
if
(
gtp_ies
.
recovery
.
first
)
{
std
::
shared_ptr
<
gtpv1u_recovery_ie
>
sie
(
new
gtpv1u_recovery_ie
(
gtp_ies
.
recovery
.
second
));
add_ie
(
sie
);}
if
(
gtp_ies
.
private_extension
.
first
)
{
std
::
shared_ptr
<
gtpv1u_private_extension_ie
>
sie
(
new
gtpv1u_private_extension_ie
(
gtp_ies
.
private_extension
.
second
));
add_ie
(
sie
);}
}
src/gtpv1u/3gpp_29.281.hpp
View file @
9aa6f728
...
...
@@ -38,6 +38,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <sys/socket.h>
#include "3gpp_29.281.h"
#include "msg_gtpv1u.hpp"
...
...
@@ -108,8 +109,8 @@ public:
explicit
gtpv1u_ie
(
const
gtpv1u_tlv
&
t
)
:
tlv
(
t
)
{}
explicit
gtpv1u_ie
(
const
uint8_t
tlv_type
)
:
explicit
gtpv1u_ie
(
const
uint8_t
tlv_type
)
:
tlv
()
{
tlv
.
type
=
tlv_type
;
}
...
...
@@ -194,19 +195,19 @@ private:
// GTP-PDU.
uint8_t
next_extension_header_type
;
bool
has_teid_
;
public:
gtpv1u_msg_header
()
{
u1
.
b
=
0
;
message_type
=
0
;
message_length
=
GTPV1U_MSG_HEADER_MIN_SIZE
;
//
message_length
=
0
;
//
teid
=
0
;
sequence_number
=
0
;
npdu_number
=
0
;
next_extension_header_type
=
0
;
u1
.
bf
.
version
=
1
;
u1
.
bf
.
pt
=
1
;
}
gtpv1u_msg_header
(
const
gtpv1u_msg_header
&
h
)
{
...
...
@@ -217,6 +218,7 @@ public:
sequence_number
=
h
.
sequence_number
;
npdu_number
=
h
.
npdu_number
;
next_extension_header_type
=
h
.
next_extension_header_type
;
has_teid_
=
h
.
has_teid_
;
}
gtpv1u_msg_header
&
operator
=
(
gtpv1u_msg_header
other
)
...
...
@@ -232,14 +234,25 @@ public:
}
void
set_teid
(
const
uint32_t
&
tid
)
{
teid
=
tid
;
teid
=
tid
;
}
uint32_t
get_teid
()
const
{
return
teid
;
}
bool
get_sequence_number
(
uint16_t
&
vsequence_number
)
const
{
if
(
u1
.
bf
.
s
)
{
// if inter rat then check in more details
vsequence_number
=
sequence_number
;
return
true
;
}
// if (...) {
// vsequence_number = 0;
// return true;
// }
return
false
;
}
void
set_message_type
(
const
uint8_t
&
t
)
{
message_type
=
t
;
}
...
...
@@ -256,8 +269,19 @@ public:
return
message_length
;
}
// get payload length without extra header length
uint16_t
get_message_length_wo_xheader
()
const
{
uint16_t
ml
=
message_length
;
if
(
u1
.
bf
.
s
)
{
ml
-=
sizeof
(
sequence_number
);
}
return
ml
;
}
void
set_sequence_number
(
const
uint16_t
&
s
)
{
message_length
+=
sizeof
(
sequence_number
);
sequence_number
=
s
;
u1
.
bf
.
s
=
1
;
}
uint16_t
get_sequence_number
()
const
{
...
...
@@ -274,9 +298,11 @@ public:
auto
be_teid
=
htobe32
(
teid
);
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
be_teid
),
sizeof
(
be_teid
));
if
(
u1
.
b
&
0x07
)
{
if
(
u1
.
b
f
.
s
)
{
auto
be_sequence_number
=
htobe16
(
sequence_number
);
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
be_sequence_number
),
sizeof
(
be_sequence_number
));
}
if
(
u1
.
b
&
0x05
)
{
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
npdu_number
),
sizeof
(
npdu_number
));
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
next_extension_header_type
),
sizeof
(
next_extension_header_type
));
}
...
...
@@ -287,9 +313,24 @@ public:
is
.
read
(
reinterpret_cast
<
char
*>
(
&
message_type
),
sizeof
(
message_type
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
message_length
),
sizeof
(
message_length
));
message_length
=
be16toh
(
message_length
);
if
(
u1
.
b
&
0x07
)
{
is
.
read
(
reinterpret_cast
<
char
*>
(
&
teid
),
sizeof
(
teid
));
teid
=
be32toh
(
teid
);
// if (message_length >= sizeof(teid)){
// switch (message_type) {
// case GTPU_ECHO_REQUEST:
// case GTPU_ECHO_RESPONSE:
// case GTPU_ERROR_INDICATION:
// case GTPU_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION:
// break;
// default:;
// }
// }
if
(
u1
.
bf
.
s
)
{
is
.
read
(
reinterpret_cast
<
char
*>
(
&
sequence_number
),
sizeof
(
sequence_number
));
sequence_number
=
be16toh
(
sequence_number
);
}
if
(
u1
.
b
&
0x05
)
{
is
.
read
(
reinterpret_cast
<
char
*>
(
&
npdu_number
),
sizeof
(
npdu_number
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
next_extension_header_type
),
sizeof
(
next_extension_header_type
));
}
...
...
@@ -299,25 +340,27 @@ public:
class
gtpv1u_msg
:
public
gtpv1u_msg_header
{
public:
uint16_t
remote_port
;
struct
sockaddr_storage
r_endpoint
;
socklen_t
r_endpoint_addr_len
;
std
::
vector
<
std
::
shared_ptr
<
gtpv1u_ie
>>
ies
;
gtpv1u_msg
()
:
gtpv1u_msg_header
(),
remote_port
(
0
),
ies
()
{}
gtpv1u_msg
(
const
gtpv1u_msg
&
m
)
:
gtpv1u_msg_header
(
m
),
remote_port
(
m
.
remote_port
),
gtpv1u_msg
()
:
gtpv1u_msg_header
(),
r_endpoint
(),
r_endpoint_addr_len
(
0
),
ies
()
{}
gtpv1u_msg
(
const
gtpv1u_msg
&
m
)
:
gtpv1u_msg_header
(
m
),
r_endpoint
(
m
.
r_endpoint
),
r_endpoint_addr_len
(
m
.
r_endpoint_addr_len
),
ies
(
m
.
ies
)
{}
gtpv1u_msg
&
operator
=
(
gtpv1u_msg
other
)
{
std
::
swap
(
remote_port
,
other
.
remote_port
);
std
::
swap
(
r_endpoint
,
other
.
r_endpoint
);
std
::
swap
(
r_endpoint_addr_len
,
other
.
r_endpoint_addr_len
);
std
::
swap
(
ies
,
other
.
ies
);
return
*
this
;
}
explicit
gtpv1u_msg
(
const
gtpv1u_msg_header
&
hdr
)
:
gtpv1u_msg_header
(
hdr
),
remote_port
(
0
),
ies
()
{}
}
explicit
gtpv1u_msg
(
const
gtpv1u_msg_header
&
hdr
)
:
gtpv1u_msg_header
(
hdr
),
r_endpoint
(),
r_endpoint_addr_len
(
0
),
ies
()
{}
explicit
gtpv1u_msg
(
const
gtpv1u_echo_request
&
gtp_ies
);
explicit
gtpv1u_msg
(
const
gtpv1u_echo_response
&
gtp_ies
);
explicit
gtpv1u_msg
(
const
gtpv1u_error_indication
&
gtp_ies
);
...
...
@@ -333,7 +376,7 @@ public:
//std::cout << std::dec<< " add_ie = " << get_message_length() << " -> "<< get_message_length() + gtpv1u_tlv::tlv_ie_length + ie.get()->tlv.get_length() << std::endl;
set_message_length
(
get_message_length
()
+
gtpv1u_tlv
::
tlv_ie_length
+
ie
.
get
()
->
tlv
.
get_length
());
}
void
to_core_type
(
gtpv1u_echo_request
&
s
)
{
for
(
auto
i
:
ies
)
{
i
.
get
()
->
to_core_type
(
s
);
...
...
@@ -359,7 +402,7 @@ public:
i
.
get
()
->
to_core_type
(
s
);
}
}
void
dump_to
(
std
::
ostream
&
os
)
{
gtpv1u_msg_header
::
dump_to
(
os
);
for
(
auto
i
:
ies
)
{
...
...
@@ -369,7 +412,7 @@ public:
void
load_from
(
std
::
istream
&
is
)
{
gtpv1u_msg_header
::
load_from
(
is
);
uint16_t
check_msg_length
=
get_message_length
();
// total length of message - fixed part of the gtpu header (GTPV1U_MSG_HEADER_MIN_SIZE)
uint16_t
check_msg_length
=
get_message_length
_wo_xheader
();
// total length of message - fixed part of the gtpu header (GTPV1U_MSG_HEADER_MIN_SIZE)
gtpv1u_ie
*
ie
=
nullptr
;
uint16_t
ies_length
=
0
;
//std::cout << std::dec<< " check_msg_length = " << check_msg_length << std::endl;
...
...
@@ -382,7 +425,7 @@ public:
}
}
while
((
ie
)
&&
(
ies_length
<
check_msg_length
));
if
(
ies_length
!=
check_msg_length
)
{
if
(
ies_length
>
check_msg_length
)
{
// should be <= (padding)
//std::cout << " check_msg_length = " << check_msg_length << " ies_length = " << ies_length << std::endl;
throw
gtpu_msg_bad_length_exception
(
get_message_type
(),
get_message_length
());
}
...
...
@@ -441,7 +484,7 @@ public:
//tlv.load_from(is);
is
.
read
(
reinterpret_cast
<
char
*>
(
&
restart_counter
),
sizeof
(
restart_counter
));
}
void
to_core_type
(
gtpv1u_ies_container
&
s
)
{
core
::
recovery_t
v
=
{};
to_core_type
(
v
);
...
...
@@ -576,7 +619,7 @@ public:
tlv
.
set_length
(
sizeof
(
extension_identifier
)
+
extension_value
.
size
());
}
//--------
gtpv1u_private_extension_ie
()
:
gtpv1u_ie
(
GTPU_IE_PRIVATE_EXTENSION
),
gtpv1u_private_extension_ie
()
:
gtpv1u_ie
(
GTPU_IE_PRIVATE_EXTENSION
),
extension_identifier
(
0
),
extension_value
()
{
...
...
src/gtpv1u/CMakeLists.txt
View file @
9aa6f728
...
...
@@ -19,6 +19,7 @@
# contact@openairinterface.org
################################################################################
add_library
(
GTPV1U STATIC
3gpp_29.281.cpp
gtpv1u.cpp
)
...
...
src/gtpv1u/gtpv1u.cpp
View file @
9aa6f728
...
...
@@ -25,6 +25,7 @@
\email: lionel.gauthier@eurecom.fr
*/
#include "common_root_types.h"
#include "gtpu.h"
#include "gtpv1u.hpp"
...
...
@@ -37,8 +38,6 @@ using namespace std;
extern
itti_mw
*
itti_inst
;
uint64_t
oai
::
cn
::
proto
::
gtpv1u
::
gtpu_l4_stack
::
gtpu_tx_id_generator
=
1
;
//odd in any case.
//------------------------------------------------------------------------------
static
std
::
string
string_to_hex
(
const
std
::
string
&
input
)
{
...
...
@@ -61,7 +60,7 @@ void udp_server::udp_read_loop(int cpu)
socklen_t
r_endpoint_addr_len
=
0
;
struct
sockaddr_storage
r_endpoint
=
{};
size_t
bytes_received
=
0
;
if
(
cpu
)
{
cpu_set_t
cpuset
;
CPU_SET
(
cpu
,
&
cpuset
);
...
...
@@ -71,9 +70,9 @@ void udp_server::udp_read_loop(int cpu)
struct
sched_param
sparam
;
memset
(
&
sparam
,
0
,
sizeof
(
sparam
));
sparam
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
policy
=
SCHED_FIFO
;
policy
=
SCHED_FIFO
;
pthread_setschedparam
(
pthread_self
(),
policy
,
&
sparam
);
while
(
1
)
{
r_endpoint_addr_len
=
sizeof
(
struct
sockaddr_storage
);
if
((
bytes_received
=
recvfrom
(
socket_
,
recv_buffer_
,
UDP_RECV_BUFFER_SIZE
,
0
,
(
struct
sockaddr
*
)
&
r_endpoint
,
&
r_endpoint_addr_len
))
>
0
)
{
...
...
@@ -311,4 +310,33 @@ void gtpu_l4_stack::send_g_pdu(const struct sockaddr_in6& peer_addr, const teid_
gtpuhdr
->
teid
=
htobe32
(
teid
);
udp_s
.
async_send_to
(
reinterpret_cast
<
const
char
*>
(
gtpuhdr
),
payload_len
+
sizeof
(
struct
gtpuhdr
),
peer_addr
);
}
//------------------------------------------------------------------------------
void
gtpu_l4_stack
::
send_response
(
const
gtpv1u_echo_response
&
gtp_ies
)
{
std
::
ostringstream
oss
(
std
::
ostringstream
::
binary
);
gtpv1u_msg
msg
(
gtp_ies
);
uint32_t
teid
=
UNASSIGNED_TEID
;
if
(
gtp_ies
.
get_teid
(
teid
))
{
msg
.
set_teid
(
teid
);
}
uint16_t
sn
=
0
;
if
(
gtp_ies
.
get_sequence_number
(
sn
))
{
msg
.
set_sequence_number
(
sn
);
}
msg
.
dump_to
(
oss
);
std
::
string
bstream
=
oss
.
str
();
switch
(
gtp_ies
.
r_endpoint
.
ss_family
)
{
case
AF_INET
:
{
const
struct
sockaddr_in
*
const
sin
=
reinterpret_cast
<
const
sockaddr_in
*
const
>
(
&
gtp_ies
.
r_endpoint
);
udp_s
.
async_send_to
(
reinterpret_cast
<
const
char
*>
(
bstream
.
c_str
()),
bstream
.
length
(),
*
sin
);
}
break
;
case
AF_INET6
:
{
const
struct
sockaddr_in6
*
const
sin6
=
reinterpret_cast
<
const
sockaddr_in6
*
const
>
(
&
gtp_ies
.
r_endpoint
);
udp_s
.
async_send_to
(
reinterpret_cast
<
const
char
*>
(
bstream
.
c_str
()),
bstream
.
length
(),
*
sin6
);
}
break
;
default:
Logger
::
gtpv1_u
().
debug
(
"gtpu_l4_stack::send_response %s, no known peer addr"
,
gtp_ies
.
get_msg_name
());
}
}
src/gtpv1u/gtpv1u.hpp
View file @
9aa6f728
...
...
@@ -144,7 +144,6 @@ class gtpu_l4_stack {
#define GTPV1U_PROC_TIME_OUT_MS ((GTPV1U_T3_RESPONSE_MS) * (GTPV1U_N3_REQUESTS + 1))
protected:
static
uint64_t
gtpu_tx_id_generator
;
uint32_t
id
;
udp_server
udp_s
;
...
...
@@ -171,9 +170,7 @@ public:
void
send_g_pdu
(
const
struct
sockaddr_in
&
peer_addr
,
const
teid_t
teid
,
const
char
*
payload
,
const
ssize_t
payload_len
);
void
send_g_pdu
(
const
struct
sockaddr_in6
&
peer_addr
,
const
teid_t
teid
,
const
char
*
payload
,
const
ssize_t
payload_len
);
//virtual uint32_t send_request(const boost::asio::ip::udp::endpoint& dest, const teid_t teid, const gtpv1u_create_session_request& gtp_ies, const core::itti::task_id_t& task_id, const uint64_t gtp_tx_id);
//virtual void send_response(const boost::asio::ip::udp::endpoint& dest, const teid_t teid, const gtpv1u_create_session_response& gtp_ies, const uint64_t gtp_tx_id);
//virtual uint32_t send_gpdu(const boost::asio::ip::udp::endpoint& dest, const teid_t teid, const gtpv1u_create_session_request& gtp_ies, const core::itti::task_id_t& task_id, const uint64_t gtp_tx_id);
void
send_response
(
const
gtpv1u_echo_response
&
gtp_ies
);
};
}
// namespace gtpv1u
...
...
src/gtpv1u/msg_gtpv1u.hpp
View file @
9aa6f728
...
...
@@ -35,12 +35,36 @@
#include "common_defs.h"
#include <vector>
#include <sys/socket.h>
namespace
oai
::
cn
::
proto
::
gtpv1u
{
class
gtpv1u_ies_container
{
public:
static
const
uint8_t
msg_id
=
0
;
static
const
uint8_t
msg_id
=
0
;
struct
sockaddr_storage
r_endpoint
;
socklen_t
r_endpoint_addr_len
;
std
::
pair
<
bool
,
uint32_t
>
teid
;
std
::
pair
<
bool
,
uint16_t
>
sequence_number
;
std
::
pair
<
bool
,
uint8_t
>
npdu_number
;
gtpv1u_ies_container
()
:
r_endpoint
(),
r_endpoint_addr_len
(
0
),
teid
(),
sequence_number
(),
npdu_number
()
{}
gtpv1u_ies_container
(
const
gtpv1u_ies_container
&
i
)
:
r_endpoint
(
i
.
r_endpoint
),
r_endpoint_addr_len
(
i
.
r_endpoint_addr_len
),
teid
(
i
.
teid
),
sequence_number
(
i
.
sequence_number
),
npdu_number
(
i
.
npdu_number
)
{}
gtpv1u_ies_container
&
operator
=
(
gtpv1u_ies_container
other
)
{
std
::
swap
(
r_endpoint
,
other
.
r_endpoint
);
std
::
swap
(
r_endpoint_addr_len
,
other
.
r_endpoint_addr_len
);
std
::
swap
(
teid
,
other
.
teid
);
std
::
swap
(
sequence_number
,
other
.
sequence_number
);
std
::
swap
(
npdu_number
,
other
.
npdu_number
);
return
*
this
;
}
virtual
bool
get
(
core
::
recovery_t
&
v
)
const
{
throw
gtpu_msg_illegal_ie_exception
(
0
,
GTPU_IE_RECOVERY
);}
virtual
bool
get
(
core
::
tunnel_endpoint_identifier_data_i_t
&
v
)
const
{
throw
gtpu_msg_illegal_ie_exception
(
0
,
GTPU_IE_TUNNEL_ENDPOINT_IDENTIFIER_DATA_I
);}
...
...
@@ -53,7 +77,14 @@ public:
virtual
void
set
(
const
core
::
gtp_u_peer_address_t
&
v
)
{
throw
gtpu_msg_illegal_ie_exception
(
0
,
GTPU_IE_GTP_U_PEER_ADDRESS
);}
virtual
void
set
(
const
core
::
extension_header_type_list_t
&
v
)
{
throw
gtpu_msg_illegal_ie_exception
(
0
,
GTPU_IE_EXTENSION_HEADER_TYPE_LIST
);}
virtual
void
set
(
const
core
::
private_extension_t
&
v
)
{
throw
gtpu_msg_illegal_ie_exception
(
0
,
GTPU_IE_PRIVATE_EXTENSION
);}
virtual
~
gtpv1u_ies_container
()
{};
virtual
void
set_teid
(
const
uint32_t
pteid
)
{
teid
.
second
=
pteid
;
teid
.
first
=
true
;}
virtual
void
set_sequence_number
(
const
uint16_t
psequence_number
)
{
sequence_number
.
second
=
psequence_number
;
sequence_number
.
first
=
true
;}
virtual
void
set_npdu_number
(
const
uint8_t
pnpdu_number
)
{
npdu_number
.
second
=
pnpdu_number
;
npdu_number
.
first
=
true
;}
virtual
bool
get_teid
(
uint32_t
&
v
)
const
{
if
(
teid
.
first
)
{
v
=
teid
.
second
;
return
true
;}
return
false
;}
virtual
bool
get_sequence_number
(
uint16_t
&
v
)
const
{
if
(
sequence_number
.
first
)
{
v
=
sequence_number
.
second
;
return
true
;}
return
false
;}
virtual
bool
get_npdu_number
(
uint8_t
&
v
)
const
{
if
(
npdu_number
.
first
)
{
v
=
npdu_number
.
second
;
return
true
;}
return
false
;}
};
//------------------------------------------------------------------------------
...
...
@@ -63,10 +94,11 @@ public:
std
::
pair
<
bool
,
core
::
private_extension_t
>
private_extension
;
gtpv1u_echo_request
()
:
private_extension
()
{}
gtpv1u_echo_request
(
const
gtpv1u_echo_request
&
i
)
:
private_extension
(
i
.
private_extension
)
{}
gtpv1u_echo_request
()
:
gtpv1u_ies_container
(),
private_extension
()
{}
gtpv1u_echo_request
(
const
gtpv1u_echo_request
&
i
)
:
gtpv1u_ies_container
(
i
),
private_extension
(
i
.
private_extension
)
{}
gtpv1u_echo_request
&
operator
=
(
gtpv1u_echo_request
other
)
{
this
->
gtpv1u_ies_container
::
operator
=
(
other
);
std
::
swap
(
private_extension
,
other
.
private_extension
);
return
*
this
;
}
...
...
@@ -85,13 +117,14 @@ public:
std
::
pair
<
bool
,
core
::
recovery_t
>
recovery
;
std
::
pair
<
bool
,
core
::
private_extension_t
>
private_extension
;
gtpv1u_echo_response
()
:
recovery
(),
private_extension
()
{}
gtpv1u_echo_response
()
:
gtpv1u_ies_container
(),
recovery
(),
private_extension
()
{}
gtpv1u_echo_response
(
const
gtpv1u_echo_response
&
i
)
:
recovery
(
i
.
recovery
),
private_extension
(
i
.
private_extension
)
{}
gtpv1u_echo_response
(
const
gtpv1u_echo_response
&
i
)
:
gtpv1u_ies_container
(
i
),
recovery
(
i
.
recovery
),
private_extension
(
i
.
private_extension
)
{}
static
const
char
*
get_msg_name
()
{
return
"GTPU_ECHO_RESPONSE"
;};
gtpv1u_echo_response
&
operator
=
(
gtpv1u_echo_response
other
)
{
this
->
gtpv1u_ies_container
::
operator
=
(
other
);
std
::
swap
(
recovery
,
other
.
recovery
);
std
::
swap
(
private_extension
,
other
.
private_extension
);
return
*
this
;
...
...
@@ -114,15 +147,16 @@ public:
std
::
pair
<
bool
,
core
::
gtp_u_peer_address_t
>
gtp_u_peer_address
;
std
::
pair
<
bool
,
core
::
private_extension_t
>
private_extension
;
gtpv1u_error_indication
()
:
tunnel_endpoint_identifier_data_i
(),
gtp_u_peer_address
(),
private_extension
()
{}
gtpv1u_error_indication
()
:
gtpv1u_ies_container
(),
tunnel_endpoint_identifier_data_i
(),
gtp_u_peer_address
(),
private_extension
()
{}
gtpv1u_error_indication
(
const
gtpv1u_error_indication
&
i
)
:
gtpv1u_error_indication
(
const
gtpv1u_error_indication
&
i
)
:
gtpv1u_ies_container
(
i
),
tunnel_endpoint_identifier_data_i
(
i
.
tunnel_endpoint_identifier_data_i
),
gtp_u_peer_address
(
i
.
gtp_u_peer_address
),
private_extension
(
i
.
private_extension
)
{}
gtpv1u_error_indication
&
operator
=
(
gtpv1u_error_indication
other
)
{
this
->
gtpv1u_ies_container
::
operator
=
(
other
);
std
::
swap
(
tunnel_endpoint_identifier_data_i
,
other
.
tunnel_endpoint_identifier_data_i
);
std
::
swap
(
gtp_u_peer_address
,
other
.
gtp_u_peer_address
);
std
::
swap
(
private_extension
,
other
.
private_extension
);
...
...
@@ -146,14 +180,16 @@ public:
std
::
pair
<
bool
,
core
::
extension_header_type_list_t
>
extension_header_type_list
;
gtpv1u_supported_extension_headers_notification
()
:
gtpv1u_supported_extension_headers_notification
()
:
gtpv1u_ies_container
(),
extension_header_type_list
()
{}
gtpv1u_supported_extension_headers_notification
(
const
gtpv1u_supported_extension_headers_notification
&
i
)
:
gtpv1u_ies_container
(
i
),
extension_header_type_list
(
i
.
extension_header_type_list
)
{}
gtpv1u_supported_extension_headers_notification
&
operator
=
(
gtpv1u_supported_extension_headers_notification
other
)
{
this
->
gtpv1u_ies_container
::
operator
=
(
other
);
std
::
swap
(
extension_header_type_list
,
other
.
extension_header_type_list
);
return
*
this
;
}
...
...
@@ -172,14 +208,15 @@ public:
std
::
pair
<
bool
,
core
::
private_extension_t
>
private_extension
;
gtpv1u_end_marker
()
:
gtpv1u_end_marker
()
:
gtpv1u_ies_container
(),
private_extension
()
{}
gtpv1u_end_marker
(
const
gtpv1u_end_marker
&
i
)
:
gtpv1u_end_marker
(
const
gtpv1u_end_marker
&
i
)
:
gtpv1u_ies_container
(
i
),
private_extension
(
i
.
private_extension
)
{}
gtpv1u_end_marker
&
operator
=
(
gtpv1u_end_marker
other
)
{
this
->
gtpv1u_ies_container
::
operator
=
(
other
);
std
::
swap
(
private_extension
,
other
.
private_extension
);
return
*
this
;
}
...
...
src/spgwu/simpleswitch/spgwu_s1u.cpp
0 → 100644
View file @
9aa6f728
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file spgwu_s1u.cpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "common_defs.h"
#include "gtpu.h"
#include "itti.hpp"
#include "logger.hpp"
#include "pfcp_switch.hpp"
#include "spgwu_config.hpp"
#include "spgwu_s1u.hpp"
#include <stdexcept>
using
namespace
oai
::
cn
::
core
;
using
namespace
oai
::
cn
::
proto
::
gtpv1u
;
using
namespace
oai
::
cn
::
core
::
itti
;
using
namespace
oai
::
cn
::
nf
::
spgwu
;
using
namespace
std
;
extern
itti_mw
*
itti_inst
;
extern
pfcp_switch
*
pfcp_switch_inst
;
extern
spgwu_config
spgwu_cfg
;
extern
spgwu_s1u
*
spgwu_s1u_inst
;
void
spgwu_s1u_task
(
void
*
);
//------------------------------------------------------------------------------
void
spgwu_s1u_task
(
void
*
args_p
)
{
const
task_id_t
task_id
=
TASK_SPGWU_S1U
;
itti_inst
->
notify_task_ready
(
task_id
);
do
{
std
::
shared_ptr
<
itti_msg
>
shared_msg
=
itti_inst
->
receive_msg
(
task_id
);
auto
*
msg
=
shared_msg
.
get
();
switch
(
msg
->
msg_type
)
{
case
S1U_ECHO_RESPONSE
:
spgwu_s1u_inst
->
handle_itti_msg
(
std
::
static_pointer_cast
<
itti_s1u_echo_response
>
(
shared_msg
));
break
;
case
TIME_OUT
:
if
(
itti_msg_timeout
*
to
=
dynamic_cast
<
itti_msg_timeout
*>
(
msg
))
{
Logger
::
spgwu_s1u
().
info
(
"TIME-OUT event timer id %d"
,
to
->
timer_id
);
}
break
;
case
TERMINATE
:
if
(
itti_msg_terminate
*
terminate
=
dynamic_cast
<
itti_msg_terminate
*>
(
msg
))
{
Logger
::
spgwu_s1u
().
info
(
"Received terminate message"
);
return
;
}
break
;
default:
Logger
::
spgwu_s1u
().
info
(
"no handler for msg type %d"
,
msg
->
msg_type
);
}
}
while
(
true
);
}
//------------------------------------------------------------------------------
spgwu_s1u
::
spgwu_s1u
()
:
gtpu_l4_stack
(
spgwu_cfg
.
s1_up
.
addr4
,
spgwu_cfg
.
s1_up
.
port
,
spgwu_cfg
.
s1_up
.
cpu_id_thread_loop_read
)
{
Logger
::
spgwu_s1u
().
startup
(
"Starting..."
);
if
(
itti_inst
->
create_task
(
TASK_SPGWU_S1U
,
spgwu_s1u_task
,
nullptr
)
)
{
Logger
::
spgwu_s1u
().
error
(
"Cannot create task TASK_SPGWU_S1U"
);
throw
std
::
runtime_error
(
"Cannot create task TASK_SPGWU_S1U"
);
}
Logger
::
spgwu_s1u
().
startup
(
"Started"
);
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
handle_receive
(
char
*
recv_buffer
,
const
std
::
size_t
bytes_transferred
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
)
{
#define GTPU_MESSAGE_FLAGS_POS_IN_UDP_PAYLOAD 0
struct
gtpuhdr
*
gtpuh
=
(
struct
gtpuhdr
*
)
&
recv_buffer
[
0
];
if
(
gtpuh
->
version
==
1
)
{
// Do it fast, do not go throught handle_receive_gtpv1u_msg()
if
(
gtpuh
->
message_type
==
GTPU_G_PDU
)
{
uint8_t
gtp_flags
=
recv_buffer
[
GTPU_MESSAGE_FLAGS_POS_IN_UDP_PAYLOAD
];
std
::
size_t
gtp_payload_offset
=
GTPV1U_MSG_HEADER_MIN_SIZE
;
std
::
size_t
gtp_payload_length
=
be16toh
(
gtpuh
->
message_length
);
if
(
gtp_flags
&
0x07
)
{
gtp_payload_offset
+=
4
;
gtp_payload_length
-=
4
;
}
uint32_t
tunnel_id
=
be32toh
(
gtpuh
->
teid
);
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
&
recv_buffer
[
gtp_payload_offset
];
if
(
iph
->
version
==
4
)
{
pfcp_switch_inst
->
pfcp_session_look_up_pack_in_access
(
iph
,
gtp_payload_length
,
r_endpoint
,
r_endpoint_addr_len
,
tunnel_id
);
}
else
if
(
iph
->
version
==
6
)
{
pfcp_switch_inst
->
pfcp_session_look_up_pack_in_access
((
struct
ipv6hdr
*
)
iph
,
gtp_payload_length
,
r_endpoint
,
r_endpoint_addr_len
,
tunnel_id
);
}
else
{
Logger
::
spgwu_s1u
().
trace
(
"Unknown GTPU_G_PDU packet"
);
}
}
else
{
//Logger::spgwu_s1u().info( "handle_receive(%d bytes)", bytes_transferred);
//std::cout << string_to_hex(recv_buffer, bytes_transferred) << std::endl;
std
::
istringstream
iss
(
std
::
istringstream
::
binary
);
iss
.
rdbuf
()
->
pubsetbuf
(
recv_buffer
,
bytes_transferred
);
gtpv1u_msg
msg
=
{};
try
{
msg
.
load_from
(
iss
);
handle_receive_gtpv1u_msg
(
msg
,
r_endpoint
,
r_endpoint_addr_len
);
}
catch
(
gtpu_exception
&
e
)
{
Logger
::
spgwu_s1u
().
info
(
"handle_receive exception %s"
,
e
.
what
());
}
}
}
else
{
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
&
recv_buffer
[
0
];
if
(
iph
->
version
==
4
)
{
pfcp_switch_inst
->
pfcp_session_look_up_pack_in_access
(
iph
,
bytes_transferred
,
r_endpoint
,
r_endpoint_addr_len
);
}
else
if
(
iph
->
version
==
6
)
{
pfcp_switch_inst
->
pfcp_session_look_up_pack_in_access
((
struct
ipv6hdr
*
)
iph
,
bytes_transferred
,
r_endpoint
,
r_endpoint_addr_len
);
}
else
{
Logger
::
spgwu_s1u
().
trace
(
"Unknown IPX packet"
);
}
}
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
handle_receive_gtpv1u_msg
(
gtpv1u_msg
&
msg
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
)
{
//Logger::spgwu_s1u().trace( "handle_receive_gtpv1u_msg msg type %d length %d", msg.get_message_type(), msg.get_message_length());
switch
(
msg
.
get_message_type
())
{
case
GTPU_ECHO_REQUEST
:
handle_receive_echo_request
(
msg
,
r_endpoint
,
r_endpoint_addr_len
);
break
;
case
GTPU_ECHO_RESPONSE
:
case
GTPU_ERROR_INDICATION
:
case
GTPU_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION
:
case
GTPU_END_MARKER
:
case
GTPU_G_PDU
:
break
;
default:
Logger
::
spgwu_s1u
().
error
(
"handle_receive_gtpv1u_msg msg length %d"
,
msg
.
get_message_length
());
}
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
send_g_pdu
(
const
struct
in_addr
&
peer_addr
,
const
uint16_t
peer_udp_port
,
const
uint32_t
tunnel_id
,
const
char
*
send_buffer
,
const
ssize_t
num_bytes
)
{
//Logger::spgwu_s1u().info( "spgwu_s1u::send_g_pdu() TEID " TEID_FMT " %d bytes", num_bytes);
struct
sockaddr_in
peer_sock_addr
;
peer_sock_addr
.
sin_family
=
AF_INET
;
peer_sock_addr
.
sin_addr
=
peer_addr
;
peer_sock_addr
.
sin_port
=
htobe16
(
peer_udp_port
);
gtpu_l4_stack
::
send_g_pdu
(
peer_sock_addr
,
(
teid_t
)
tunnel_id
,
send_buffer
,
num_bytes
);
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
send_g_pdu
(
const
struct
in6_addr
&
peer_addr
,
const
uint16_t
peer_udp_port
,
const
uint32_t
tunnel_id
,
const
char
*
send_buffer
,
const
ssize_t
num_bytes
)
{
struct
sockaddr_in6
peer_sock_addr
;
peer_sock_addr
.
sin6_family
=
AF_INET6
;
peer_sock_addr
.
sin6_addr
=
peer_addr
;
peer_sock_addr
.
sin6_port
=
htobe16
(
peer_udp_port
);
peer_sock_addr
.
sin6_flowinfo
=
0
;
peer_sock_addr
.
sin6_scope_id
=
0
;
gtpu_l4_stack
::
send_g_pdu
(
peer_sock_addr
,
tunnel_id
,
send_buffer
,
num_bytes
);
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
handle_receive_echo_request
(
gtpv1u_msg
&
msg
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
)
{
itti_s1u_echo_request
*
echo
=
new
itti_s1u_echo_request
(
TASK_SPGWU_S1U
,
TASK_SPGWU_APP
);
gtpv1u_echo_request
msg_ies_container
=
{};
msg
.
to_core_type
(
echo
->
gtp_ies
);
echo
->
gtp_ies
.
r_endpoint
=
r_endpoint
;
echo
->
gtp_ies
.
r_endpoint_addr_len
=
r_endpoint_addr_len
;
echo
->
gtp_ies
.
set_teid
(
msg
.
get_teid
());
uint16_t
sn
=
0
;
if
(
msg
.
get_sequence_number
(
sn
))
{
echo
->
gtp_ies
.
set_sequence_number
(
sn
);
}
std
::
shared_ptr
<
itti_s1u_echo_request
>
secho
=
std
::
shared_ptr
<
itti_s1u_echo_request
>
(
echo
);
int
ret
=
itti_inst
->
send_msg
(
secho
);
if
(
RETURNok
!=
ret
)
{
Logger
::
spgwu_s1u
().
error
(
"Could not send ITTI message %s to task TASK_SPGWU_APP"
,
echo
->
get_msg_name
());
}
}
//------------------------------------------------------------------------------
void
spgwu_s1u
::
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_s1u_echo_response
>
m
)
{
send_response
(
m
->
gtp_ies
);
}
src/spgwu/simpleswitch/spgwu_s1u.hpp
0 → 100644
View file @
9aa6f728
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file spgwu_s1u.hpp
\author Lionel GAUTHIER
\date 2019
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_SGWU_S1U_HPP_SEEN
#define FILE_SGWU_S1U_HPP_SEEN
#include "gtpv1u.hpp"
#include "itti_msg_s1u.hpp"
#include "msg_gtpv1u.hpp"
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <netinet/in.h>
#include <thread>
namespace
oai
::
cn
::
nf
::
spgwu
{
class
spgwu_s1u
:
public
oai
::
cn
::
proto
::
gtpv1u
::
gtpu_l4_stack
{
private:
std
::
thread
::
id
thread_id
;
std
::
thread
thread
;
void
handle_receive_gtpv1u_msg
(
proto
::
gtpv1u
::
gtpv1u_msg
&
msg
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
);
void
handle_receive_echo_request
(
proto
::
gtpv1u
::
gtpv1u_msg
&
msg
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
);
public:
spgwu_s1u
();
spgwu_s1u
(
spgwu_s1u
const
&
)
=
delete
;
void
operator
=
(
spgwu_s1u
const
&
)
=
delete
;
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_echo_request& s) {};
void
handle_itti_msg
(
std
::
shared_ptr
<
oai
::
cn
::
core
::
itti
::
itti_s1u_echo_response
>
m
);
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_error_indication& s) {};
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_supported_extension_headers_notification& s) {};
//void handle_itti_msg (oai::cn::core::itti::itti_s1u_end_marker& s) {};
//void send_msg (oai::cn::core::itti::itti_s1u_echo_request& s) {};
//void send_msg (oai::cn::core::itti::itti_s1u_echo_response& s);
//void send_msg (oai::cn::core::itti::itti_s1u_error_indication& s) {};
//void send_msg (oai::cn::core::itti::itti_s1u_supported_extension_headers_notification& s) {};
//void send_msg (oai::cn::core::itti::itti_s1u_end_marker& s) {};
void
handle_receive_s1u_msg
(
proto
::
gtpv1u
::
gtpv1u_msg
&
msg
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
);
void
handle_receive
(
char
*
recv_buffer
,
const
std
::
size_t
bytes_transferred
,
const
struct
sockaddr_storage
&
r_endpoint
,
const
socklen_t
&
r_endpoint_addr_len
);
void
send_g_pdu
(
const
struct
in_addr
&
peer_addr
,
const
uint16_t
peer_udp_port
,
const
uint32_t
tunnel_id
,
const
char
*
send_buffer
,
const
ssize_t
num_bytes
);
void
send_g_pdu
(
const
struct
in6_addr
&
peer_addr
,
const
uint16_t
peer_udp_port
,
const
uint32_t
tunnel_id
,
const
char
*
send_buffer
,
const
ssize_t
num_bytes
);
void
time_out_itti_event
(
const
uint32_t
timer_id
);
};
}
#endif
/* FILE_SGWU_S1U_HPP_SEEN */
src/spgwu/spgwu_app.cpp
View file @
9aa6f728
...
...
@@ -43,12 +43,12 @@ using namespace std;
// C includes
spgwu_sx
*
spgwu_sx_inst
=
nullptr
;
spgwu_sx
*
spgwu_sx_inst
=
nullptr
;
spgwu_s1u
*
spgwu_s1u_inst
=
nullptr
;
extern
itti_mw
*
itti_inst
;
extern
itti_mw
*
itti_inst
;
extern
pfcp_switch
*
pfcp_switch_inst
;
extern
spgwu_app
*
spgwu_app_inst
;
extern
spgwu_app
*
spgwu_app_inst
;
extern
spgwu_config
spgwu_cfg
;
...
...
@@ -65,6 +65,10 @@ void spgwu_app_task (void *args_p)
auto
*
msg
=
shared_msg
.
get
();
switch
(
msg
->
msg_type
)
{
case
S1U_ECHO_REQUEST
:
spgwu_app_inst
->
handle_itti_msg
(
std
::
static_pointer_cast
<
itti_s1u_echo_request
>
(
shared_msg
));
break
;
case
SXAB_SESSION_ESTABLISHMENT_REQUEST
:
spgwu_app_inst
->
handle_itti_msg
(
std
::
static_pointer_cast
<
itti_sxab_session_establishment_request
>
(
shared_msg
));
break
;
...
...
@@ -111,13 +115,6 @@ spgwu_app::spgwu_app (const std::string& config_file)
spgwu_cfg
.
execute
();
spgwu_cfg
.
display
();
// teid_s11_cp = 0;
// teid_s5s8_cp = 0;
// teid_s5s8_up = 0;
// imsi2sgwu_eps_bearer_context = {};
// s11lteid2sgwu_eps_bearer_context = {};
// s5s8lteid2sgwu_contexts = {};
// s5s8uplteid = {};
if
(
itti_inst
->
create_task
(
TASK_SPGWU_APP
,
spgwu_app_task
,
nullptr
)
)
{
Logger
::
spgwu_app
().
error
(
"Cannot create task TASK_SPGWU_APP"
);
throw
std
::
runtime_error
(
"Cannot create task TASK_SPGWU_APP"
);
...
...
@@ -149,9 +146,27 @@ spgwu_app::~spgwu_app()
if
(
spgwu_sx_inst
)
delete
spgwu_sx_inst
;
}
//------------------------------------------------------------------------------
void
spgwu_app
::
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_s1u_echo_request
>
m
)
{
Logger
::
spgwu_app
().
debug
(
"Received %s "
,
m
->
get_msg_name
());
itti_s1u_echo_response
*
s1u_resp
=
new
itti_s1u_echo_response
(
TASK_SPGWU_APP
,
TASK_SPGWU_S1U
);
// May insert a call to a function here(throttle for example)
s1u_resp
->
gtp_ies
.
r_endpoint
=
m
->
gtp_ies
.
r_endpoint
;
s1u_resp
->
gtp_ies
.
r_endpoint_addr_len
=
m
->
gtp_ies
.
r_endpoint_addr_len
;
s1u_resp
->
gtp_ies
.
teid
=
m
->
gtp_ies
.
teid
;
s1u_resp
->
gtp_ies
.
sequence_number
=
m
->
gtp_ies
.
sequence_number
;
std
::
shared_ptr
<
itti_s1u_echo_response
>
msg
=
std
::
shared_ptr
<
itti_s1u_echo_response
>
(
s1u_resp
);
int
ret
=
itti_inst
->
send_msg
(
msg
);
if
(
RETURNok
!=
ret
)
{
Logger
::
spgwu_app
().
error
(
"Could not send ITTI message %s to task TASK_SPGWU_S1U"
,
s1u_resp
->
get_msg_name
());
}
}
//------------------------------------------------------------------------------
void
spgwu_app
::
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_establishment_request
>
m
)
{
Logger
::
spgwu_
sx
().
info
(
"Received SXAB_SESSION_ESTABLISHMENT_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
Logger
::
spgwu_
app
().
info
(
"Received SXAB_SESSION_ESTABLISHMENT_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
itti_sxab_session_establishment_response
*
sx_resp
=
new
itti_sxab_session_establishment_response
(
TASK_SPGWU_APP
,
TASK_SPGWU_SX
);
pfcp_switch_inst
->
handle_pfcp_session_establishment_request
(
m
,
sx_resp
);
...
...
@@ -172,7 +187,7 @@ void spgwu_app::handle_itti_msg (std::shared_ptr<core::itti::itti_sxab_session_e
//------------------------------------------------------------------------------
void
spgwu_app
::
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_modification_request
>
m
)
{
Logger
::
spgwu_
sx
().
info
(
"Received SXAB_SESSION_MODIFICATION_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
Logger
::
spgwu_
app
().
info
(
"Received SXAB_SESSION_MODIFICATION_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
itti_sxab_session_modification_response
*
sx_resp
=
new
itti_sxab_session_modification_response
(
TASK_SPGWU_APP
,
TASK_SPGWU_SX
);
pfcp_switch_inst
->
handle_pfcp_session_modification_request
(
m
,
sx_resp
);
...
...
@@ -188,7 +203,7 @@ void spgwu_app::handle_itti_msg (std::shared_ptr<core::itti::itti_sxab_session_m
//------------------------------------------------------------------------------
void
spgwu_app
::
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_deletion_request
>
m
)
{
Logger
::
spgwu_
sx
().
info
(
"Received SXAB_SESSION_DELETION_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
Logger
::
spgwu_
app
().
info
(
"Received SXAB_SESSION_DELETION_REQUEST seid "
SEID_FMT
" "
,
m
->
seid
);
itti_sxab_session_deletion_response
*
sx_resp
=
new
itti_sxab_session_deletion_response
(
TASK_SPGWU_APP
,
TASK_SPGWU_SX
);
pfcp_switch_inst
->
handle_pfcp_session_deletion_request
(
m
,
sx_resp
);
...
...
src/spgwu/spgwu_app.hpp
View file @
9aa6f728
...
...
@@ -31,6 +31,7 @@
#include "common_root_types.h"
#include "itti_msg_sxab.hpp"
#include "itti_msg_s1u.hpp"
#include <boost/atomic.hpp>
...
...
@@ -48,52 +49,7 @@ private:
std
::
thread
::
id
thread_id
;
std
::
thread
thread
;
// teid generators (linear)
// boost::atomic<teid_t> teid_sxab_cp;
// boost::atomic<teid_t> teid_s5s8_up;
// /* There shall be only one pair of TEID-C per UE over the S11 and the S4 interfaces. The same tunnel shall be
// shared for the control messages related to the same UE operation. A TEID-C on the S11/S4 interface shall be
// released after all its associated EPS bearers are deleted.*/
// std::map<imsi64_t, std::shared_ptr<sgwu_eps_bearer_context>> imsi2sgwu_eps_bearer_context;
// std::map<teid_t, std::shared_ptr<sgwu_eps_bearer_context>> s11lteid2sgwu_eps_bearer_context;
//
// std::map<teid_t, std::pair<std::shared_ptr<sgwu_eps_bearer_context>, std::shared_ptr<sgwu_pdn_connection>>> s5s8lteid2sgwu_contexts;
// std::set<teid_t> s5s8uplteid; // In case of overflow of generator of teid_t
//
// teid_t generate_s11_cp_teid();
// bool is_s11c_teid_exist(const teid_t& teid_s11_cp) const;
//
// bool is_s5s8sgwu_teid_2_sgwu_contexts(const teid_t& sgwu_teid) const;
//
// // s11lteid2sgwu_eps_bearer_context collection
// bool is_s11sgwu_teid_2_sgwu_eps_bearer_context(const teid_t& sgwu_teid) const;
//
// bool is_imsi64_2_sgwu_eps_bearer_context(const imsi64_t& imsi64) const;
// void set_imsi64_2_sgwu_eps_bearer_context(const imsi64_t& imsi64, std::shared_ptr<sgwu_eps_bearer_context> sebc);
//
// teid_t generate_s5s8_cp_teid();
// bool is_s5s8c_teid_exist(const teid_t& teid_s5s8_cp)const;
//
// bool is_s5s8u_teid_exist(const teid_t& teid_s5s8_up) const;
public:
// key is S11 S-GW local teid, value is S11 tunnel id pair
// map<teid_t, int> s11teid2mme_hashtable;
// key is paa, value is S11 s-gw local teid
//obj_hash_table_uint64_t *ip2s11teid;
// key is S1-U S-GW local teid
////hash_table_t *s1uteid2enb_hashtable;
// the key of this hashtable is the S11 s-gw local teid.
//hash_table_ts_t *s11_bearer_context_information_hashtable;
/* The TEID-C shall be unique per PDN-Connection on GTP based S2a, S2b, S5 and S8 interfaces. The same
tunnel shall be shared for the control messages related to all bearers associated to
the PDN-Connection. A TEID-C on the S2a/S2b/S5/S8 interface shall be released after all its associated EPS bearers are deleted. */
//gtpv1u_data_t gtpv1u_data;
explicit
spgwu_app
(
const
std
::
string
&
config_file
);
~
spgwu_app
();
...
...
@@ -102,6 +58,7 @@ public:
teid_t
generate_s5s8_up_teid
();
void
handle_itti_msg
(
std
::
shared_ptr
<
oai
::
cn
::
core
::
itti
::
itti_s1u_echo_request
>
m
);
// void handle_itti_msg core::(itti::itti_sxab_heartbeat_request& m);
...
...
@@ -117,9 +74,9 @@ public:
// void handle_itti_msg (core::itti::itti_sxab_pfcp_version_not_supported_response& m);
// void handle_itti_msg (core::itti::itti_sxab_pfcp_node_report_request& m);
// void handle_itti_msg (core::itti::itti_sxab_pfcp_node_report_response& m);
void
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_establishment_request
>
m
);
void
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_modification_request
>
m
);
void
handle_itti_msg
(
std
::
shared_ptr
<
core
::
itti
::
itti_sxab_session_deletion_request
>
m
);
void
handle_itti_msg
(
std
::
shared_ptr
<
oai
::
cn
::
core
::
itti
::
itti_sxab_session_establishment_request
>
m
);
void
handle_itti_msg
(
std
::
shared_ptr
<
oai
::
cn
::
core
::
itti
::
itti_sxab_session_modification_request
>
m
);
void
handle_itti_msg
(
std
::
shared_ptr
<
oai
::
cn
::
core
::
itti
::
itti_sxab_session_deletion_request
>
m
);
// void handle_itti_msg (core::itti::itti_sxab_session_deletion_response& m);
// void handle_itti_msg (core::itti::itti_sxab_session_report_request& m);
// void handle_itti_msg (core::itti::itti_sxab_session_report_response& m);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment