fixeria submitted this change.
pfcp_peer: make assoc_setup and heartbeat_req timeouts configurable
Add assoc_setup_timeout and heartbeat_req_timeout as optional fields
in the pfcp_peer config map, with 2000 ms defaults. Store the full
cfg() map in #peer_state{} and read values from it with maps:get/3
at the point of use.
Change-Id: I58a472a3bbbbad029a2f0246b084428ab3b1905c
---
M config/sys.config
M contrib/openapi.yaml
M doc/manuals/chapters/configuration.adoc
M doc/manuals/chapters/rest.adoc
M include/osmo_s1gw.hrl
M priv/openapi.json
M src/osmo_s1gw_sup.erl
M src/pfcp_peer.erl
M src/rest_server.erl
9 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/config/sys.config b/config/sys.config
index af6480b..5bebbe6 100644
--- a/config/sys.config
+++ b/config/sys.config
@@ -32,6 +32,10 @@
laddr => "127.0.1.1",
%% remote address for outgoing PFCP PDUs to the UPF
raddr => "127.0.1.2"
+ %% optional: PFCP Association Setup timeout in milliseconds (default: 2000)
+ %% assoc_setup_timeout => 2000,
+ %% optional: PFCP Heartbeat Request timeout in milliseconds (default: 2000)
+ %% heartbeat_req_timeout => 2000
}}
%% Optional PFCP Network Instance IEs (omitted if not configured)
%% {pfcp_net_inst_core, "core-side"}, %% PFCP Network Instance IE value (to core)
diff --git a/contrib/openapi.yaml b/contrib/openapi.yaml
index 59de93f..8ca18aa 100644
--- a/contrib/openapi.yaml
+++ b/contrib/openapi.yaml
@@ -529,6 +529,12 @@
raddr:
type: string
description: Remote IP address of the UPF (PFCP peer)
+ assoc_setup_timeout:
+ type: integer
+ description: PFCP Association Setup response timeout in milliseconds
+ heartbeat_req_timeout:
+ type: integer
+ description: PFCP Heartbeat Request response timeout in milliseconds
GtpuKpiCfg:
type: object
diff --git a/doc/manuals/chapters/configuration.adoc b/doc/manuals/chapters/configuration.adoc
index a43c9ad..a361730 100644
--- a/doc/manuals/chapters/configuration.adoc
+++ b/doc/manuals/chapters/configuration.adoc
@@ -137,6 +137,8 @@
{pfcp_peer, #{
laddr => "127.0.1.1", %% local address for PFCP (UDP)
raddr => "127.0.1.2" %% remote address of the UPF
+ %% assoc_setup_timeout => 2000, %% optional, milliseconds
+ %% heartbeat_req_timeout => 2000 %% optional, milliseconds
}},
%% Optional Network Instance IEs:
@@ -151,6 +153,14 @@
`raddr`::
Remote IP address of the UPF. Default: `"127.0.1.2"`.
+`assoc_setup_timeout`::
+ How long (in milliseconds) to wait for a PFCP Association Setup Response
+ before retrying. Default: `2000`.
+
+`heartbeat_req_timeout`::
+ How long (in milliseconds) to wait for a PFCP Heartbeat Response before
+ declaring the heartbeat timed out. Default: `2000`.
+
NOTE: The legacy flat keys `pfcp_loc_addr` and `pfcp_rem_addr` are still
accepted for backwards compatibility. The `pfcp_peer` map takes priority
if both are present.
diff --git a/doc/manuals/chapters/rest.adoc b/doc/manuals/chapters/rest.adoc
index 92b4f7a..c3f53af 100644
--- a/doc/manuals/chapters/rest.adoc
+++ b/doc/manuals/chapters/rest.adoc
@@ -78,7 +78,9 @@
},
"pfcp": {
"laddr": "127.0.1.1",
- "raddr": "127.0.1.2"
+ "raddr": "127.0.1.2",
+ "assoc_setup_timeout": 2000,
+ "heartbeat_req_timeout": 2000
},
"gtpu_kpi": {
"enable": false,
@@ -107,6 +109,8 @@
`pfcp`::
`laddr`::: Local PFCP bind address.
`raddr`::: Remote UPF (PFCP peer) address.
+ `assoc_setup_timeout`::: PFCP Association Setup response timeout in milliseconds.
+ `heartbeat_req_timeout`::: PFCP Heartbeat Request response timeout in milliseconds.
`gtpu_kpi`::
`enable`::: Whether GTP-U KPI reporting via nftables counters is active.
diff --git a/include/osmo_s1gw.hrl b/include/osmo_s1gw.hrl
index 91bd2e6..692a6ff 100644
--- a/include/osmo_s1gw.hrl
+++ b/include/osmo_s1gw.hrl
@@ -41,6 +41,8 @@
-define(ENV_DEFAULT_MME_REM_PORT, 36412).
-define(ENV_DEFAULT_PFCP_LOC_ADDR, "127.0.1.1").
-define(ENV_DEFAULT_PFCP_REM_ADDR, "127.0.1.2").
+-define(ENV_DEFAULT_PFCP_ASSOC_SETUP_TIMEOUT, 2000).
+-define(ENV_DEFAULT_PFCP_HEARTBEAT_REQ_TIMEOUT, 2000).
-define(ENV_DEFAULT_GTPU_KPI_ENABLE, false).
-define(ENV_DEFAULT_GTPU_KPI_TABLE_NAME, "osmo-s1gw").
-define(ENV_DEFAULT_GTPU_KPI_INTERVAL, 3000).
diff --git a/priv/openapi.json b/priv/openapi.json
index cf2fb50..3153505 100644
--- a/priv/openapi.json
+++ b/priv/openapi.json
@@ -763,6 +763,14 @@
"raddr": {
"type": "string",
"description": "Remote IP address of the UPF (PFCP peer)"
+ },
+ "assoc_setup_timeout": {
+ "type": "integer",
+ "description": "PFCP Association Setup response timeout in milliseconds"
+ },
+ "heartbeat_req_timeout": {
+ "type": "integer",
+ "description": "PFCP Heartbeat Request response timeout in milliseconds"
}
}
},
diff --git a/src/osmo_s1gw_sup.erl b/src/osmo_s1gw_sup.erl
index 573f2cb..9809fff 100644
--- a/src/osmo_s1gw_sup.erl
+++ b/src/osmo_s1gw_sup.erl
@@ -159,7 +159,11 @@
%% parse the new pfcp configuration block (takes priority)
Cfg = maps:merge(OldCfg, osmo_s1gw:get_env(pfcp_peer, #{ })),
#{laddr => maps:get(laddr, Cfg, ?ENV_DEFAULT_PFCP_LOC_ADDR),
- raddr => maps:get(raddr, Cfg, ?ENV_DEFAULT_PFCP_REM_ADDR)}.
+ raddr => maps:get(raddr, Cfg, ?ENV_DEFAULT_PFCP_REM_ADDR),
+ assoc_setup_timeout => maps:get(assoc_setup_timeout, Cfg,
+ ?ENV_DEFAULT_PFCP_ASSOC_SETUP_TIMEOUT),
+ heartbeat_req_timeout => maps:get(heartbeat_req_timeout, Cfg,
+ ?ENV_DEFAULT_PFCP_HEARTBEAT_REQ_TIMEOUT)}.
-spec gtpu_kpi_cfg() -> gtpu_kpi:cfg().
diff --git a/src/pfcp_peer.erl b/src/pfcp_peer.erl
index 3423237..a6f4b03 100644
--- a/src/pfcp_peer.erl
+++ b/src/pfcp_peer.erl
@@ -55,14 +55,14 @@
-include_lib("kernel/include/logger.hrl").
-include_lib("pfcplib/include/pfcp_packet.hrl").
+
+-include("osmo_s1gw.hrl").
-include("s1gw_metrics.hrl").
%% 3GPP TS 29.244, section 4.2 "UDP Header and Port Numbers"
-define(PFCP_PORT, 8805).
-define(PFCP_SEQ_NR_MAX, 16#ffffff).
-define(PFCP_SEID_MAX, 16#ffffffffffffffff).
--define(PFCP_ASSOC_SETUP_TIMEOUT, 2000).
--define(PFCP_HEARTBEAT_REQ_TIMEOUT, 2000).
-type pfcp_session_rsp() :: ok | {error, term()}.
@@ -75,7 +75,9 @@
-type pfcp_pdu() :: #pfcp{}.
-type cfg() :: #{laddr := string() | inet:ip_address(),
- raddr := string() | inet:ip_address()}.
+ raddr := string() | inet:ip_address(),
+ assoc_setup_timeout => pos_integer(),
+ heartbeat_req_timeout => pos_integer()}.
-type peer_info() :: #{state := atom(),
laddr := inet:ip_address(),
@@ -98,7 +100,8 @@
tref :: reference()
}).
--record(peer_state, {seid :: pfcp_seid(),
+-record(peer_state, {cfg :: cfg(),
+ seid :: pfcp_seid(),
sock :: gen_udp:socket(),
loc_addr :: inet:ip_address(),
rem_addr :: inet:ip_address(),
@@ -189,7 +192,8 @@
{reuseaddr, true},
{active, true}]),
?LOG_INFO("PFCP peer @ ~p will talk to UPF @ ~p", [LocAddr, RemAddr]),
- {ok, connecting, #peer_state{seid = 1, %% SEID=0 is special, see 7.2.2.4.2
+ {ok, connecting, #peer_state{cfg = Cfg,
+ seid = 1, %% SEID=0 is special, see 7.2.2.4.2
sock = Sock,
loc_addr = LocAddr,
rem_addr = RemAddr,
@@ -204,12 +208,13 @@
%% CONNECTING state
connecting(enter, OldState,
- #peer_state{} = S0) ->
+ #peer_state{cfg = Cfg} = S0) ->
?LOG_INFO("State change: ~p -> ~p", [OldState, ?FUNCTION_NAME]),
s1gw_metrics:gauge_set(?S1GW_GAUGE_PFCP_ASSOCIATED, 0),
%% Tx PFCP Association Setup
{ok, S1} = send_assoc_setup(S0),
- {keep_state, S1, [{state_timeout, ?PFCP_ASSOC_SETUP_TIMEOUT, assoc_setup_timeout}]};
+ TVal = maps:get(assoc_setup_timeout, Cfg, ?ENV_DEFAULT_PFCP_ASSOC_SETUP_TIMEOUT),
+ {keep_state, S1, [{state_timeout, TVal, assoc_setup_timeout}]};
%% Handle Association Setup timeout
connecting(state_timeout, assoc_setup_timeout, S) ->
@@ -571,7 +576,8 @@
?LOG_ERROR("Another Heartbeat Request is still pending (SeqNr=~p)", [SeqNr]),
{{error, heartbeat_req_pending}, S};
-send_heartbeat_request(From, #peer_state{heartbeat = undefined,
+send_heartbeat_request(From, #peer_state{cfg = Cfg,
+ heartbeat = undefined,
seq_nr = SeqNr,
loc_rts = LRTS} = S0) ->
ReqIEs = #{recovery_time_stamp => #recovery_time_stamp{time = LRTS}},
@@ -579,8 +585,9 @@
case send_pdu({heartbeat_request, ReqIEs}, S0) of
{ok, S1} ->
s1gw_metrics:ctr_inc(?S1GW_CTR_PFCP_HEARTBEAT_REQ_TX),
- TRef = erlang:start_timer(?PFCP_HEARTBEAT_REQ_TIMEOUT, self(),
- heartbeat_request_watchdog),
+ TVal = maps:get(heartbeat_req_timeout, Cfg,
+ ?ENV_DEFAULT_PFCP_HEARTBEAT_REQ_TIMEOUT),
+ TRef = erlang:start_timer(TVal, self(), heartbeat_request_watchdog),
HB = #heartbeat_state{from = From,
seq_nr = SeqNr,
tref = TRef},
diff --git a/src/rest_server.erl b/src/rest_server.erl
index 24ca33b..7960ffa 100644
--- a/src/rest_server.erl
+++ b/src/rest_server.erl
@@ -281,7 +281,11 @@
config_pfcp() ->
Cfg = osmo_s1gw:get_env(pfcp_peer, #{}),
#{<<"laddr">> => bval(maps:get(laddr, Cfg, ?ENV_DEFAULT_PFCP_LOC_ADDR)),
- <<"raddr">> => bval(maps:get(raddr, Cfg, ?ENV_DEFAULT_PFCP_REM_ADDR))}.
+ <<"raddr">> => bval(maps:get(raddr, Cfg, ?ENV_DEFAULT_PFCP_REM_ADDR)),
+ <<"assoc_setup_timeout">> => maps:get(assoc_setup_timeout, Cfg,
+ ?ENV_DEFAULT_PFCP_ASSOC_SETUP_TIMEOUT),
+ <<"heartbeat_req_timeout">> => maps:get(heartbeat_req_timeout, Cfg,
+ ?ENV_DEFAULT_PFCP_HEARTBEAT_REQ_TIMEOUT)}.
-spec config_gtpu_kpi() -> map().
To view, visit change 42486. To unsubscribe, or for help writing mail filters, visit settings.