blob: 0e4f71c42baeee9d78fa093b973f0299484919fb [file] [log] [blame]
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +01001/*
2 * OsmoGGSN - Gateway GPRS Support Node
3 * Copyright (C) 2002, 2003, 2004 Mondru AB.
4 *
5 * The contents of this file may be used under the terms of the GNU
6 * General Public License Version 2, provided that the above copyright
7 * notice and this permission notice is included in all copies or
8 * substantial portions of the software.
9 *
10 */
11
12#ifndef _GSN_H
13#define _GSN_H
14
15#include <osmocom/core/utils.h>
16#include <osmocom/core/defs.h>
17#include <osmocom/core/timer.h>
Pau Espin Pedrol9f1f7472022-11-02 19:52:19 +010018#include <osmocom/core/tdef.h>
Pau Espin Pedrolb9036af2022-11-02 18:17:56 +010019#include <osmocom/core/rate_ctr.h>
Daniel Willmann65363762024-01-26 16:36:20 +010020#include <osmocom/gsm/gsm23003.h>
21#include <osmocom/gsm/gsm48.h>
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +010022
23#include "pdp.h"
24
25#define GTP_MODE_GGSN 1
26#define GTP_MODE_SGSN 2
27
28#define RESTART_FILE "gsn_restart"
29
Pau Espin Pedrol9f1f7472022-11-02 19:52:19 +010030extern struct osmo_tdef gtp_T_defs[];
31
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +010032/* ***********************************************************
33 * Information storage for each gsn instance
34 *
35 * Normally each instance of the application corresponds to
36 * one instance of a gsn.
37 *
38 * In order to avoid global variables in the application, and
39 * also in order to allow several instances of a gsn in the same
40 * application this struct is provided in order to store all
41 * relevant information related to the gsn.
42 *
43 * Note that this does not include information storage for '
44 * each pdp context. This is stored in another struct.
45 *************************************************************/
46
Pau Espin Pedrolb9036af2022-11-02 18:17:56 +010047enum gsn_rate_ctr_keys {
48 GSN_CTR_ERR_SOCKET,
49 GSN_CTR_ERR_READFROM, /* Number of readfrom errors */
50 GSN_CTR_ERR_SENDTO, /* Number of sendto errors */
51 GSN_CTR_ERR_QUEUEFULL, /* Number of times queue was full */
52 GSN_CTR_ERR_SEQ, /* Number of seq out of range */
53 GSN_CTR_ERR_ADDRESS, /* GSN address conversion failed */
54 GSN_CTR_ERR_UNKNOWN_PDP, /* GSN address conversion failed */
55 GSN_CTR_ERR_UNEXPECTED_CAUSE, /* Unexpected cause value received */
56 GSN_CTR_ERR_OUT_OF_PDP, /* Out of storage for PDP contexts */
57 GSN_CTR_PKT_EMPTY, /* Number of empty packets */
58 GSN_CTR_PKT_UNSUP, /* Number of unsupported version 29.60 11.1.1 */
59 GSN_CTR_PKT_TOOSHORT, /* Number of too short headers 29.60 11.1.2 */
60 GSN_CTR_PKT_UNKNOWN, /* Number of unknown messages 29.60 11.1.3 */
61 GSN_CTR_PKT_UNEXPECT, /* Number of unexpected messages 29.60 11.1.4 */
62 GSN_CTR_PKT_DUPLICATE, /* Number of duplicate or unsolicited replies */
63 GSN_CTR_PKT_MISSING, /* Number of missing information field messages */
64 GSN_CTR_PKT_INCORRECT, /* Number of incorrect information field messages */
65 GSN_CTR_PKT_INVALID, /* Number of invalid message format messages */
66};
67
Pau Espin Pedrol9f1f7472022-11-02 19:52:19 +010068/* 3GPP TS 29.006 14.1, 14,2 */
69enum gtp_gsn_timers {
70 GTP_GSN_TIMER_T3_RESPONSE = 3,
71 GTP_GSN_TIMER_N3_REQUESTS = 1003,
Pau Espin Pedrol3a55b892022-11-04 11:21:23 +010072 GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3,
Pau Espin Pedrol9f1f7472022-11-02 19:52:19 +010073};
74
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +010075struct gsn_t {
76 /* Parameters related to the network interface */
77
78 int fd0; /* GTP0 file descriptor */
79 int fd1c; /* GTP1 control plane file descriptor */
80 int fd1u; /* GTP0 user plane file descriptor */
81 int mode; /* Mode of operation: GGSN or SGSN */
Oliver Smith9bd27112024-02-22 16:02:37 +010082 struct in_addr gsnc; /* IP address of this gsn for signalling */
83 struct in_addr gsnu; /* IP address of this gsn for user traffic */
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +010084
85 /* Parameters related to signalling messages */
86 uint16_t seq_next; /* Next sequence number to use */
87 int seq_first; /* First packet in queue (oldest timeout) */
88 int seq_last; /* Last packet in queue (youngest timeout) */
89
90 unsigned char restart_counter; /* Increment on restart. Stored on disk */
91 char *statedir; /* Disk location for permanent storage */
92 void *priv; /* used by libgtp users to attach their own state) */
93 struct queue_t *queue_req; /* Request queue */
94 struct queue_t *queue_resp; /* Response queue */
95
96 struct pdp_t pdpa[PDP_MAX]; /* PDP storage */
97 struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */
98
99 struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */
100
101 /* Call back functions */
102 int (*cb_delete_context) (struct pdp_t *);
103 int (*cb_create_context_ind) (struct pdp_t *);
104 int (*cb_unsup_ind) (struct sockaddr_in * peer);
105 int (*cb_extheader_ind) (struct sockaddr_in * peer);
106 int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
107 int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
108 int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
109 int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
110 int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery);
111 int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
Daniel Willmann54fcd642024-03-06 11:53:37 +0100112 int (*cb_sgsn_context_request_ind) (struct gsn_t *gsn, struct sockaddr_in *peer, uint16_t seq, 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 */
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +0100113
114 /* Counters */
Pau Espin Pedrolb9036af2022-11-02 18:17:56 +0100115 struct rate_ctr_group *ctrg;
Pau Espin Pedrol9f1f7472022-11-02 19:52:19 +0100116
117 /* Timers: */
118 struct osmo_tdef *tdef;
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +0100119};
120
121/* External API functions */
122
Oliver Smith9bd27112024-02-22 16:02:37 +0100123extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
124 int mode);
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +0100125
126extern int gtp_free(struct gsn_t *gsn);
127
128extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
129 uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
130extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
131extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);
132
133extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
134 void *cbp);
135
Daniel Willmann65363762024-01-26 16:36:20 +0100136extern int gtp_create_sgsn_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp);
137
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +0100138extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
139 int (*cb_create_context_ind) (struct
140 pdp_t *
141 pdp));
142extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
143 int (*cb_data_ind) (struct pdp_t * pdp,
144 void *pack, unsigned len));
145extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
146 int (*cb_delete_context) (struct pdp_t *
147 pdp));
148/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
149 int (*cb_create_context) (struct pdp_t* pdp)); */
150
151extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
152 int (*cb) (struct sockaddr_in * peer));
153
154extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
155 int (*cb) (struct sockaddr_in * peer));
156
157extern int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
158 int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie));
159
Daniel Willmann65363762024-01-26 16:36:20 +0100160extern int gtp_set_cb_sgsn_context_request_ind(struct gsn_t *gsn,
Daniel Willmann54fcd642024-03-06 11:53:37 +0100161 int (*cb) (struct gsn_t *gsn, struct sockaddr_in *peer, uint16_t seq, const struct osmo_routing_area_id *rai, uint32_t teic, struct osmo_mobile_identity *mi, union gtpie_member **ie));
Daniel Willmann65363762024-01-26 16:36:20 +0100162
Pau Espin Pedrol724ecc62022-11-02 14:57:24 +0100163extern int gtp_set_cb_conf(struct gsn_t *gsn,
164 int (*cb) (int type, int cause, struct pdp_t * pdp,
165 void *cbp));
166
167int gtp_set_cb_recovery(struct gsn_t *gsn,
168 int (*cb) (struct sockaddr_in * peer,
169 uint8_t recovery))
170 OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery");
171int gtp_set_cb_recovery2(struct gsn_t *gsn,
172 int (*cb) (struct sockaddr_in * peer,
173 struct pdp_t * pdp,
174 uint8_t recovery))
175 OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");
176int gtp_set_cb_recovery3(struct gsn_t *gsn,
177 int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer,
178 struct pdp_t * pdp,
179 uint8_t recovery));
180void gtp_clear_queues(struct gsn_t *gsn);
181extern int gtp_fd(struct gsn_t *gsn);
182
183extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
184extern 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");
185
186/* Internal APIs: */
187void gtp_queue_timer_start(struct gsn_t *gsn);
188
189#endif /* !_GSN_H */