aboutsummaryrefslogtreecommitdiffstats
path: root/gtp/gsn.h
blob: be7cd53cb9a0b0184eb7a8b0db0223b66c95e4ff (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
/*
 *  OsmoGGSN - Gateway GPRS Support Node
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 *
 *  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 _GSN_H
#define _GSN_H

#include <osmocom/core/utils.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/gsm/gsm48.h>

#include "pdp.h"

#define GTP_MODE_GGSN 1
#define GTP_MODE_SGSN 2

#define RESTART_FILE "gsn_restart"

extern struct osmo_tdef gtp_T_defs[];

/* ***********************************************************
 * Information storage for each gsn instance
 *
 * Normally each instance of the application corresponds to
 * one instance of a gsn.
 *
 * In order to avoid global variables in the application, and
 * also in order to allow several instances of a gsn in the same
 * application this struct is provided in order to store all
 * relevant information related to the gsn.
 *
 * Note that this does not include information storage for '
 * each pdp context. This is stored in another struct.
 *************************************************************/

enum gsn_rate_ctr_keys {
	GSN_CTR_ERR_SOCKET,
	GSN_CTR_ERR_READFROM,	/* Number of readfrom errors */
	GSN_CTR_ERR_SENDTO,	/* Number of sendto errors */
	GSN_CTR_ERR_QUEUEFULL,	/* Number of times queue was full */
	GSN_CTR_ERR_SEQ,	/* Number of seq out of range */
	GSN_CTR_ERR_ADDRESS,	/* GSN address conversion failed */
	GSN_CTR_ERR_UNKNOWN_PDP,	/* GSN address conversion failed */
	GSN_CTR_ERR_UNEXPECTED_CAUSE,	/* Unexpected cause value received */
	GSN_CTR_ERR_OUT_OF_PDP,	/* Out of storage for PDP contexts */
	GSN_CTR_PKT_EMPTY,		/* Number of empty packets */
	GSN_CTR_PKT_UNSUP,		/* Number of unsupported version 29.60 11.1.1 */
	GSN_CTR_PKT_TOOSHORT,	/* Number of too short headers 29.60 11.1.2 */
	GSN_CTR_PKT_UNKNOWN,	/* Number of unknown messages 29.60 11.1.3 */
	GSN_CTR_PKT_UNEXPECT,	/* Number of unexpected messages 29.60 11.1.4 */
	GSN_CTR_PKT_DUPLICATE,	/* Number of duplicate or unsolicited replies */
	GSN_CTR_PKT_MISSING,	/* Number of missing information field messages */
	GSN_CTR_PKT_INCORRECT,	/* Number of incorrect information field messages */
	GSN_CTR_PKT_INVALID,	/* Number of invalid message format messages */
};

/* 3GPP TS 29.006 14.1, 14,2 */
enum gtp_gsn_timers {
	GTP_GSN_TIMER_T3_RESPONSE = 3,
	GTP_GSN_TIMER_N3_REQUESTS = 1003,
	GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3,
};

struct gsn_t {
	/* Parameters related to the network interface */

	int fd0;		/* GTP0 file descriptor */
	int fd1c;		/* GTP1 control plane file descriptor */
	int fd1u;		/* GTP0 user plane file descriptor */
	int mode;		/* Mode of operation: GGSN or SGSN */
	struct in_addr gsnc;	/* IP address of this gsn for signalling */
	struct in_addr gsnu;	/* IP address of this gsn for user traffic */

	/* Parameters related to signalling messages */
	uint16_t seq_next;	/* Next sequence number to use */
	int seq_first;		/* First packet in queue (oldest timeout) */
	int seq_last;		/* Last packet in queue (youngest timeout) */

	unsigned char restart_counter;	/* Increment on restart. Stored on disk */
	char *statedir;		/* Disk location for permanent storage */
	void *priv;		/* used by libgtp users to attach their own state) */
	struct queue_t *queue_req;	/* Request queue */
	struct queue_t *queue_resp;	/* Response queue */

	struct pdp_t pdpa[PDP_MAX];	/* PDP storage */
	struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */

	struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */

	/* Call back functions */
	int (*cb_delete_context) (struct pdp_t *);
	int (*cb_create_context_ind) (struct pdp_t *);
	int (*cb_unsup_ind) (struct sockaddr_in * peer);
	int (*cb_extheader_ind) (struct sockaddr_in * peer);
	int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
	int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
	int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
	int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
	int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery);
	int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
	int (*cb_sgsn_context_request_ind) (struct gsn_t *gsn, struct sockaddr_in *peer, const struct osmo_routing_area_id *rai, uint32_t teic, struct osmo_mobile_identity *mi, union gtpie_member **ie); /* Pass RAI and TLLI/TMSI/IMSI directly */

	/* Counters */
	struct rate_ctr_group *ctrg;

	/* Timers: */
	struct osmo_tdef *tdef;
};

/* External API functions */

extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
		   int mode);

extern int gtp_free(struct gsn_t *gsn);

extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
		      uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);

extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
				  void *cbp);

extern int gtp_create_sgsn_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp);

extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
					 int (*cb_create_context_ind) (struct
								       pdp_t *
								       pdp));
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
			       int (*cb_data_ind) (struct pdp_t * pdp,
						   void *pack, unsigned len));
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
				     int (*cb_delete_context) (struct pdp_t *
							       pdp));
/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
  int (*cb_create_context) (struct pdp_t* pdp)); */

extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
				int (*cb) (struct sockaddr_in * peer));

extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
				    int (*cb) (struct sockaddr_in * peer));

extern int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
				    int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie));

extern int gtp_set_cb_sgsn_context_request_ind(struct gsn_t *gsn,
			     int (*cb) (struct gsn_t *gsn, struct sockaddr_in *peer, const struct osmo_routing_area_id *rai, uint32_t teic, struct osmo_mobile_identity *mi, union gtpie_member **ie));

extern int gtp_set_cb_conf(struct gsn_t *gsn,
			   int (*cb) (int type, int cause, struct pdp_t * pdp,
				      void *cbp));

int gtp_set_cb_recovery(struct gsn_t *gsn,
			int (*cb) (struct sockaddr_in * peer,
				   uint8_t recovery))
	OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery");
int gtp_set_cb_recovery2(struct gsn_t *gsn,
			int (*cb) (struct sockaddr_in * peer,
				   struct pdp_t * pdp,
				   uint8_t recovery))
	OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");
int gtp_set_cb_recovery3(struct gsn_t *gsn,
			int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer,
				   struct pdp_t * pdp,
				   uint8_t recovery));
void gtp_clear_queues(struct gsn_t *gsn);
extern int gtp_fd(struct gsn_t *gsn);

extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout");

/* Internal APIs: */
void gtp_queue_timer_start(struct gsn_t *gsn);

#endif /* !_GSN_H */