Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 1 | /* |
| 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 Pedrol | 9f1f747 | 2022-11-02 19:52:19 +0100 | [diff] [blame] | 18 | #include <osmocom/core/tdef.h> |
Pau Espin Pedrol | b9036af | 2022-11-02 18:17:56 +0100 | [diff] [blame] | 19 | #include <osmocom/core/rate_ctr.h> |
Daniel Willmann | 6536376 | 2024-01-26 16:36:20 +0100 | [diff] [blame] | 20 | #include <osmocom/gsm/gsm23003.h> |
| 21 | #include <osmocom/gsm/gsm48.h> |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 22 | |
| 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 Pedrol | 9f1f747 | 2022-11-02 19:52:19 +0100 | [diff] [blame] | 30 | extern struct osmo_tdef gtp_T_defs[]; |
| 31 | |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 32 | /* *********************************************************** |
| 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 Pedrol | b9036af | 2022-11-02 18:17:56 +0100 | [diff] [blame] | 47 | enum 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 Pedrol | 9f1f747 | 2022-11-02 19:52:19 +0100 | [diff] [blame] | 68 | /* 3GPP TS 29.006 14.1, 14,2 */ |
| 69 | enum gtp_gsn_timers { |
| 70 | GTP_GSN_TIMER_T3_RESPONSE = 3, |
| 71 | GTP_GSN_TIMER_N3_REQUESTS = 1003, |
Pau Espin Pedrol | 3a55b89 | 2022-11-04 11:21:23 +0100 | [diff] [blame] | 72 | GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3, |
Pau Espin Pedrol | 9f1f747 | 2022-11-02 19:52:19 +0100 | [diff] [blame] | 73 | }; |
| 74 | |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 75 | struct 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 Smith | 9bd2711 | 2024-02-22 16:02:37 +0100 | [diff] [blame] | 82 | 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 Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 84 | |
| 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 Willmann | 54fcd64 | 2024-03-06 11:53:37 +0100 | [diff] [blame] | 112 | 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 Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 113 | |
| 114 | /* Counters */ |
Pau Espin Pedrol | b9036af | 2022-11-02 18:17:56 +0100 | [diff] [blame] | 115 | struct rate_ctr_group *ctrg; |
Pau Espin Pedrol | 9f1f747 | 2022-11-02 19:52:19 +0100 | [diff] [blame] | 116 | |
| 117 | /* Timers: */ |
| 118 | struct osmo_tdef *tdef; |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 119 | }; |
| 120 | |
| 121 | /* External API functions */ |
| 122 | |
Oliver Smith | 9bd2711 | 2024-02-22 16:02:37 +0100 | [diff] [blame] | 123 | extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen, |
| 124 | int mode); |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 125 | |
| 126 | extern int gtp_free(struct gsn_t *gsn); |
| 127 | |
| 128 | extern 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"); |
| 130 | extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp); |
| 131 | extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp); |
| 132 | |
| 133 | extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp, |
| 134 | void *cbp); |
| 135 | |
Daniel Willmann | 6536376 | 2024-01-26 16:36:20 +0100 | [diff] [blame] | 136 | extern int gtp_create_sgsn_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp); |
| 137 | |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 138 | extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn, |
| 139 | int (*cb_create_context_ind) (struct |
| 140 | pdp_t * |
| 141 | pdp)); |
| 142 | extern int gtp_set_cb_data_ind(struct gsn_t *gsn, |
| 143 | int (*cb_data_ind) (struct pdp_t * pdp, |
| 144 | void *pack, unsigned len)); |
| 145 | extern 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 | |
| 151 | extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn, |
| 152 | int (*cb) (struct sockaddr_in * peer)); |
| 153 | |
| 154 | extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn, |
| 155 | int (*cb) (struct sockaddr_in * peer)); |
| 156 | |
| 157 | extern 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 Willmann | 6536376 | 2024-01-26 16:36:20 +0100 | [diff] [blame] | 160 | extern int gtp_set_cb_sgsn_context_request_ind(struct gsn_t *gsn, |
Daniel Willmann | 54fcd64 | 2024-03-06 11:53:37 +0100 | [diff] [blame] | 161 | 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 Willmann | 6536376 | 2024-01-26 16:36:20 +0100 | [diff] [blame] | 162 | |
Pau Espin Pedrol | 724ecc6 | 2022-11-02 14:57:24 +0100 | [diff] [blame] | 163 | extern int gtp_set_cb_conf(struct gsn_t *gsn, |
| 164 | int (*cb) (int type, int cause, struct pdp_t * pdp, |
| 165 | void *cbp)); |
| 166 | |
| 167 | int 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"); |
| 171 | int 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"); |
| 176 | int 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)); |
| 180 | void gtp_clear_queues(struct gsn_t *gsn); |
| 181 | extern int gtp_fd(struct gsn_t *gsn); |
| 182 | |
| 183 | extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally"); |
| 184 | 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"); |
| 185 | |
| 186 | /* Internal APIs: */ |
| 187 | void gtp_queue_timer_start(struct gsn_t *gsn); |
| 188 | |
| 189 | #endif /* !_GSN_H */ |