blob: 7c7e2211e29ee67346a1e4b5ad1081df14b93b21 [file] [log] [blame]
Alexander Couzens6a161492020-07-12 13:45:50 +02001/*! \file gprs_ns2.h */
2
3
4#pragma once
5
6#include <stdint.h>
7#include <netinet/in.h>
8
9#include <osmocom/core/prim.h>
Alexander Couzensb3b837c2020-10-27 15:12:25 +010010#include <osmocom/gprs/protocol/gsm_08_16.h>
Alexander Couzens841817e2020-11-19 00:41:29 +010011#include <osmocom/gprs/frame_relay.h>
Alexander Couzens6a161492020-07-12 13:45:50 +020012
13struct osmo_sockaddr;
Alexander Couzens1fac6f72020-10-01 19:08:38 +020014struct osmo_sockaddr_str;
Alexander Couzens841817e2020-11-19 00:41:29 +010015struct osmo_fr_network;
Alexander Couzens6a161492020-07-12 13:45:50 +020016
17struct gprs_ns2_inst;
18struct gprs_ns2_nse;
19struct gprs_ns2_vc;
20struct gprs_ns2_vc_bind;
21struct gprs_ns2_vc_driver;
22struct gprs_ns_ie_ip4_elem;
23struct gprs_ns_ie_ip6_elem;
24
25enum gprs_ns2_vc_mode {
Harald Weltefa2d66c2020-10-17 13:09:34 +020026 /*! The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK.
27 * This is what is needed for Frame Relay transport, and if you use a R97/R99 Gb
28 * interface over an IP transport (never standardized by 3GPP) */
Alexander Couzens138b96f2021-01-25 16:23:29 +010029 GPRS_NS2_VC_MODE_BLOCKRESET,
Harald Weltefa2d66c2020-10-17 13:09:34 +020030 /*! The VC will only use ALIVE/ACK (no RESET/BLOCK/UNBLOCK), which is for Gb-IP
31 * interface compliant to 3GPP Rel=4 or later. */
Alexander Couzens138b96f2021-01-25 16:23:29 +010032 GPRS_NS2_VC_MODE_ALIVE,
Alexander Couzens6a161492020-07-12 13:45:50 +020033};
34
Alexander Couzensd923cff2020-12-01 01:03:52 +010035enum gprs_ns2_dialect {
Alexander Couzens138b96f2021-01-25 16:23:29 +010036 GPRS_NS2_DIALECT_UNDEF,
37 GPRS_NS2_DIALECT_STATIC_ALIVE,
38 GPRS_NS2_DIALECT_STATIC_RESETBLOCK,
39 GPRS_NS2_DIALECT_IPACCESS,
40 GPRS_NS2_DIALECT_SNS,
Alexander Couzensd923cff2020-12-01 01:03:52 +010041};
42
Alexander Couzens24a14ac2020-11-19 02:34:49 +010043/*! Osmocom NS link layer types */
44enum gprs_ns2_ll {
Alexander Couzens412bc342020-11-19 05:24:37 +010045 GPRS_NS2_LL_UNDEF, /*!< undefined, used by vty */
Alexander Couzens24a14ac2020-11-19 02:34:49 +010046 GPRS_NS2_LL_UDP, /*!< NS/UDP/IP */
Alexander Couzens24a14ac2020-11-19 02:34:49 +010047 GPRS_NS2_LL_FR, /*!< NS/FR */
48 GPRS_NS2_LL_FR_GRE, /*!< NS/FR/GRE/IP */
49};
50
Harald Weltea3f73232021-01-31 15:57:22 +010051/*! Osmocom NS primitives according to 48.016 5.2 Service primitives */
Alexander Couzens6a161492020-07-12 13:45:50 +020052enum gprs_ns2_prim {
Alexander Couzens138b96f2021-01-25 16:23:29 +010053 GPRS_NS2_PRIM_UNIT_DATA,
54 GPRS_NS2_PRIM_CONGESTION,
55 GPRS_NS2_PRIM_STATUS,
Alexander Couzens6a161492020-07-12 13:45:50 +020056};
57
Alexander Couzens0ab028c2020-11-04 02:41:44 +010058extern const struct value_string gprs_ns2_prim_strs[];
Harald Weltea24e7ee2020-11-29 17:38:48 +010059extern const struct value_string gprs_ns2_lltype_strs[];
Alexander Couzens2498f1d2020-10-27 01:09:01 +010060
61/*! Obtain a human-readable string for NS primitives */
62static inline const char *gprs_ns2_prim_str(enum gprs_ns2_prim val)
Alexander Couzens0ab028c2020-11-04 02:41:44 +010063{ return get_value_string(gprs_ns2_prim_strs, val); }
Alexander Couzens2498f1d2020-10-27 01:09:01 +010064
Harald Weltea24e7ee2020-11-29 17:38:48 +010065/*! Obtain a human-readable string for NS link-layer type */
66static inline const char *gprs_ns2_lltype_str(enum gprs_ns2_ll val)
67{ return get_value_string(gprs_ns2_lltype_strs, val); }
68
Harald Weltea3f73232021-01-31 15:57:22 +010069/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitives */
Alexander Couzens6a161492020-07-12 13:45:50 +020070enum gprs_ns2_congestion_cause {
Alexander Couzens138b96f2021-01-25 16:23:29 +010071 GPRS_NS2_CONG_CAUSE_BACKWARD_BEGIN,
72 GPRS_NS2_CONG_CAUSE_BACKWARD_END,
73 GPRS_NS2_CONG_CAUSE_FORWARD_BEGIN,
74 GPRS_NS2_CONG_CAUSE_FORWARD_END,
Alexander Couzens6a161492020-07-12 13:45:50 +020075};
76
Harald Weltea3f73232021-01-31 15:57:22 +010077/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitives */
Alexander Couzens6a161492020-07-12 13:45:50 +020078enum gprs_ns2_affecting_cause {
Alexander Couzens138b96f2021-01-25 16:23:29 +010079 GPRS_NS2_AFF_CAUSE_VC_FAILURE,
80 GPRS_NS2_AFF_CAUSE_VC_RECOVERY,
81 GPRS_NS2_AFF_CAUSE_FAILURE,
82 GPRS_NS2_AFF_CAUSE_RECOVERY,
Alexander Couzens6a161492020-07-12 13:45:50 +020083 /* osmocom own causes */
Alexander Couzens138b96f2021-01-25 16:23:29 +010084 GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED,
85 GPRS_NS2_AFF_CAUSE_SNS_FAILURE,
86 GPRS_NS2_AFF_CAUSE_SNS_NO_ENDPOINTS,
Alexander Couzens4f1128f2021-01-20 17:42:48 +010087 GPRS_NS2_AFF_CAUSE_MTU_CHANGE,
Alexander Couzens6a161492020-07-12 13:45:50 +020088};
89
Alexander Couzens2498f1d2020-10-27 01:09:01 +010090extern const struct value_string gprs_ns2_aff_cause_prim_strs[];
91
Harald Weltea3f73232021-01-31 15:57:22 +010092/*! Obtain a human-readable string for NS affecting cause in primitives */
Alexander Couzens2498f1d2020-10-27 01:09:01 +010093static inline const char *gprs_ns2_aff_cause_prim_str(enum gprs_ns2_affecting_cause val)
94{ return get_value_string(gprs_ns2_aff_cause_prim_strs, val); }
95
Harald Weltea3f73232021-01-31 15:57:22 +010096/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitives */
Alexander Couzens6a161492020-07-12 13:45:50 +020097enum gprs_ns2_change_ip_endpoint {
Alexander Couzens138b96f2021-01-25 16:23:29 +010098 GRPS_NS2_ENDPOINT_NO_CHANGE,
99 GPRS_NS2_ENDPOINT_REQUEST_CHANGE,
100 GPRS_NS2_ENDPOINT_CONFIRM_CHANGE,
Alexander Couzens6a161492020-07-12 13:45:50 +0200101};
102
Alexander Couzensb3b837c2020-10-27 15:12:25 +0100103extern const struct value_string gprs_ns2_cause_strs[];
104
105/*! Obtain a human-readable string for NS primitives */
106static inline const char *gprs_ns2_cause_str(enum ns_cause val)
107{ return get_value_string(gprs_ns2_cause_strs, val); }
108
Alexander Couzens6a161492020-07-12 13:45:50 +0200109struct osmo_gprs_ns2_prim {
110 struct osmo_prim_hdr oph;
111
112 uint16_t nsei;
113 uint16_t bvci;
114
115 union {
116 struct {
117 enum gprs_ns2_change_ip_endpoint change;
Alexander Couzensfc3dd1f2020-11-19 00:41:47 +0100118 uint32_t link_selector;
Alexander Couzens6a161492020-07-12 13:45:50 +0200119 /* TODO: implement resource distribution
120 * add place holder for the link selector */
121 long long _resource_distribution_placeholder1;
122 long long _resource_distribution_placeholder2;
123 long long _resource_distribution_placeholder3;
124 } unitdata;
125 struct {
126 enum gprs_ns2_congestion_cause cause;
127 } congestion;
128 struct {
129 enum gprs_ns2_affecting_cause cause;
Daniel Willmann15c09a82020-11-03 23:05:43 +0100130 char *nsvc;
Alexander Couzens6a161492020-07-12 13:45:50 +0200131 /* 48.016 5.2.2.6 transfer capability */
132 int transfer;
Alexander Couzensda0a2852020-10-01 23:24:07 +0200133 /* osmocom specific */
134 /* Persistent NSE/NSVC are configured by vty */
135 bool persistent;
136 /* Only true on the first time it's available.
137 * Allow the BSSGP layer to reset persistent NSE */
138 bool first;
Alexander Couzens4f1128f2021-01-20 17:42:48 +0100139 /* MTU of a NS SDU. It's the lowest MTU of all (alive & dead) NSVCs */
140 uint16_t mtu;
Alexander Couzens6a161492020-07-12 13:45:50 +0200141 } status;
142 } u;
143};
144
145/* instance */
146struct gprs_ns2_inst *gprs_ns2_instantiate(void *ctx, osmo_prim_cb cb, void *cb_data);
147void gprs_ns2_free(struct gprs_ns2_inst *inst);
Alexander Couzens6a161492020-07-12 13:45:50 +0200148
149/* Entrypoint for primitives from the NS USER */
150int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);
151
Alexander Couzens6cb5d5f2020-10-11 23:23:31 +0200152/*! a callback to iterate over all NSVC */
153typedef int (*gprs_ns2_foreach_nsvc_cb)(struct gprs_ns2_vc *nsvc, void *ctx);
154
155int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse,
156 gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
Alexander Couzens6a161492020-07-12 13:45:50 +0200157struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
Alexander Couzensaac90162020-11-19 02:44:04 +0100158struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
Alexander Couzensd923cff2020-12-01 01:03:52 +0100159 enum gprs_ns2_ll linklayer,
160 enum gprs_ns2_dialect dialect);
Harald Welte5b034fb2021-03-04 14:16:49 +0100161struct gprs_ns2_nse *gprs_ns2_create_nse2(struct gprs_ns2_inst *nsi, uint16_t nsei,
162 enum gprs_ns2_ll linklayer,
163 enum gprs_ns2_dialect dialect, bool local_sgsn_role);
Alexander Couzens05e7f7d2020-10-11 19:51:46 +0200164uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
Alexander Couzens6a161492020-07-12 13:45:50 +0200165void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
Alexander Couzens4b6c8af2020-10-11 20:15:25 +0200166void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
Alexander Couzens6a161492020-07-12 13:45:50 +0200167
168/* create vc */
169void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
Alexander Couzens47558792020-12-06 03:16:11 +0100170void gprs_ns2_free_nsvcs(struct gprs_ns2_nse *nse);
Alexander Couzens6a161492020-07-12 13:45:50 +0200171struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);
172
Alexander Couzensaaa55a62020-12-03 06:02:03 +0100173/* generic VL driver */
174struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name(struct gprs_ns2_inst *nsi,
175 const char *name);
176
Alexander Couzens6a161492020-07-12 13:45:50 +0200177/* IP VL driver */
178int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
Alexander Couzensaaa55a62020-12-03 06:02:03 +0100179 const char *name,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700180 const struct osmo_sockaddr *local,
Alexander Couzens6a161492020-07-12 13:45:50 +0200181 int dscp,
182 struct gprs_ns2_vc_bind **result);
Alexander Couzens4f608452020-10-11 18:41:24 +0200183struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
184 const struct osmo_sockaddr *sockaddr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200185
Alexander Couzens841817e2020-11-19 00:41:29 +0100186/* FR VL driver */
187struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
188 struct gprs_ns2_inst *nsi,
189 const char *netif);
190const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind);
Alexander Couzensc782cec2020-12-10 04:10:25 +0100191enum osmo_fr_role gprs_ns2_fr_bind_role(struct gprs_ns2_vc_bind *bind);
Alexander Couzens841817e2020-11-19 00:41:29 +0100192int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
Alexander Couzensaaa55a62020-12-03 06:02:03 +0100193 const char *name,
Alexander Couzens841817e2020-11-19 00:41:29 +0100194 const char *netif,
195 struct osmo_fr_network *fr_network,
196 enum osmo_fr_role fr_role,
197 struct gprs_ns2_vc_bind **result);
198int gprs_ns2_is_fr_bind(struct gprs_ns2_vc_bind *bind);
199struct gprs_ns2_vc *gprs_ns2_fr_nsvc_by_dlci(struct gprs_ns2_vc_bind *bind, uint16_t dlci);
200struct gprs_ns2_vc *gprs_ns2_fr_connect(struct gprs_ns2_vc_bind *bind,
Alexander Couzensebcbd722020-12-03 06:11:39 +0100201 struct gprs_ns2_nse *nse,
202 uint16_t nsvci,
203 uint16_t dlci);
204struct gprs_ns2_vc *gprs_ns2_fr_connect2(struct gprs_ns2_vc_bind *bind,
Alexander Couzens841817e2020-11-19 00:41:29 +0100205 uint16_t nsei,
206 uint16_t nsvci,
207 uint16_t dlci);
208
Alexander Couzens6a161492020-07-12 13:45:50 +0200209/* create a VC connection */
210struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700211 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200212 struct gprs_ns2_nse *nse,
213 uint16_t nsvci);
214
215struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700216 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200217 uint16_t nsei,
Alexander Couzensd923cff2020-12-01 01:03:52 +0100218 uint16_t nsvci,
219 enum gprs_ns2_dialect dialect);
Alexander Couzens6a161492020-07-12 13:45:50 +0200220struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700221 const struct osmo_sockaddr *remote,
Alexander Couzens6a161492020-07-12 13:45:50 +0200222 struct gprs_ns2_nse *nse,
223 uint16_t nsvci);
Alexander Couzensc4704762021-02-08 23:13:12 +0100224void gprs_ns2_ip_bind_set_sns_weight(struct gprs_ns2_vc_bind *bind,
225 uint8_t signalling, uint8_t data);
Alexander Couzens6a161492020-07-12 13:45:50 +0200226
227void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);
Alexander Couzens896fcd52020-10-11 19:52:36 +0200228void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi);
Alexander Couzens6a161492020-07-12 13:45:50 +0200229
230/* create a VC SNS connection */
Alexander Couzense769f522020-12-07 07:37:07 +0100231int gprs_ns2_sns_count(struct gprs_ns2_nse *nse);
232int gprs_ns2_sns_add_endpoint(struct gprs_ns2_nse *nse,
233 const struct osmo_sockaddr *saddr);
234int gprs_ns2_sns_del_endpoint(struct gprs_ns2_nse *nse,
235 const struct osmo_sockaddr *saddr);
Alexander Couzens6b9d2322021-02-12 03:17:59 +0100236int gprs_ns2_sns_add_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
237int gprs_ns2_sns_del_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
Alexander Couzens125298f2020-10-11 21:22:42 +0200238const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);
Alexander Couzens6a161492020-07-12 13:45:50 +0200239
Alexander Couzensd33512b2020-10-11 21:42:11 +0200240const struct osmo_sockaddr *gprs_ns2_ip_vc_remote(const struct gprs_ns2_vc *nsvc);
Alexander Couzens979f5f52020-10-11 21:01:48 +0200241const struct osmo_sockaddr *gprs_ns2_ip_vc_local(const struct gprs_ns2_vc *nsvc);
Alexander Couzensd420ea92020-10-12 01:11:05 +0200242bool gprs_ns2_ip_vc_equal(const struct gprs_ns2_vc *nsvc,
243 const struct osmo_sockaddr *local,
244 const struct osmo_sockaddr *remote,
245 uint16_t nsvci);
Alexander Couzens9a4cf272020-10-11 20:48:04 +0200246const struct osmo_sockaddr *gprs_ns2_ip_bind_sockaddr(struct gprs_ns2_vc_bind *bind);
Alexander Couzens6a161492020-07-12 13:45:50 +0200247int gprs_ns2_is_ip_bind(struct gprs_ns2_vc_bind *bind);
248int gprs_ns2_ip_bind_set_dscp(struct gprs_ns2_vc_bind *bind, int dscp);
Harald Welted99e4ee2021-04-28 19:57:12 +0200249int gprs_ns2_ip_bind_set_priority(struct gprs_ns2_vc_bind *bind, uint8_t priority);
Alexander Couzens38b19e82020-09-23 23:56:37 +0200250struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
Alexander Couzens6a161492020-07-12 13:45:50 +0200251 struct gprs_ns2_vc_bind *bind,
Pau Espin Pedrolf6ef9ba2023-04-27 17:50:10 +0200252 const struct osmo_sockaddr *rem_addr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200253
254int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
Alexander Couzensaaa55a62020-12-03 06:02:03 +0100255 const char *name,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700256 const struct osmo_sockaddr *local,
Alexander Couzens6a161492020-07-12 13:45:50 +0200257 int dscp,
258 struct gprs_ns2_vc_bind **result);
259int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);
Alexander Couzens22c26e02020-12-10 04:10:07 +0100260uint16_t gprs_ns2_fr_nsvc_dlci(const struct gprs_ns2_vc *nsvc);
Alexander Couzens6a161492020-07-12 13:45:50 +0200261
Alexander Couzens38b19e82020-09-23 23:56:37 +0200262struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
263 struct gprs_ns2_nse *nse,
Vadim Yanitskiya07f25e2020-10-09 21:47:01 +0700264 const struct osmo_sockaddr *sockaddr);
Alexander Couzens6a161492020-07-12 13:45:50 +0200265void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
Daniel Willmannf1286542020-11-03 23:03:33 +0100266
267/* VC information */
Alexander Couzens6a161492020-07-12 13:45:50 +0200268const char *gprs_ns2_ll_str(struct gprs_ns2_vc *nsvc);
269char *gprs_ns2_ll_str_buf(char *buf, size_t buf_len, struct gprs_ns2_vc *nsvc);
270char *gprs_ns2_ll_str_c(const void *ctx, struct gprs_ns2_vc *nsvc);
Daniel Willmannf1286542020-11-03 23:03:33 +0100271const char *gprs_ns2_nsvc_state_name(struct gprs_ns2_vc *nsvc);
Alexander Couzens6a161492020-07-12 13:45:50 +0200272
273/* vty */
Alexander Couzensda1bf8e2021-01-25 16:27:33 +0100274int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi);
Alexander Couzens412bc342020-11-19 05:24:37 +0100275
Alexander Couzens6a161492020-07-12 13:45:50 +0200276/*! @} */