clufn has uploaded this change for review. (
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/40277?usp=email )
Change subject: Enable the use of an UE requested IP type and address to be used for gtpv2
PDN Address Allocation
......................................................................
Enable the use of an UE requested IP type and address to be used for gtpv2 PDN Address
Allocation
Change-Id: If0c77b1e366df36439d3a1b72030d831dd1b3a05
---
M src/conv.erl
M src/epdg_gtpc_s2b.erl
M src/epdg_ue_fsm.erl
M src/gsup_server.erl
4 files changed, 43 insertions(+), 22 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/77/40277/1
diff --git a/src/conv.erl b/src/conv.erl
index 5832c64..d2a54ab 100644
--- a/src/conv.erl
+++ b/src/conv.erl
@@ -41,7 +41,7 @@
-export([ip_to_bin/1, bin_to_ip/1]).
-export([cause_gtp2gsup/1]).
-export([dia_rc_success/1, dia_rc_to_gsup_cause/1]).
--export([gtp2_paa_to_epdg_eua/1, epdg_eua_to_gsup_pdp_address/1]).
+-export([gtp2_paa_to_epdg_eua/1, pdp_address_to_gtp2_paa/2,
epdg_eua_to_gsup_pdp_address/1]).
-export([nai_to_imsi/1]).
% ergw_aaa/src/ergw_aaa_3gpp_dict.erl
@@ -62,6 +62,9 @@
bin_to_ip({_, _, _, _, _, _, _, _} = IP) ->
IP.
+%% Add "IPv6 Prefix Length" to PAA (3GPP TS 29.274 Table 8.14).
+add_v6_prefix_len_byte(<< IPv6:16/binary >>) -> << 8, IPv6/binary
>>.
+
%% Remove "IPv6 Prefix Length" from PAA (3GPP TS 29.274 Table 8.14).
remove_v6_prefix_len_byte(<<_:8, Rest/binary>>) -> Rest.
@@ -129,6 +132,13 @@
ipv4 = get_4_from_v4v6(Addr),
ipv6 = get_6_from_v4v6(Addr)}.
+pdp_address_to_gtp2_paa(?GTP_PDP_ADDR_TYPE_NR_IPv4, Address) ->
+ #v2_pdn_address_allocation{type = ipv4, address = maps:get(ipv4,Address)};
+pdp_address_to_gtp2_paa(?GTP_PDP_ADDR_TYPE_NR_IPv6, Address) ->
+ #v2_pdn_address_allocation{type = ipv6, address =
add_v6_prefix_len_byte(maps:get(ipv6,Address))};
+pdp_address_to_gtp2_paa(?GTP_PDP_ADDR_TYPE_NR_IPv4v6, Address) ->
+ #v2_pdn_address_allocation{type = ipv4v6, address =
get_v4v6(maps:get(ipv4,Address),maps:get(ipv6,Address))}.
+
epdg_eua_to_gsup_pdp_address(#epdg_eua{type_nr = ?GTP_PDP_ADDR_TYPE_NR_IPv4, ipv4 =
Addr}) ->
#{pdp_type_org => 1,
pdp_type_nr => ?GTP_PDP_ADDR_TYPE_NR_IPv4,
diff --git a/src/epdg_gtpc_s2b.erl b/src/epdg_gtpc_s2b.erl
index 4b88be3..d4d2b71 100644
--- a/src/epdg_gtpc_s2b.erl
+++ b/src/epdg_gtpc_s2b.erl
@@ -48,7 +48,7 @@
%% gen_server Function Exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
-export([code_change/3]).
--export([create_session_req/4, delete_session_req/1]).
+-export([create_session_req/5, delete_session_req/1]).
%% Application Definitions
-define(SERVER, ?MODULE).
@@ -144,13 +144,13 @@
lager:error("GTPv2C UDP socket open error: ~w~n", [Reason])
end.
-create_session_req(Imsi, Apn, APCO, PGWAddrCandidateList) ->
- gen_server:call(?SERVER, {gtpc_create_session_req, {Imsi, Apn, APCO,
PGWAddrCandidateList}}).
+create_session_req(Imsi, Apn, APCO, Paa, PGWAddrCandidateList) ->
+ gen_server:call(?SERVER, {gtpc_create_session_req, {Imsi, Apn, APCO, Paa,
PGWAddrCandidateList}}).
delete_session_req(Imsi) ->
gen_server:call(?SERVER, {gtpc_delete_session_req, {Imsi}}).
-handle_call({gtpc_create_session_req, {Imsi, Apn, APCO, PGWAddrCandidateList}}, {Pid,
_Tag} = _From, State0) ->
+handle_call({gtpc_create_session_req, {Imsi, Apn, APCO, Paa, PGWAddrCandidateList}},
{Pid, _Tag} = _From, State0) ->
RemoteAddrStr = pick_gtpc_remote_address(PGWAddrCandidateList, State0),
lager:debug("Selected PGW Remote Address ~p~n", [RemoteAddrStr]),
{ok, RemoteAddrInet} = inet_parse:address(RemoteAddrStr),
@@ -160,7 +160,7 @@
raddr_str = RemoteAddrInet,
raddr = RemoteAddrInet},
State0),
- Req = gen_create_session_request(Sess0, APCO, State1),
+ Req = gen_create_session_request(Sess0, APCO, Paa, State1),
tx_gtp(Req, State1),
State2 = inc_seq_no(State1),
lager:debug("Waiting for CreateSessionResponse~n", []),
@@ -514,6 +514,7 @@
apn = Apn,
local_control_tei = LocalCtlTEI} = Sess,
APCO,
+ Paa,
#gtp_state{laddr = LocalAddr,
laddr_gtpu = LocalAddrGtpu,
restart_counter = RCnt,
@@ -548,7 +549,7 @@
},
#v2_access_point_name{instance = 0, apn = [Apn]},
#v2_selection_mode{mode = 0},
- #v2_pdn_address_allocation{type = ipv4, address = <<0,0,0,0>>},
+ Paa, %% v2_pdn_address_allocation
#v2_bearer_context{group = BearersIE},
#v2_recovery{restart_counter = RCnt},
#v2_additional_protocol_configuration_options{instance = 0, config =
APCO_decoded}
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index 2e4f417..220bc5e 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -66,6 +66,7 @@
-record(ue_fsm_data, {
imsi,
+ paa,
apn = "internet" :: string(),
pgw_rem_addr_list = [] :: list(),
tun_pdp_ctx :: #epdg_tun_pdp_ctx{},
@@ -96,10 +97,10 @@
{error, Err}
end.
-auth_request(Pid, {PdpTypeNr, Apn, EAP}) ->
+auth_request(Pid, {PdpTypeNr, PdpAddress, Apn, EAP}) ->
lager:info("ue_fsm auth_request~n", []),
try
- gen_statem:call(Pid, {auth_request, PdpTypeNr, Apn, EAP})
+ gen_statem:call(Pid, {auth_request, PdpTypeNr, PdpAddress, Apn, EAP})
catch
exit:Err ->
{error, Err}
@@ -227,7 +228,7 @@
%% Internal helpers
%% ------------------------------------------------------------------
-ev_handle({call, From}, {auth_request, PdpTypeNr, Apn, EAP}, Data) ->
+ev_handle({call, From}, {auth_request, PdpTypeNr, PdpAddress, Apn, EAP}, Data) ->
epdg_diameter_swm:tx_der_auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn,
EAP),
{next_state, state_wait_auth_resp, Data, [{reply,From,ok}]}.
@@ -258,9 +259,10 @@
state_new(enter, _OldState, Data) ->
{keep_state, Data};
-state_new({call, _From} = EvType, {auth_request, PdpTypeNr, Apn, EAP} = EvContent, Data)
->
- lager:info("ue_fsm state_new event=auth_request {~p, ~p, ~p}, ~p~n",
[PdpTypeNr, Apn, EAP, Data]),
- ev_handle(EvType, EvContent, Data);
+state_new({call, _From} = EvType, {auth_request, PdpTypeNr, PdpAddress, Apn, EAP} =
EvContent, Data) ->
+ lager:info("ue_fsm state_new event=auth_request {~p, ~p, ~p}, ~p~n",
[PdpTypeNr, PdpAddress, Apn, EAP, Data]),
+ Data1 = Data#ue_fsm_data{paa = conv:pdp_address_to_gtp2_paa(PdpTypeNr,
PdpAddress), apn = Apn},
+ ev_handle(EvType, EvContent, Data1);
state_new({call, From}, purge_ms_request, Data) ->
lager:info("ue_fsm state_new event=purge_ms_request, ~p~n", [Data]),
@@ -300,8 +302,8 @@
state_authenticating(enter, _OldState, Data) ->
{keep_state, Data};
-state_authenticating({call, _From} = EvType, {auth_request, PdpTypeNr, Apn, EAP} =
EvContent, Data) ->
- lager:info("ue_fsm state_authenticating event=auth_request {~p, ~p, ~p},
~p~n", [PdpTypeNr, Apn, EAP, Data]),
+state_authenticating({call, _From} = EvType, {auth_request, PdpTypeNr, PdpAddress, Apn,
EAP} = EvContent, Data) ->
+ lager:info("ue_fsm state_authenticating event=auth_request {~p, ~p, ~p},
~p~n", [PdpTypeNr, PdpAddress, Apn, EAP, Data]),
ev_handle(EvType, EvContent, Data);
state_authenticating({call, From}, lu_request, Data) ->
@@ -339,8 +341,8 @@
state_authenticated(enter, _OldState, Data) ->
{keep_state, Data};
-state_authenticated({call, _From}, {auth_request, PdpTypeNr, Apn, EAP}, Data) ->
- lager:info("ue_fsm state_authenticated event=auth_request {~p, ~p, ~p},
~p~n", [PdpTypeNr, Apn, EAP, Data]),
+state_authenticated({call, _From}, {auth_request, PdpTypeNr, PdpAddress, Apn, EAP}, Data)
->
+ lager:info("ue_fsm state_authenticated event=auth_request {~p, ~p, ~p},
~p~n", [PdpTypeNr, PdpAddress, Apn, EAP, Data]),
{next_state, state_new, Data, [postpone]};
state_authenticated({call, From}, {tunnel_request, PCO}, Data) ->
@@ -348,6 +350,7 @@
epdg_gtpc_s2b:create_session_req(Data#ue_fsm_data.imsi,
Data#ue_fsm_data.apn,
PCO,
+ Data#ue_fsm_data.paa,
Data#ue_fsm_data.pgw_rem_addr_list),
{next_state, state_wait_create_session_resp, Data, [{reply,From,ok}]};
@@ -437,8 +440,8 @@
state_active(enter, _OldState, Data) ->
{keep_state, Data};
-state_active({call, _From}, {auth_request, PdpTypeNr, Apn, EAP}, Data) ->
- lager:info("ue_fsm state_active event=auth_request {~p, ~p, ~p}, ~p~n",
[PdpTypeNr, Apn, EAP, Data]),
+state_active({call, _From}, {auth_request, PdpTypeNr, PdpAddress, Apn, EAP}, Data) ->
+ lager:info("ue_fsm state_active event=auth_request {~p, ~p, ~p}, ~p~n",
[PdpTypeNr, PdpAddress, Apn, EAP, Data]),
gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined},
{next_state, state_new, Data1, [postpone]};
diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index c5d3738..c4c28cf 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -296,13 +296,20 @@
case maps:find(pdp_info_list, GsupMsgRx) of
{ok, [PdpInfo]} ->
#{pdp_context_id := _PDPCtxId,
- pdp_address := #{address := #{},
+ pdp_address := #{address := PdpAddress,
pdp_type_nr := PdpTypeNr,
pdp_type_org := 241},
access_point_name := Apn
- } = PdpInfo;
+ } = PdpInfo,
+ case maps:is_key(ipv4,PdpAddress) or maps:is_key(ipv6,PdpAddress) of
+ true -> ok; %% Address received so do nothing
+ false -> %% No address received from strongswan, use a default
value
+ PdpTypeNr = ?GTP_PDP_ADDR_TYPE_NR_IPv4,
+ PdpAddress = #{ipv4 => <<0,0,0,0>>}
+ end;
error -> % Use some sane defaults:
PdpTypeNr = ?GTP_PDP_ADDR_TYPE_NR_IPv4,
+ PdpAddress = #{ipv4 => <<0,0,0,0>>},
Apn = "*"
end,
EAP = parse_eap(GsupMsgRx),
@@ -310,7 +317,7 @@
undefined -> {ok, Pid} = epdg_ue_fsm:start(Imsi);
Pid -> Pid
end,
- case epdg_ue_fsm:auth_request(Pid, {PdpTypeNr, Apn, EAP}) of
+ case epdg_ue_fsm:auth_request(Pid, {PdpTypeNr, PdpAddress, Apn, EAP}) of
ok -> ok;
{error, Err} ->
lager:error("Auth Req for Imsi ~p failed: ~p~n", [Imsi, Err]),
--
To view, visit
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/40277?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: If0c77b1e366df36439d3a1b72030d831dd1b3a05
Gerrit-Change-Number: 40277
Gerrit-PatchSet: 1
Gerrit-Owner: clufn <callumfarrbennett(a)yahoo.com>