Skip to content

Commit

Permalink
add NAT to the TDF function
Browse files Browse the repository at this point in the history
  • Loading branch information
RoadRunnr committed May 31, 2021
1 parent 9fdbf75 commit a33184c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 5 deletions.
15 changes: 12 additions & 3 deletions apps/ergw_core/src/tdf.erl
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,12 @@ start_session(#data{apn = APN, context = Context, dp_node = Node,
SOpts = #{now => Now},

SessionOpts0 = init_session(Data),
{_, AuthSEvs} =
{SessionOpts1, AuthSEvs} =
case authenticate(Session, SessionOpts0) of
{ok, Result2} -> Result2;
{error, Err2} -> throw({fail, Err2})
end,
Bearer2 = apply_bearer_opts(SessionOpts1, Bearer1),

%% -----------------------------------------------------------
%% TBD: maybe reselect VRF based on outcome of authenticate ??
Expand Down Expand Up @@ -437,12 +438,12 @@ start_session(#data{apn = APN, context = Context, dp_node = Node,
PCC4 = ergw_pcc_context:session_events_to_pcc_ctx(RfSEvs, PCC3),

{PCtx, Bearer, SessionInfo} =
case ergw_pfcp_context:create_session(tdf, PCC4, PendingPCtx, Bearer1, Context) of
case ergw_pfcp_context:create_session(tdf, PCC4, PendingPCtx, Bearer2, Context) of
{ok, Result5} -> Result5;
{error, Err5} -> throw({fail, Err5})
end,

SessionOpts = maps:merge(SessionOpts0, SessionInfo),
SessionOpts = maps:merge(SessionOpts1, SessionInfo),
ergw_aaa_session:invoke(Session, SessionOpts, start, SOpts#{async => true}),

Keys = context2keys(Bearer, Context),
Expand Down Expand Up @@ -486,6 +487,14 @@ init_session(#data{context = #tdf_ctx{ms_ip = UeIP}}) ->
Opts1
end.

apply_bearer_opts('NAT-Pool-Id', Id, #{right := #bearer{local = Local} = Right} = Bearer)
when is_record(Local, ue_ip) ->
Bearer#{right => Right#bearer{local = Local#ue_ip{nat = Id}}};
apply_bearer_opts(_, _, Bearer) ->
Bearer.

apply_bearer_opts(SOpts, Bearer) ->
maps:fold(fun apply_bearer_opts/3, Bearer, SOpts).

authenticate(Session, SessionOpts) ->
?LOG(debug, "SessionOpts: ~p", [SessionOpts]),
Expand Down
64 changes: 62 additions & 2 deletions apps/ergw_core/test/tdf_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,14 @@ common() ->
tdf_app_id
].

only(ipv4) ->
[aa_nat_select];
only(_) ->
[].

groups() ->
[{ipv4, [], common()},
{ipv6, [], common()}].
[{ipv4, [], common() ++ only(ipv4)},
{ipv6, [], common() ++ only(ipv6)}].

all() ->
[{group, ipv4},
Expand Down Expand Up @@ -497,6 +502,11 @@ init_per_testcase(tdf_app_id, Config0) ->
Config = setup_per_testcase(Config0),
ergw_test_lib:load_aaa_answer_config([{{gx, 'CCR-Initial'}, 'Initial-Gx-TDF-App'}]),
Config;
init_per_testcase(aa_pool_select, Config) ->
ergw_test_sx_up:ue_ip_pools('tdf-u', [<<"pool-A">>, <<"pool-C">>,
<<"pool-D">>, <<"pool-B">>]),
setup_per_testcase(Config),
Config;
init_per_testcase(_, Config) ->
setup_per_testcase(Config).

Expand All @@ -513,6 +523,11 @@ end_per_testcase(TestCase, Config)
ok = meck:delete(ergw_aaa_session, invoke, 4),
end_per_testcase(Config),
Config;
end_per_testcase(aa_nat_select, Config) ->
ergw_test_sx_up:nat_port_blocks('tdf-u', []),
ok = meck:delete(ergw_aaa_session, invoke, 4),
end_per_testcase(Config),
Config;
end_per_testcase(_, Config) ->
end_per_testcase(Config),
Config.
Expand Down Expand Up @@ -1838,6 +1853,51 @@ tdf_app_id(Config) ->
meck_validate(Config),
ok.

%%--------------------------------------------------------------------
aa_nat_select() ->
[{doc, "Select IP-NAT through AAA"}].
aa_nat_select(Config) ->
AAAReply = #{'NAT-Pool-Id' => <<"nat-B">>},

ok = meck:expect(ergw_aaa_session, invoke,
fun (Session, SessionOpts, Procedure = authenticate, Opts) ->
{_, SIn, EvIn} =
meck:passthrough([Session, SessionOpts, Procedure, Opts]),
{SOut, EvOut} =
ergw_aaa_radius:to_session(authenticate, {SIn, EvIn}, AAAReply),
{ok, SOut, EvOut};
(Session, SessionOpts, Procedure, Opts) ->
meck:passthrough([Session, SessionOpts, Procedure, Opts])
end),

UeIP = ergw_inet:ip2bin(proplists:get_value(ue_ip, Config)),

packet_in(Config),
ct:sleep(100),

{tdf, Server} = gtp_context_reg:lookup({ue, <<3, "sgi">>, UeIP}),
true = is_pid(Server),

ct:sleep(100),
stop_session(Server),
ct:sleep(100),

H = meck:history(ergw_aaa_session),
[SInv|_] =
lists:foldr(
fun({_, {ergw_aaa_session, invoke, [_, _, start, _]}, {ok, Opts}}, Acc) ->
[Opts|Acc];
(_, Acc) ->
Acc
end, [], H),
?match(#{'NAT-Pool-Id' := _,
'NAT-IP-Address' := _,
'NAT-Port-Start' := _}, SInv),

ok = meck:wait(?HUT, terminate, '_', ?TIMEOUT),
meck_validate(Config),
ok.

%%%===================================================================
%%% Helper
%%%===================================================================
Expand Down

0 comments on commit a33184c

Please sign in to comment.