blob: 8019ad1cab04e5aabcd7818bd7bf620cbb3c8811 [file] [log] [blame]
Harald Welte9b455bf2010-03-14 15:45:01 +08001#ifndef _GPRS_SGSN_H
2#define _GPRS_SGSN_H
3
Harald Welteeaa614c2010-05-02 11:26:34 +02004#include <stdint.h>
Harald Welted193cb32010-05-17 22:58:03 +02005#include <netinet/in.h>
6
Holger Hans Peter Freyther26d0fe32012-01-06 17:29:06 +01007#include <osmocom/core/timer.h>
8
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +01009#include <osmocom/gsm/gsm48.h>
Harald Welteeaa614c2010-05-02 11:26:34 +020010
Harald Welte496aee42010-06-30 19:59:55 +020011#include <osmocom/crypt/gprs_cipher.h>
12
Jacob Erlbeckbd0cf112014-12-01 12:33:33 +010013#include <openbsc/gsm_data.h>
14
Harald Welte2720e732010-05-17 00:44:57 +020015#define GSM_IMSI_LENGTH 17
16#define GSM_IMEI_LENGTH 17
17#define GSM_EXTENSION_LENGTH 15
18
Harald Welte807a5d82010-06-01 11:53:01 +020019struct gprs_llc_lle;
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +010020struct ctrl_handle;
Jacob Erlbeck02ab91e2014-11-12 09:53:45 +010021struct gsm_subscriber;
Harald Welte807a5d82010-06-01 11:53:01 +020022
Harald Welte9b455bf2010-03-14 15:45:01 +080023/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
24enum gprs_mm_state {
25 GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
26 GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
27 GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
28 GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
29 GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
30};
31
Harald Weltec2e8cc42010-05-31 20:23:38 +020032enum gprs_mm_ctr {
Harald Welte8acd88f2010-05-18 10:57:45 +020033 GMM_CTR_PKTS_SIG_IN,
34 GMM_CTR_PKTS_SIG_OUT,
35 GMM_CTR_PKTS_UDATA_IN,
36 GMM_CTR_PKTS_UDATA_OUT,
37 GMM_CTR_BYTES_UDATA_IN,
38 GMM_CTR_BYTES_UDATA_OUT,
39 GMM_CTR_PDP_CTX_ACT,
40 GMM_CTR_SUSPEND,
41 GMM_CTR_PAGING_PS,
42 GMM_CTR_PAGING_CS,
43 GMM_CTR_RA_UPDATE,
44};
45
Harald Welteefbdee92010-06-10 00:20:12 +020046enum gprs_pdp_ctx {
47 PDP_CTR_PKTS_UDATA_IN,
48 PDP_CTR_PKTS_UDATA_OUT,
49 PDP_CTR_BYTES_UDATA_IN,
50 PDP_CTR_BYTES_UDATA_OUT,
51};
52
Harald Weltec2e8cc42010-05-31 20:23:38 +020053enum gprs_t3350_mode {
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +010054 GMM_T3350_MODE_NONE,
Harald Weltec2e8cc42010-05-31 20:23:38 +020055 GMM_T3350_MODE_ATT,
56 GMM_T3350_MODE_RAU,
57 GMM_T3350_MODE_PTMSI_REALL,
58};
59
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +020060/* Authorization/ACL handling */
61enum sgsn_auth_state {
62 SGSN_AUTH_UNKNOWN,
Jacob Erlbeck4adb1362014-12-02 09:47:26 +010063 SGSN_AUTH_AUTHENTICATE,
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +020064 SGSN_AUTH_ACCEPTED,
65 SGSN_AUTH_REJECTED
66};
67
Harald Welte9b455bf2010-03-14 15:45:01 +080068#define MS_RADIO_ACCESS_CAPA
69
70/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
Harald Weltef533e132010-05-01 16:45:46 +020071/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
Harald Welte9b455bf2010-03-14 15:45:01 +080072struct sgsn_mm_ctx {
73 struct llist_head list;
74
75 char imsi[GSM_IMSI_LENGTH];
76 enum gprs_mm_state mm_state;
Harald Welteeaa614c2010-05-02 11:26:34 +020077 uint32_t p_tmsi;
Harald Weltec2e8cc42010-05-31 20:23:38 +020078 uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
Harald Welteeaa614c2010-05-02 11:26:34 +020079 uint32_t p_tmsi_sig;
Harald Welte9b455bf2010-03-14 15:45:01 +080080 char imei[GSM_IMEI_LENGTH];
Harald Weltef533e132010-05-01 16:45:46 +020081 /* Opt: Software Version Numbber / TS 23.195 */
Harald Welte9b455bf2010-03-14 15:45:01 +080082 char msisdn[GSM_EXTENSION_LENGTH];
83 struct gprs_ra_id ra;
Harald Welteeaa614c2010-05-02 11:26:34 +020084 uint16_t cell_id;
85 uint32_t cell_id_age;
86 uint16_t sac; /* Iu: Service Area Code */
87 uint32_t sac_age;/* Iu: Service Area Code age */
Harald Welte9b455bf2010-03-14 15:45:01 +080088 /* VLR number */
Harald Welteeaa614c2010-05-02 11:26:34 +020089 uint32_t new_sgsn_addr;
Jacob Erlbeckbd0cf112014-12-01 12:33:33 +010090 /* Authentication Triplet */
91 struct gsm_auth_tuple auth_triplet;
Harald Welte9b455bf2010-03-14 15:45:01 +080092 /* Kc */
Harald Weltef533e132010-05-01 16:45:46 +020093 /* Iu: CK, IK, KSI */
Harald Welte9b455bf2010-03-14 15:45:01 +080094 /* CKSN */
95 enum gprs_ciph_algo ciph_algo;
96 struct {
Harald Welteeaa614c2010-05-02 11:26:34 +020097 uint8_t len;
Alexander Chemeris84402c02013-07-03 10:12:23 +040098 uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */
Harald Welte9b455bf2010-03-14 15:45:01 +080099 } ms_radio_access_capa;
100 struct {
Harald Welteeaa614c2010-05-02 11:26:34 +0200101 uint8_t len;
Alexander Chemeris84402c02013-07-03 10:12:23 +0400102 uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */
Harald Welte9b455bf2010-03-14 15:45:01 +0800103 } ms_network_capa;
Harald Welteeaa614c2010-05-02 11:26:34 +0200104 uint16_t drx_parms;
Harald Welte9b455bf2010-03-14 15:45:01 +0800105 int mnrg; /* MS reported to HLR? */
106 int ngaf; /* MS reported to MSC/VLR? */
107 int ppf; /* paging for GPRS + non-GPRS? */
108 /* SMS Parameters */
109 int recovery;
Harald Welteba850c52010-05-02 14:40:32 +0200110 uint8_t radio_prio_sms;
Harald Welte9b455bf2010-03-14 15:45:01 +0800111
112 struct llist_head pdp_list;
113
114 /* Additional bits not present in the GSM TS */
Harald Welte807a5d82010-06-01 11:53:01 +0200115 struct gprs_llc_llme *llme;
Harald Welteeaa614c2010-05-02 11:26:34 +0200116 uint32_t tlli;
Harald Welte807a5d82010-06-01 11:53:01 +0200117 uint32_t tlli_new;
Harald Welte6abf94e2010-05-18 10:35:06 +0200118 uint16_t nsei;
119 uint16_t bvci;
Harald Welte8acd88f2010-05-18 10:57:45 +0200120 struct rate_ctr_group *ctrg;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200121 struct osmo_timer_list timer;
Harald Weltec2e8cc42010-05-31 20:23:38 +0200122 unsigned int T; /* Txxxx number */
123 unsigned int num_T_exp; /* number of consecutive T expirations */
124
125 enum gprs_t3350_mode t3350_mode;
126 uint8_t t3370_id_type;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100127 uint8_t pending_req; /* the request's message type */
128 /* TODO: There isn't much semantic difference between t3350_mode
129 * (refers to the timer) and pending_req (refers to the procedure),
130 * where mm->T == 3350 => mm->t3350_mode == f(mm->pending_req). Check
131 * whether one of them can be dropped. */
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100132
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200133 enum sgsn_auth_state auth_state;
Jacob Erlbeck8ff3fb02014-12-01 12:44:24 +0100134 int is_authenticated;
Jacob Erlbeck02ab91e2014-11-12 09:53:45 +0100135
136 struct gsm_subscriber *subscr;
Harald Welte9b455bf2010-03-14 15:45:01 +0800137};
138
Daniel Willmannb15ceec2014-09-03 15:57:49 +0200139#define LOGMMCTXP(level, mm, fmt, args...) \
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200140 LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \
141 (mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args)
Daniel Willmannb15ceec2014-09-03 15:57:49 +0200142
Harald Welte9b455bf2010-03-14 15:45:01 +0800143/* look-up a SGSN MM context based on TLLI + RAI */
Harald Welteeaa614c2010-05-02 11:26:34 +0200144struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
Harald Welte9b455bf2010-03-14 15:45:01 +0800145 const struct gprs_ra_id *raid);
Harald Welteeaa614c2010-05-02 11:26:34 +0200146struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
Harald Welte9b455bf2010-03-14 15:45:01 +0800147struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
148
149/* Allocate a new SGSN MM context */
Harald Welteeaa614c2010-05-02 11:26:34 +0200150struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
Harald Welte9b455bf2010-03-14 15:45:01 +0800151 const struct gprs_ra_id *raid);
Harald Weltec728eea2010-12-24 23:07:18 +0100152void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm);
Harald Welte9b455bf2010-03-14 15:45:01 +0800153
Harald Welted193cb32010-05-17 22:58:03 +0200154
155enum pdp_ctx_state {
156 PDP_STATE_NONE,
Harald Welte6abf94e2010-05-18 10:35:06 +0200157 PDP_STATE_CR_REQ,
158 PDP_STATE_CR_CONF,
Harald Weltea9b473a2010-12-24 21:13:26 +0100159
160 /* 04.08 / Figure 6.2 / 6.1.2.2 */
161 PDP_STATE_INACT_PEND,
162 PDP_STATE_INACTIVE = PDP_STATE_NONE,
Harald Welted193cb32010-05-17 22:58:03 +0200163};
164
165enum pdp_type {
166 PDP_TYPE_NONE,
Harald Welte6abf94e2010-05-18 10:35:06 +0200167 PDP_TYPE_ETSI_PPP,
168 PDP_TYPE_IANA_IPv4,
169 PDP_TYPE_IANA_IPv6,
Harald Welted193cb32010-05-17 22:58:03 +0200170};
171
172struct sgsn_pdp_ctx {
173 struct llist_head list; /* list_head for mmctx->pdp_list */
174 struct llist_head g_list; /* list_head for global list */
175 struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
176 struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
Harald Welteefbdee92010-06-10 00:20:12 +0200177 struct rate_ctr_group *ctrg;
Harald Welted193cb32010-05-17 22:58:03 +0200178
179 //unsigned int id;
180 struct pdp_t *lib; /* pointer to libgtp PDP ctx */
181 enum pdp_ctx_state state;
182 enum pdp_type type;
183 uint32_t address;
184 char *apn_subscribed;
185 //char *apn_used;
Harald Welte6abf94e2010-05-18 10:35:06 +0200186 uint16_t nsapi; /* SNDCP */
187 uint16_t sapi; /* LLC */
Harald Welted193cb32010-05-17 22:58:03 +0200188 uint8_t ti; /* transaction identifier */
189 int vplmn_allowed;
190 uint32_t qos_profile_subscr;
191 //uint32_t qos_profile_req;
192 //uint32_t qos_profile_neg;
193 uint8_t radio_prio;
194 uint32_t tx_npdu_nr;
195 uint32_t rx_npdu_nr;
196 uint32_t tx_gtp_snd;
197 uint32_t rx_gtp_snu;
198 //uint32_t charging_id;
199 int reordering_reqd;
Harald Weltea9b473a2010-12-24 21:13:26 +0100200
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200201 struct osmo_timer_list timer;
Harald Weltea9b473a2010-12-24 21:13:26 +0100202 unsigned int T; /* Txxxx number */
203 unsigned int num_T_exp; /* number of consecutive T expirations */
Harald Welted193cb32010-05-17 22:58:03 +0200204};
205
Daniel Willmannb15ceec2014-09-03 15:57:49 +0200206#define LOGPDPCTXP(level, pdp, fmt, args...) \
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200207 LOGP(DGPRS, level, "PDP(%s/%u) " \
208 fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args)
Harald Welted193cb32010-05-17 22:58:03 +0200209
Harald Welte96df6062010-06-03 06:37:26 +0200210/* look up PDP context by MM context and NSAPI */
Harald Welted193cb32010-05-17 22:58:03 +0200211struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
212 uint8_t nsapi);
Harald Welte96df6062010-06-03 06:37:26 +0200213/* look up PDP context by MM context and transaction ID */
Harald Welte77289c22010-05-18 14:32:29 +0200214struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
215 uint8_t tid);
Harald Welte96df6062010-06-03 06:37:26 +0200216
Harald Welted193cb32010-05-17 22:58:03 +0200217struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
218 uint8_t nsapi);
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200219void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp);
Harald Welted193cb32010-05-17 22:58:03 +0200220void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
221
222
Harald Welte77289c22010-05-18 14:32:29 +0200223struct sgsn_ggsn_ctx {
Harald Welted193cb32010-05-17 22:58:03 +0200224 struct llist_head list;
225 uint32_t id;
226 unsigned int gtp_version;
227 struct in_addr remote_addr;
Harald Weltea9b473a2010-12-24 21:13:26 +0100228 int remote_restart_ctr;
Harald Welted193cb32010-05-17 22:58:03 +0200229 struct gsn_t *gsn;
230};
Harald Weltecd4dd4d2010-05-18 17:20:49 +0200231struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id);
232struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id);
Harald Weltea9b473a2010-12-24 21:13:26 +0100233struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr);
Harald Weltecd4dd4d2010-05-18 17:20:49 +0200234struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
Harald Welted193cb32010-05-17 22:58:03 +0200235
236struct apn_ctx {
237 struct llist_head list;
Harald Welte77289c22010-05-18 14:32:29 +0200238 struct sgsn_ggsn_ctx *ggsn;
Harald Welted193cb32010-05-17 22:58:03 +0200239 char *name;
240 char *description;
241};
242
243extern struct llist_head sgsn_mm_ctxts;
244extern struct llist_head sgsn_ggsn_ctxts;
245extern struct llist_head sgsn_apn_ctxts;
246extern struct llist_head sgsn_pdp_ctxts;
247
Harald Welte6463c072010-05-18 17:04:55 +0200248uint32_t sgsn_alloc_ptmsi(void);
249
Harald Weltea9b473a2010-12-24 21:13:26 +0100250/* High-level function to be called in case a GGSN has disappeared or
251 * ottherwise lost state (recovery procedure) */
252int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn);
253
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100254char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len);
255
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200256/* Force re-attachment based on msgb meta data */
257int sgsn_force_reattach_oldmsg(struct msgb *oldmsg);
258
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100259/*
260 * ctrl interface related work
261 */
262struct gsm_network;
263struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, uint16_t port);
264int sgsn_ctrl_cmds_install(void);
265
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +0200266/*
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200267 * Authorization/ACL handling
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +0200268 */
Jacob Erlbeck3b5d4072014-10-24 15:11:03 +0200269struct imsi_acl_entry {
270 struct llist_head list;
271 char imsi[16+1];
272};
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200273
274struct sgsn_subscriber_data {
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +0100275 struct sgsn_mm_ctx *mm;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100276 struct gsm_auth_tuple auth_triplets[5];
277 int auth_triplets_updated;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +0100278 int authenticate;
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200279};
280
Jacob Erlbeck3b5d4072014-10-24 15:11:03 +0200281struct sgsn_config;
282struct sgsn_instance;
Jacob Erlbeckf951a012014-11-07 14:17:44 +0100283extern const struct value_string *sgsn_auth_state_names;
Jacob Erlbeck3b5d4072014-10-24 15:11:03 +0200284
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +0100285void sgsn_auth_init(void);
Jacob Erlbeck3b5d4072014-10-24 15:11:03 +0200286struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg);
287int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg);
288int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200289/* Request authorization */
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +0100290int sgsn_auth_request(struct sgsn_mm_ctx *mm);
291enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mm);
292void sgsn_auth_update(struct sgsn_mm_ctx *mm);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100293struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
294 unsigned key_seq);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200295
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100296/*
297 * GPRS subscriber data
298 */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100299#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16)
300#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17)
301#define GPRS_SUBSCRIBER_CANCELLED (1 << 18)
302
303#define GPRS_SUBSCRIBER_UPDATE_PENDING_MASK ( \
304 GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING | \
305 GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \
306)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100307
308void gprs_subscr_init(struct sgsn_instance *sgi);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100309int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
310int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100311void gprs_subscr_delete(struct gsm_subscriber *subscr);
312struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100313struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100314struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi);
315void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr);
316void gprs_subscr_update(struct gsm_subscriber *subscr);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100317void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100318int gprs_subscr_rx_gsup_message(struct msgb *msg);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100319
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200320/* Called on subscriber data updates */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100321void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
322 struct gsm_subscriber *subscr);
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +0200323
Holger Hans Peter Freyther90e9a442014-04-04 12:51:28 +0200324int gprs_sndcp_vty_init(void);
325struct sgsn_instance;
326int sgsn_gtp_init(struct sgsn_instance *sgi);
327
Harald Welte9b455bf2010-03-14 15:45:01 +0800328#endif /* _GPRS_SGSN_H */