aboutsummaryrefslogtreecommitdiffstats
path: root/gtp/pdp.h
blob: d64d394fff75c9801c677d8853ece4e75d3375e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 *  OsmoGGSN - Gateway GPRS Support Node
 *  Copyright (C) 2002, 2003 Mondru AB.
 *  Copyright (C) 2017 Harald Welte <laforge@gnumonks.org>
 *
 *  The contents of this file may be used under the terms of the GNU
 *  General Public License Version 2, provided that the above copyright
 *  notice and this permission notice is included in all copies or
 *  substantial portions of the software.
 *
 */

#ifndef _PDP_H
#define _PDP_H

#include <stdbool.h>
#include <netinet/in.h>

#include <osmocom/core/defs.h>

struct gsn_t;

#define LOGPDPX(ss, level, pdp, fmt, args...)				\
	LOGP(ss, level, "PDP(%s:%u): " fmt, imsi_gtp2str(&(pdp)->imsi), (pdp)->nsapi, ## args)

#define PDP_MAX 1024		/* Max number of PDP contexts */
#define PDP_MAXNSAPI 16		/* Max number of NSAPI */

#define PDP_EUA_ORG_IETF	0xF1
#define PDP_EUA_TYPE_v4		0x21
#define PDP_EUA_TYPE_v6		0x57
#define PDP_EUA_TYPE_v4v6	0x8D

/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
 * by 135: QOS Profile in version 1 */

struct sl_t {
	unsigned int l;
	char *v;
};

struct ul_t {
	unsigned int l;
	unsigned char *v;
};

struct ul16_t {
	unsigned int l;
	unsigned char v[16];
};

struct ul66_t {
	unsigned int l;
	unsigned char v[66];
};

struct ul255_t {
	unsigned int l;
	unsigned char v[255];
};

/* *****************************************************************
 * Information storage for each PDP context
 *
 * Information storage for each PDP context is defined in 23.060
 * section 13.3 and 03.60. Includes IMSI, MSISDN, APN, PDP-type,
 * PDP-address (IP address), sequence numbers, charging ID.  For the
 * SGSN it also includes radio related mobility information.
 *
 * The following structure is a combination of the storage
 * requirements for each PDP context for the GGSN and SGSN.  It
 * contains both 23.060 as well as 03.60 parameters.  Information is
 * stored in the format for information elements described in 29.060
 * and 09.60.
 * 31 * 4 + 15 structs +  = 120 + 15 structs ~ 2k / context
 * Structs: IP address 16+4 bytes (6), APN 255 bytes (2)
 * QOS: 255 bytes (3), msisdn 16 bytes (1),
 *
 * TODO: We need to consider who manages the pdp_t hash tables
 * Is it gtp_lib, or is it the application?
 * I suppose that it will be gtp_lib.
 * SGSN will ask gtplib for new pdp_t. Fill out the fields,
 * and pass it on to gtp_create_pdp_req.
 * GGSN will receive gtp_create_pdp_ind, create new pdp_t and
 * send responce to SGSN.
 * SGSN will receive response and gtplib will find the
 * original pdp_t corresponding to the request. This will be
 * passed on to the application.
 * Eventually the SGSN will close the connection, and the
 * pdp_t will be freed by gtplib in SGSN and GGSN
 * This means that gtplib need to have functions to
 * allocate, free, sort and find pdp_t
 * (newpdp, freepdp, getpdp)
 * Hash tables: TID, IMSI, IP etc.)
 *
 *
 * Secondary PDP Context Activation Procedure
 *
 * With GTP version 1 it is possible to establish multiple PDP
 * contexts with the same IP address. With this scheme the first
 * context is established as normal. Following contexts are
 * established by referencing one of the allready existing ones.  Each
 * context is uniquely identified by IMSI and NSAPI. Each context is
 * allocated an tei_di, but they all share the same tei_c.
 *
 * For Delete PDP Context the context is referenced by tei_c and
 * nsapi. As an option it is possible to include a teardown indicater,
 * in which case all PDP contexts with the same tei_c (IP address) are
 * deleted.
 *
 * For Update PDP Context the context is normally referenced by tei_c
 * and nsapi. If moving from GTP0 to GTP1 during an update the context
 * is referenced instead by IMSI and NSAPI.
 *****************************************************************/

struct pdp_t {
	/* Parameter determining if this PDP is in use. */
	uint8_t inuse;		/* 0=free. 1=used by somebody */

	/* Pointers related to hash tables */
	struct pdp_t *tidnext;
	struct pdp_t *ipnext;

	/* Parameters shared by all PDP context belonging to the same MS */

	void *ipif;		/* IP network interface */
	void *peer[2];		/* Pointer to peer protocol */
	void *asap;		/* Application specific service access point */

	uint64_t imsi;		/* International Mobile Subscriber Identity. */
	struct ul16_t msisdn;	/* The basic MSISDN of the MS. */
	uint8_t mnrg;		/* Indicates whether the MS is marked as not reachable for PS at the HLR. (1 bit, not transmitted) */
	uint8_t cch_sub;	/* The charging characteristics for the MS, e.g. normal, prepaid, flat-rate, and/or hot billing subscription. (not transmitted) */
	uint16_t traceref;	/* Identifies a record or a collection of records for a particular trace. */
	uint16_t tracetype;	/* Indicates the type of trace. */
	struct ul_t triggerid;	/* Identifies the entity that initiated the trace. */
	struct ul_t omcid;	/* Identifies the OMC that shall receive the trace record(s). */
	uint8_t rec_hlr;	/* Indicates if HLR or VLR is performing database recovery. (1 bit, not transmitted) */

	/* Parameters specific to each individual PDP context */

	uint8_t pdp_id;		/* Index of the PDP context. (PDP context identifier) */
	uint8_t pdp_state;	/* PDP State Packet data protocol state, INACTIVE or ACTIVE. (1 bit, not transmitted) */
	/* struct ul_t pdp_type; * PDP type; e.g. PPP or IP. */
	/* struct ul_t pdp_addr; * PDP address; e.g. an IP address. */
	struct ul66_t eua;	/* End user address. PDP type and address combined */
	uint8_t pdp_dyn;	/* Indicates whether PDP Address is static or dynamic. (1 bit, not transmitted) */
	struct ul255_t apn_req;	/* The APN requested. */
	struct ul255_t apn_sub;	/* The APN received from the HLR. */
	struct ul255_t apn_use;	/* The APN Network Identifier currently used. */
	uint8_t nsapi;		/* Network layer Service Access Point Identifier. (4 bit) */
	uint16_t ti;		/* Transaction Identifier. (4 or 12 bit) */

	uint32_t teic_own;	/* (Own Tunnel Endpoint Identifier Control) */
	uint32_t teid_own;	/* (Own Tunnel Endpoint Identifier Data I) */
	uint32_t teic_gn;	/* Tunnel Endpoint Identifier for the Gn and Gp interfaces. (Control plane) */
	uint32_t teid_gn;	/* Tunnel Endpoint Identifier for the Gn and Gp interfaces. (Data I) */
	uint32_t tei_iu;	/* Tunnel Endpoint Identifier for the Iu interface. */

	uint16_t fllc;		/* (Local Flow Label Control, gtp0) */
	uint16_t fllu;		/* (Local Flow Label Data I, gtp0) */
	uint16_t flrc;		/* (Remote gn/gp Flow Label Control, gtp0) */
	uint16_t flru;		/* (Remote gn/gp Flow Label Data I, gtp0) */

	struct ul255_t tft;	/* Traffic flow template. */
	/*struct ul16_t sgsnc;  * The IP address of the SGSN currently serving this MS. (Control plane) */
	/*struct ul16_t sgsnu;  * The IP address of the SGSN currently serving this MS. (User plane) */
	/*struct ul16_t ggsnc;  * The IP address of the GGSN currently used. (Control plane) */
	/*struct ul16_t ggsnu;  * The IP address of the GGSN currently used. (User plane) */

	struct ul16_t gsnlc;	/* The IP address of the local GSN. (Control plane) */
	struct ul16_t gsnlu;	/* The IP address of the local GSN. (User plane) */
	struct ul16_t gsnrc;	/* The IP address of the remote GSN. (Control plane) */
	struct ul16_t gsnru;	/* The IP address of the remote GSN. (User plane) */

	uint8_t vplmn_allow;	/* Specifies whether the MS is allowed to use the APN in the domain of the HPLMN only, or additionally the APN in the domain of the VPLMN. (1 bit) */
	uint8_t qos_sub0[3];	/* The quality of service profile subscribed. */
	uint8_t qos_req0[3];	/* The quality of service profile requested. */
	uint8_t qos_neg0[3];	/* The quality of service profile negotiated. */
	struct ul255_t qos_sub;	/* The quality of service profile subscribed. */
	struct ul255_t qos_req;	/* The quality of service profile requested. */
	struct ul255_t qos_neg;	/* The quality of service profile negotiated. */
	uint8_t radio_pri;	/* The RLC/MAC radio priority level for uplink user data transmission. (4 bit) */
	uint16_t flow_id;	/*  Packet flow identifier. */
	/* struct ul_t bssqos_neg; * The aggregate BSS quality of service profile negotiated for the packet flow that this PDP context belongs to. (NOT GTP) */
	uint8_t sndcpd;		/* SNDCP sequence number of the next downlink N-PDU to be sent to the MS. */
	uint8_t sndcpu;		/* SNDCP sequence number of the next uplink N-PDU expected from the MS. */
	uint8_t rec_sgsn;	/* Indicates if the SGSN is performing database recovery. (1 bit, not transmitted) */
/*  uint16_t    gtpsnd;    GTP-U sequence number of the next downlink N-PDU to be sent to the SGSN / received from the GGSN. */
/*  uint16_t    gtpsnu;    GTP-U sequence number of the next uplink N-PDU to be received from the SGSN / sent to the GGSN */
	uint16_t gtpsntx;	/* GTP-U sequence number of the next downlink N-PDU to be sent (09.60 section 8.1.1.1) */
	uint16_t gtpsnrx;	/* GTP-U sequence number of the next uplink N-PDU to be received (09.60 section 8.1.1.1) */
	uint8_t pdcpsndd;	/* Sequence number of the next downlink in-sequence PDCP-PDU to be sent to the MS. */
	uint8_t pdcpsndu;	/* Sequence number of the next uplink in-sequence PDCP-PDU expected from the MS. */
	uint32_t cid;		/* Charging identifier, identifies charging records generated by SGSN and GGSN. */
	uint16_t cch_pdp;	/* The charging characteristics for this PDP context, e.g. normal, prepaid, flat-rate, and/or hot billing. */
	struct ul16_t rnc_addr;	/* The IP address of the RNC currently used. */
	uint8_t reorder;	/* Specifies whether the GGSN shall reorder N-PDUs received from the SGSN / Specifies whether the SGSN shall reorder N-PDUs before delivering the N-PSUs to the MS. (1 bit) */
	struct ul255_t pco_req;	/* Requested packet control options. */
	struct ul255_t pco_neg;	/* Negotiated packet control options. */
	uint32_t selmode;	/* Selection mode. */
	struct ul255_t rattype;	/* Radio Access Technology Type */
	int rattype_given;	/* Radio Access Technology Type given */
	struct ul255_t userloc;	/* User Location Information  */
	int userloc_given;	/* User Location Information  given */
	struct ul255_t rai;	/* Routing Area Information  */
	int rai_given;		/* Routing Area Information  given */
	struct ul255_t mstz;	/* MS Time Zone */
	int mstz_given;		/* MS Time Zone given */
	struct ul255_t imeisv;	/* IMEI Software Version */
	int imeisv_given;	/* IMEI Software Version given */
	int norecovery_given;	/* norecovery given */

	/* Additional parameters used by library */

	int version;		/* Protocol version currently in use. 0 or 1 */

	uint64_t tid;		/* Combination of imsi and nsapi */
	uint16_t seq;		/* Sequence number of last request */
	struct sockaddr_in sa_peer;	/* Address of last request */
	int fd;			/* File descriptor request was received on */

	uint8_t teic_confirmed;	/* 0: Not confirmed. 1: Confirmed */

	/* Parameters used for secondary activation procedure (tei data) */
	/* If (secondary == 1) then teic_own indicates linked PDP context */
	uint8_t secondary;	/* 0: Primary (control). 1: Secondary (data only) */
	uint8_t nodata;		/* 0: User plane PDP context. 1: No user plane */

	/* Secondary contexts of this primary context */
	uint32_t secondary_tei[PDP_MAXNSAPI];

	/* IP address used for Create and Update PDP Context Requests */
	struct in_addr hisaddr0;	/* Server address */
	struct in_addr hisaddr1;	/* Server address */

	/* to be used by libgtp callers/users (to attach their own private state) */
	void *priv;

	struct gsn_t *gsn; /* Back pointer to GSN where this pdp ctx belongs to */

	bool tx_gpdu_seq;		/* Transmit (true) or suppress G-PDU sequence numbers */
};

/* functions related to pdp_t management */
int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi,
		   uint8_t nsapi, struct pdp_t *pdp_old);
int pdp_freepdp(struct pdp_t *pdp);
int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl);
int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei);
int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn);
int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi);
int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid);

int pdp_tidhash(uint64_t tid);
int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
int pdp_tiddel(struct pdp_t *pdp);

uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi);
void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid);

unsigned int pdp_count_secondary(struct pdp_t *pdp);

/* Deprecated APIs (support for only 1 GSN per process). Must be used only after first call to gtp_new() and until it is freed. */
int pdp_init(struct gsn_t *gsn); /* Use only allowed inside libgtp to keep compatiblity with deprecated APIs defined here. */
int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
	       struct pdp_t *pdp_old) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
int pdp_getpdp(struct pdp_t **pdp) OSMO_DEPRECATED("Use gsn_t->pdpa field instead");
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl) OSMO_DEPRECATED("Use gtp_pdp_getgtp0() instead");
int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei) OSMO_DEPRECATED("Use gtp_pdp_getgtp1() instead");
int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn) OSMO_DEPRECATED("Use gtp_pdp_getgtp1_peer_d() instead");
int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_getimsi() instead");
int pdp_tidget(struct pdp_t **pdp, uint64_t tid) OSMO_DEPRECATED("Use gtp_pdp_tidget() instead");


#endif /* !_PDP_H */