pespin has uploaded this change for review.
WIP: EPDGTunnel
Change-Id: I6f00b7fce2d5fcdc484bfd45629b9141f16bc579
---
M config/sys.config
M rebar.config
M rebar.lock
A src/epdg_gtpc_s2b.erl
M src/gsup_server.erl
M src/osmo_epdg.app.src
M src/osmo_epdg_sup.erl
7 files changed, 207 insertions(+), 8 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/04/34804/1
diff --git a/config/sys.config b/config/sys.config
index 8d751b9..1b89e86 100755
--- a/config/sys.config
+++ b/config/sys.config
@@ -13,7 +13,13 @@
{vendor_id, 0},
{origin_host, "epdg.localdomain"},
{origin_realm, "localdomain"},
- {context_id, "epdg@localdomain"}]},
+ {context_id, "epdg@localdomain"},
+ % GTPv2C Connection parameters
+ {gtpc_local_ip, "127.0.0.2"},
+ {gtpc_local_port, 2123},
+ {gtpc_remote_ip, "127.0.0.1"},
+ {gtpc_remote_port, 2123}
+ ]},
%% ===========================================
%% SASL config
%% ===========================================
diff --git a/rebar.config b/rebar.config
index 03e0e7c..83923b8 100644
--- a/rebar.config
+++ b/rebar.config
@@ -4,8 +4,9 @@
{deps, [
{lager, {git, "https://github.com/erlang-lager/lager", {tag, "3.9.2"}}},
+ {gtplib, "3.2.0"},
{osmo_ss7, {git, "https://gitea.osmocom.org/erlang/osmo_ss7", {ref, "9f294d3612f998860004820d1d85b4264721577b"}}},
- {osmo_gsup, {git, "https://gitea.osmocom.org/erlang/osmo_gsup", {ref, "07672d8ab1608aa9c9e50ca035521876558fcd42"}}}
+ {osmo_gsup, {git, "https://gitea.osmocom.org/erlang/osmo_gsup", {ref, "e23f118e6e8f7ee1247db34e4cb79e4cecdb0947"}}}
]}.
{minimum_otp_vsn, "20.3"}.
diff --git a/rebar.lock b/rebar.lock
index 4aeafea..8f00ea6 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -1,16 +1,18 @@
{"1.2.0",
-[{<<"epcap">>,
+[{<<"cut">>,{pkg,<<"cut">>,<<"1.0.3">>},1},
+ {<<"epcap">>,
{git,"https://github.com/msantos/epcap",
{ref,"d5c03caf608c1369e68cfed0a606d3eb82ddfd21"}},
1},
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
+ {<<"gtplib">>,{pkg,<<"gtplib">>,<<"3.2.0">>},0},
{<<"lager">>,
{git,"https://github.com/erlang-lager/lager",
{ref,"459a3b2cdd9eadd29e5a7ce5c43932f5ccd6eb88"}},
0},
{<<"osmo_gsup">>,
{git,"https://gitea.osmocom.org/erlang/osmo_gsup",
- {ref,"07672d8ab1608aa9c9e50ca035521876558fcd42"}},
+ {ref,"e23f118e6e8f7ee1247db34e4cb79e4cecdb0947"}},
0},
{<<"osmo_ss7">>,
{git,"https://gitea.osmocom.org/erlang/osmo_ss7",
@@ -23,10 +25,17 @@
{<<"pkt">>,
{git,"https://github.com/msantos/pkt",
{ref,"67a4a14f596fded5ad5f2d8f94318faa8ad2c288"}},
- 1}]}.
+ 1},
+ {<<"ppplib">>,{pkg,<<"ppplib">>,<<"1.0.0">>},1}]}.
[
{pkg_hash,[
- {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>}]},
+ {<<"cut">>, <<"1577F2F3BC0F2BF3B97903B7426F8A3D79523687B6A444D0F59A095EF69A0E81">>},
+ {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
+ {<<"gtplib">>, <<"41E8E14BE21DD6E08B2CBB9D708BCF8FDD47CA49D7FFA480219CAB29F5AE2760">>},
+ {<<"ppplib">>, <<"F9EC2690532BAF590277A305A2276FCFAD0285557E1055552F8A2FCAF1BF081A">>}]},
{pkg_hash_ext,[
- {<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>}]}
+ {<<"cut">>, <<"1A4A25DB2B7C5565FD28B314A4EEB898B1ED3CAFFA1AB09149345FB5731ED04B">>},
+ {<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>},
+ {<<"gtplib">>, <<"264626E6993C17B00CA3C083B9BF23D16B88BEEDDDE35F62C954832C21B57AEF">>},
+ {<<"ppplib">>, <<"32440D630F55DD29F849847DD8F15F69175FDDC210AA88517AC8AD2854CD6FA1">>}]}
].
diff --git a/src/epdg_gtpc_s2b.erl b/src/epdg_gtpc_s2b.erl
new file mode 100644
index 0000000..d2238a0
--- /dev/null
+++ b/src/epdg_gtpc_s2b.erl
@@ -0,0 +1,159 @@
+% S2b: GTPv2C towards PGW
+%
+% TS 29.273
+%
+% (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+% Author: Pau Espin Pedrol <pespin@sysmocom.de>
+%
+% All Rights Reserved
+%
+% This program is free software; you can redistribute it and/or modify
+% it under the terms of the GNU Affero General Public License as
+% published by the Free Software Foundation; either version 3 of the
+% License, or (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU Affero General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% Additional Permission under GNU AGPL version 3 section 7:
+%
+% If you modify this Program, or any covered work, by linking or
+% combining it with runtime libraries of Erlang/OTP as released by
+% Ericsson on http://www.erlang.org (or a modified version of these
+% libraries), containing parts covered by the terms of the Erlang Public
+% License (http://www.erlang.org/EPLICENSE), the licensors of this
+% Program grant you additional permission to convey the resulting work
+% without the need to license the runtime libraries of Erlang/OTP under
+% the GNU Affero General Public License. Corresponding Source for a
+% non-source form of such a combination shall include the source code
+% for the parts of the runtime libraries of Erlang/OTP used as well as
+% that of the covered work.
+
+
+-module(epdg_gtpc_s2b).
+-author('Pau Espin Pedrol <pespin@sysmocom.de>').
+
+-behaviour(gen_server).
+
+-include_lib("diameter_3gpp_ts29_273_swx.hrl").
+-include_lib("diameter/include/diameter_gen_base_rfc6733.hrl").
+
+%% API Function Exports
+-export([start_link/5]).
+-export([terminate/2]).
+%% gen_server Function Exports
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
+-export([code_change/3]).
+%%-export([multimedia_auth_request/6]).
+
+%% Application Definitions
+-define(SERVER, ?MODULE).
+-define(SVC_NAME, ?MODULE).
+-define(APP_ALIAS, ?MODULE).
+-define(CALLBACK_MOD, epdg_gtpc_s2b_cb).
+-define(ENV_APP_NAME, osmo_epdg).
+
+%% The service configuration. As in the server example, a client
+%% supporting multiple Diameter applications may or may not want to
+%% configure a common callback module on all applications.
+-define(SERVICE,
+ [{'Origin-Host', application:get_env(?ENV_APP_NAME, origin_host, ?ENV_DEFAULT_ORIG_HOST)},
+ {'Origin-Realm', application:get_env(?ENV_APP_NAME, origin_realm, ?ENV_DEFAULT_ORIG_REALM)},
+ {'Vendor-Id', application:get_env(?ENV_APP_NAME, vendor_id, ?ENV_DEFAULT_VENDOR_ID)},
+ {'Vendor-Specific-Application-Id',
+ [#'diameter_base_Vendor-Specific-Application-Id'{
+ 'Vendor-Id' = ?VENDOR_ID_3GPP,
+ 'Auth-Application-Id' = [?DIAMETER_APP_ID_SWX]}]},
+ {'Product-Name', "osmo-epdg"},
+ % TODO: check which we should annouce here as Supported-Vendor-Id
+ {'Supported-Vendor-Id', [?VENDOR_ID_3GPP, ?VENDOR_ID_ETSI, ?VENDOR_ID_3GPP2]},
+ { application,
+ [{alias, ?APP_ALIAS},
+ {dictionary, ?DIAMETER_DICT_SWX},
+ {module, ?CALLBACK_MOD},
+ {answer_errors, callback}]}]).
+
+-record(state, {
+ handlers,
+ peers = #{}
+}).
+
+start_link(LocalAddr, LocalPort, RemoteAddr, RemotePort, Options) ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [LocalAddr, LocalPort, RemoteAddr, RemotePort, Options], []).
+
+peer_down(API, SvcName, {PeerRef, _} = Peer) ->
+ % fixme: why do we still have ets here?
+ (catch ets:delete(?MODULE, {API, PeerRef})),
+ gen_server:cast(?SERVER, {peer_down, SvcName, Peer}),
+ ok.
+
+init(State) ->
+ lager:info("epdg_gtpc_s2b: init(): ~p", [State]),
+ [_ | [_ | [RemoteAddr | [RemotePort | _]]]] = State,
+ %Proto = application:get_env(?ENV_APP_NAME, diameter_proto, ?ENV_DEFAULT_DIAMETER_PROTO),
+ %Ip = application:get_env(?ENV_APP_NAME, diameter_remote_ip, ?ENV_DEFAULT_DIAMETER_REMOTE_IP),
+ %Port = application:get_env(?ENV_APP_NAME, diameter_remote_port, ?ENV_DEFAULT_DIAMETER_REMOTE_PORT),
+ %ok = diameter:start_service(?MODULE, ?SERVICE),
+ % lager:info("DiaServices is ~p~n", [DiaServ]),
+ {ok, _} = connect({address, RemoteAddr, RemotePort}),
+ {ok, State}.
+
+
+%% multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey) ->
+%% gen_server:call(?SERVER,
+%% {mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}).
+
+handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey}}, _From, State) ->
+ lager:error("Error: not implemented!~n", []),
+ {reply, {error, 'not-implemented'}, State}.
+
+%% @callback gen_server
+handle_cast(stop, State) ->
+ {stop, normal, State};
+handle_cast(_Req, State) ->
+ {noreply, State}.
+
+%% @callback gen_server
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%% @callback gen_server
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%% @callback gen_server
+terminate(normal, _State) ->
+ diameter:stop_service(?SVC_NAME),
+ ok;
+terminate(shutdown, _State) ->
+ ok;
+terminate({shutdown, _Reason}, _State) ->
+ ok;
+terminate(_Reason, _State) ->
+ ok.
+
+%% ------------------------------------------------------------------
+%% Internal Function Definitions
+%% ------------------------------------------------------------------
+
+%% connect/2
+connect(Name, {address, IPAddr, Port}) ->
+ lager:notice("~s connecting to IP ~s port ~p~n", [Name, IPAddr, Port]),
+ {ok, IP} = inet_parse:address(IPAddr),
+ TransportOpts =
+ [{transport_module, udp},
+ {transport_config,
+ [{reuseaddr, true},
+ {raddr, IP},
+ {rport, Port}]}],
+ diameter:add_transport(Name, {connect, [{reconnect_timer, 1000} | TransportOpts]}).
+
+connect(Address) ->
+ connect(?SVC_NAME, Address).
+
+
diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index 923d020..9bd4552 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -177,6 +177,7 @@
% epdg tunnel request / trigger the establishment to the PGW and prepares everything for the user traffic to flow
% When sending a epdg_tunnel_response everything must be ready for the UE traffic
handle_info({ipa, Socket, ?IPAC_PROTO_EXT_GSUP, GsupMsgRx = #{message_type := epdg_tunnel_request, imsi := Imsi}}, S) ->
+ lager:info("Rx EPDG Tunnel Req IMSI ~p ~n", [Imsi]),
{noreply, S};
handle_info(Info, S) ->
diff --git a/src/osmo_epdg.app.src b/src/osmo_epdg.app.src
index 483d339..ec60bd2 100644
--- a/src/osmo_epdg.app.src
+++ b/src/osmo_epdg.app.src
@@ -8,6 +8,7 @@
kernel,
stdlib,
lager,
+ gtplib,
diameter,
osmo_gsup,
osmo_ss7
diff --git a/src/osmo_epdg_sup.erl b/src/osmo_epdg_sup.erl
index 457d993..c679b39 100644
--- a/src/osmo_epdg_sup.erl
+++ b/src/osmo_epdg_sup.erl
@@ -8,6 +8,10 @@
-define(ENV_APP_NAME, osmo_epdg).
-define(ENV_DEFAULT_GSUP_LOCAL_IP, "0.0.0.0").
-define(ENV_DEFAULT_GSUP_LOCAL_PORT, 4222).
+-define(ENV_DEFAULT_GTPC_LOCAL_IP, "127.0.0.2").
+-define(ENV_DEFAULT_GTPC_LOCAL_PORT, 2123).
+-define(ENV_DEFAULT_GTPC_REMOTE_IP, "127.0.0.1").
+-define(ENV_DEFAULT_GTPC_REMOTE_PORT, 2123).
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
@@ -15,11 +19,20 @@
init([]) ->
GsupLocalIp = application:get_env(?ENV_APP_NAME, gsup_local_ip, ?ENV_DEFAULT_GSUP_LOCAL_IP),
GsupLocalPort = application:get_env(?ENV_APP_NAME, gsup_local_port, ?ENV_DEFAULT_GSUP_LOCAL_PORT),
+ GtpcLocalIp = application:get_env(?ENV_APP_NAME, gtpc_local_ip, ?ENV_DEFAULT_GTPC_LOCAL_IP),
+ GtpcLocalPort = application:get_env(?ENV_APP_NAME, gtpc_local_port, ?ENV_DEFAULT_GTPC_LOCAL_PORT),
+ GtpcRemoteIp = application:get_env(?ENV_APP_NAME, gtpc_remote_ip, ?ENV_DEFAULT_GTPC_REMOTE_IP),
+ GtpcRemotePort = application:get_env(?ENV_APP_NAME, gtpc_remote_port, ?ENV_DEFAULT_GTPC_REMOTE_PORT),
DiaServer = {epdg_diameter_swx, {epdg_diameter_swx,start_link,[]},
permanent,
5000,
worker,
[epdg_diameter_swx_cb]},
+ GtpcServer = {epdg_gtpc_s2b, {epdg_gtpc_s2b,start_link, [GtpcLocalIp, GtpcLocalPort, GtpcRemoteIp, GtpcRemotePort, []]},
+ permanent,
+ 5000,
+ worker,
+ [epdg_gtpc_s2b]},
GsupServer = {gsup_server, {gsup_server, start_link, [GsupLocalIp, GsupLocalPort, []]},
permanent,
5000,
@@ -30,4 +43,4 @@
5000,
worker,
[auth_handler]},
- {ok, { {one_for_all, 5, 10}, [DiaServer, GsupServer, AuthHandler]} }.
+ {ok, { {one_for_all, 5, 10}, [DiaServer, GtpcServer, GsupServer, AuthHandler]} }.
To view, visit change 34804. To unsubscribe, or for help writing mail filters, visit settings.