blob: 25a8f91238486eba51ae8f472cfdb1da78ea580c [file] [log] [blame]
Harald Weltef7365592020-04-15 21:48:45 +02001/* SPDX-License-Identifier: GPL-2.0 */
2#pragma once
3
Pau Espin Pedrolf9f5b302022-04-12 12:34:25 +02004#include "netns.h"
5
Harald Weltef7365592020-04-15 21:48:45 +02006#include <stdint.h>
7#include <stdbool.h>
8#include <pthread.h>
9#include <sys/socket.h>
Pau Espin Pedrolf9f5b302022-04-12 12:34:25 +020010
11#include <jansson.h>
12
Harald Weltef7365592020-04-15 21:48:45 +020013#include <osmocom/core/linuxlist.h>
14#include <osmocom/core/write_queue.h>
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +020015#include <osmocom/core/it_q.h>
Harald Weltef7365592020-04-15 21:48:45 +020016#include <osmocom/core/utils.h>
Pau Espin Pedrolf9f5b302022-04-12 12:34:25 +020017#include <osmocom/core/socket.h>
18
19#include <osmocom/netif/stream.h>
Harald Weltef7365592020-04-15 21:48:45 +020020
21struct nl_sock;
22struct osmo_stream_srv_link;
23
24/***********************************************************************
25 * Utility
26 ***********************************************************************/
27/* ensure we are called from main thread context */
28#define ASSERT_MAIN_THREAD(d) OSMO_ASSERT(pthread_self() == (d)->main_thread)
29
30#define MAX_UDP_PACKET 65535
31
32bool sockaddr_equals(const struct sockaddr *a, const struct sockaddr *b);
33
34struct addrinfo *addrinfo_helper(uint16_t family, uint16_t type, uint8_t proto,
35 const char *host, uint16_t port, bool passive);
36enum {
37 DTUN,
38 DEP,
39 DGT,
40 DUECUPS,
41};
42
43/***********************************************************************
44 * netdev / netlink
45 ***********************************************************************/
46
47int netdev_add_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss);
48int netdev_del_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss);
49int netdev_set_link(struct nl_sock *nlsk, int ifindex, bool up);
50int netdev_add_defaultroute(struct nl_sock *nlsk, int ifindex, uint8_t family);
51
52
53/***********************************************************************
54 * GTP Endpoint (UDP socket)
55 ***********************************************************************/
56
57struct gtp_daemon;
58
59/* local UDP socket for GTP communication */
60struct gtp_endpoint {
61 /* entry in global list */
62 struct llist_head list;
63 /* back-pointer to daemon */
64 struct gtp_daemon *d;
65 unsigned long use_count;
66
67 /* file descriptor */
68 int fd;
69
70 /* local IP:port */
71 struct sockaddr_storage bind_addr;
72 char *name;
73
74 /* the thread handling Rx from the fd/socket */
75 pthread_t thread;
76};
77
78
79struct gtp_endpoint *
80gtp_endpoint_find_or_create(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr);
81
82struct gtp_endpoint *
83_gtp_endpoint_find(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr);
84
85void _gtp_endpoint_deref_destroy(struct gtp_endpoint *ep);
86
87bool _gtp_endpoint_release(struct gtp_endpoint *ep);
88
89bool gtp_endpoint_release(struct gtp_endpoint *ep);
90
91
92
93/***********************************************************************
94 * TUN Device
95 ***********************************************************************/
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +020096/* Message sent tun thread -> main thread through osmo_itq */
97struct gtp_daemon_itq_msg {
98 struct llist_head list;
99 struct {
100 struct tun_device *tun;
101 } tun_released; /* tun became stopped and can be freed */
102};
Harald Weltef7365592020-04-15 21:48:45 +0200103
104struct tun_device {
105 /* entry in global list */
106 struct llist_head list;
107 /* back-pointer to daemon */
108 struct gtp_daemon *d;
109 unsigned long use_count;
110
111 /* which device we refer to */
112 const char *devname;
113 int ifindex;
114
115 /* file descriptor */
116 int fd;
117
118 /* network namespace */
119 const char *netns_name;
120 int netns_fd;
121
122 /* netlink socket in the namespace of the tun device */
123 struct nl_sock *nl;
124
125 /* list of local addresses? or simply only have the kernel know thses? */
126
127 /* the thread handling Rx from the tun fd */
128 pthread_t thread;
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200129
130 /* Used to store messages to be sent to main thread, since tun thread doesn't allocate through talloc */
131 struct gtp_daemon_itq_msg itq_msg;
Harald Weltef7365592020-04-15 21:48:45 +0200132};
133
134struct tun_device *
135tun_device_find_or_create(struct gtp_daemon *d, const char *devname, const char *netns_name);
136
137struct tun_device *
Harald Welte24557a72020-04-17 22:08:29 +0200138tun_device_find_netns(struct gtp_daemon *d, const char *netns_name);
139
140struct tun_device *
Harald Weltef7365592020-04-15 21:48:45 +0200141_tun_device_find(struct gtp_daemon *d, const char *devname);
142
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200143void _tun_device_destroy(struct tun_device *tun);
Harald Weltef7365592020-04-15 21:48:45 +0200144
145bool _tun_device_release(struct tun_device *tun);
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200146void _tun_device_deref_release(struct tun_device *tun);
Harald Weltef7365592020-04-15 21:48:45 +0200147
148bool tun_device_release(struct tun_device *tun);
149
150
Pau Espin Pedrolf9f5b302022-04-12 12:34:25 +0200151/***********************************************************************
152 * Client (Control/User Plane Separation) Socket
153 ***********************************************************************/
154
155struct cups_client {
156 /* member in daemon->cups_clients */
157 struct llist_head list;
158 /* back-pointer to daemon */
159 struct gtp_daemon *d;
160 /* client socket */
161 struct osmo_stream_srv *srv;
162 char sockname[OSMO_SOCK_NAME_MAXLEN];
163 bool reset_all_state_res_pending;
164};
165
166struct osmo_stream_srv_link *cups_srv_link_create(struct gtp_daemon *d);
167void child_terminated(struct gtp_daemon *d, int pid, int status);
168json_t *gen_uecups_result(const char *name, const char *res);
169int cups_client_tx_json(struct cups_client *cc, json_t *jtx);
Harald Weltef7365592020-04-15 21:48:45 +0200170
171/***********************************************************************
172 * GTP Tunnel
173 ***********************************************************************/
174
175/* Every tunnel is identified uniquely by the following tuples:
176 *
177 * a) local endpoint + TEID
178 * this is what happens on incoming GTP messages
179 *
180 * b) tun device + end-user-address (+ filter, if any)
181 * this is what happens when IP arrives on the tun device
182 */
183
184struct gtp_tunnel {
185 /* entry in global list / hash table */
186 struct llist_head list;
187 /* back-pointer to daemon */
188 struct gtp_daemon *d;
189
190 const char *name;
191
192 /* the TUN device associated with this tunnel */
193 struct tun_device *tun_dev;
194 /* the GTP endpoint (UDP socket) associated with this tunnel */
195 struct gtp_endpoint *gtp_ep;
196
197 /* TEID on transmit (host byte order) */
198 uint32_t tx_teid;
199 /* TEID one receive (host byte order) */
200 uint32_t rx_teid;
201
202 /* End user Address (inner IP) */
203 struct sockaddr_storage user_addr;
204
205 /* Remote UDP IP/Port*/
206 struct sockaddr_storage remote_udp;
207
208 /* TODO: Filter */
209};
210
211struct gtp_tunnel *
212_gtp_tunnel_find_r(struct gtp_daemon *d, uint32_t rx_teid, struct gtp_endpoint *ep);
213
214struct gtp_tunnel *
215_gtp_tunnel_find_eua(struct tun_device *tun, const struct sockaddr *sa, uint8_t proto);
216
217struct gtp_tunnel_params {
218 /* TEID in receive and transmit direction */
219 uint32_t rx_teid;
220 uint32_t tx_teid;
221
222 /* end user address */
223 struct sockaddr_storage user_addr;
224
225 /* remote GTP/UDP IP+Port */
226 struct sockaddr_storage remote_udp;
227
228 /* local GTP/UDP IP+Port (used to lookup/create local EP) */
229 struct sockaddr_storage local_udp;
230
231 /* local TUN device name (used to lookup/create local tun) */
232 const char *tun_name;
233 const char *tun_netns_name;
234};
235struct gtp_tunnel *gtp_tunnel_alloc(struct gtp_daemon *d, const struct gtp_tunnel_params *cpars);
236
237void _gtp_tunnel_destroy(struct gtp_tunnel *t);
238bool gtp_tunnel_destroy(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr, uint32_t rx_teid);
239
240
241/***********************************************************************
242 * GTP Daemon
243 ***********************************************************************/
244
Harald Welte432a1302020-04-17 12:52:40 +0200245#define UECUPS_SCTP_PORT 4268
246
Harald Welte24557a72020-04-17 22:08:29 +0200247struct osmo_signalfd;
248
Harald Weltef7365592020-04-15 21:48:45 +0200249struct gtp_daemon {
250 /* global lists of various objects */
251 struct llist_head gtp_endpoints;
252 struct llist_head tun_devices;
253 struct llist_head gtp_tunnels;
Harald Welte24557a72020-04-17 22:08:29 +0200254 struct llist_head subprocesses;
Harald Weltef7365592020-04-15 21:48:45 +0200255 /* lock protecting all of the above lists */
256 pthread_rwlock_t rwlock;
257 /* main thread ID */
258 pthread_t main_thread;
259 /* client CUPS interface */
260 struct llist_head cups_clients;
261 struct osmo_stream_srv_link *cups_link;
Harald Welte24557a72020-04-17 22:08:29 +0200262 struct osmo_signalfd *signalfd;
Harald Weltef7365592020-04-15 21:48:45 +0200263
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200264 /* inter-thread queue between main thread and workers, pass struct gtp_daemon_itq_msg: */
265 struct osmo_it_q *itq;
266
267 /* Number of tunnels in progrress of being released: */
268 unsigned int reset_all_state_tun_remaining;
269
Harald Weltef7365592020-04-15 21:48:45 +0200270 struct {
271 char *cups_local_ip;
272 uint16_t cups_local_port;
273 } cfg;
274};
275extern struct gtp_daemon *g_daemon;
276
Pau Espin Pedrolf9f5b302022-04-12 12:34:25 +0200277struct gtp_daemon *gtp_daemon_alloc(void *ctx);
278
Harald Weltef7365592020-04-15 21:48:45 +0200279int gtpud_vty_init(void);