fixeria has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42486?usp=email )


Change subject: pfcp_peer: make assoc_setup and heartbeat_req timeouts 
configurable
......................................................................

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(-)



  git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw 
refs/changes/86/42486/1

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 https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42486?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-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I58a472a3bbbbad029a2f0246b084428ab3b1905c
Gerrit-Change-Number: 42486
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <[email protected]>

Reply via email to