blob: fc5708d3223792f783d64ef4a73bae3ec2d7566c [file] [log] [blame]
Harald Weltef7365592020-04-15 21:48:45 +02001/* SPDX-License-Identifier: GPL-2.0 */
2#pragma once
3
4#include <stdint.h>
5#include <stdbool.h>
6#include <pthread.h>
7#include <sys/socket.h>
8#include <osmocom/core/linuxlist.h>
9#include <osmocom/core/write_queue.h>
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +020010#include <osmocom/core/it_q.h>
Harald Weltef7365592020-04-15 21:48:45 +020011#include <osmocom/core/utils.h>
12
13struct nl_sock;
14struct osmo_stream_srv_link;
15
16/***********************************************************************
17 * Utility
18 ***********************************************************************/
19/* ensure we are called from main thread context */
20#define ASSERT_MAIN_THREAD(d) OSMO_ASSERT(pthread_self() == (d)->main_thread)
21
22#define MAX_UDP_PACKET 65535
23
24bool sockaddr_equals(const struct sockaddr *a, const struct sockaddr *b);
25
26struct addrinfo *addrinfo_helper(uint16_t family, uint16_t type, uint8_t proto,
27 const char *host, uint16_t port, bool passive);
28enum {
29 DTUN,
30 DEP,
31 DGT,
32 DUECUPS,
33};
34
35/***********************************************************************
36 * netdev / netlink
37 ***********************************************************************/
38
39int netdev_add_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss);
40int netdev_del_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss);
41int netdev_set_link(struct nl_sock *nlsk, int ifindex, bool up);
42int netdev_add_defaultroute(struct nl_sock *nlsk, int ifindex, uint8_t family);
43
44
45/***********************************************************************
46 * GTP Endpoint (UDP socket)
47 ***********************************************************************/
48
49struct gtp_daemon;
50
51/* local UDP socket for GTP communication */
52struct gtp_endpoint {
53 /* entry in global list */
54 struct llist_head list;
55 /* back-pointer to daemon */
56 struct gtp_daemon *d;
57 unsigned long use_count;
58
59 /* file descriptor */
60 int fd;
61
62 /* local IP:port */
63 struct sockaddr_storage bind_addr;
64 char *name;
65
66 /* the thread handling Rx from the fd/socket */
67 pthread_t thread;
68};
69
70
71struct gtp_endpoint *
72gtp_endpoint_find_or_create(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr);
73
74struct gtp_endpoint *
75_gtp_endpoint_find(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr);
76
77void _gtp_endpoint_deref_destroy(struct gtp_endpoint *ep);
78
79bool _gtp_endpoint_release(struct gtp_endpoint *ep);
80
81bool gtp_endpoint_release(struct gtp_endpoint *ep);
82
83
84
85/***********************************************************************
86 * TUN Device
87 ***********************************************************************/
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +020088/* Message sent tun thread -> main thread through osmo_itq */
89struct gtp_daemon_itq_msg {
90 struct llist_head list;
91 struct {
92 struct tun_device *tun;
93 } tun_released; /* tun became stopped and can be freed */
94};
Harald Weltef7365592020-04-15 21:48:45 +020095
96struct tun_device {
97 /* entry in global list */
98 struct llist_head list;
99 /* back-pointer to daemon */
100 struct gtp_daemon *d;
101 unsigned long use_count;
102
103 /* which device we refer to */
104 const char *devname;
105 int ifindex;
106
107 /* file descriptor */
108 int fd;
109
110 /* network namespace */
111 const char *netns_name;
112 int netns_fd;
113
114 /* netlink socket in the namespace of the tun device */
115 struct nl_sock *nl;
116
117 /* list of local addresses? or simply only have the kernel know thses? */
118
119 /* the thread handling Rx from the tun fd */
120 pthread_t thread;
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200121
122 /* Used to store messages to be sent to main thread, since tun thread doesn't allocate through talloc */
123 struct gtp_daemon_itq_msg itq_msg;
Harald Weltef7365592020-04-15 21:48:45 +0200124};
125
126struct tun_device *
127tun_device_find_or_create(struct gtp_daemon *d, const char *devname, const char *netns_name);
128
129struct tun_device *
Harald Welte24557a72020-04-17 22:08:29 +0200130tun_device_find_netns(struct gtp_daemon *d, const char *netns_name);
131
132struct tun_device *
Harald Weltef7365592020-04-15 21:48:45 +0200133_tun_device_find(struct gtp_daemon *d, const char *devname);
134
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200135void _tun_device_destroy(struct tun_device *tun);
Harald Weltef7365592020-04-15 21:48:45 +0200136
137bool _tun_device_release(struct tun_device *tun);
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200138void _tun_device_deref_release(struct tun_device *tun);
Harald Weltef7365592020-04-15 21:48:45 +0200139
140bool tun_device_release(struct tun_device *tun);
141
142
143
144/***********************************************************************
145 * GTP Tunnel
146 ***********************************************************************/
147
148/* Every tunnel is identified uniquely by the following tuples:
149 *
150 * a) local endpoint + TEID
151 * this is what happens on incoming GTP messages
152 *
153 * b) tun device + end-user-address (+ filter, if any)
154 * this is what happens when IP arrives on the tun device
155 */
156
157struct gtp_tunnel {
158 /* entry in global list / hash table */
159 struct llist_head list;
160 /* back-pointer to daemon */
161 struct gtp_daemon *d;
162
163 const char *name;
164
165 /* the TUN device associated with this tunnel */
166 struct tun_device *tun_dev;
167 /* the GTP endpoint (UDP socket) associated with this tunnel */
168 struct gtp_endpoint *gtp_ep;
169
170 /* TEID on transmit (host byte order) */
171 uint32_t tx_teid;
172 /* TEID one receive (host byte order) */
173 uint32_t rx_teid;
174
175 /* End user Address (inner IP) */
176 struct sockaddr_storage user_addr;
177
178 /* Remote UDP IP/Port*/
179 struct sockaddr_storage remote_udp;
180
181 /* TODO: Filter */
182};
183
184struct gtp_tunnel *
185_gtp_tunnel_find_r(struct gtp_daemon *d, uint32_t rx_teid, struct gtp_endpoint *ep);
186
187struct gtp_tunnel *
188_gtp_tunnel_find_eua(struct tun_device *tun, const struct sockaddr *sa, uint8_t proto);
189
190struct gtp_tunnel_params {
191 /* TEID in receive and transmit direction */
192 uint32_t rx_teid;
193 uint32_t tx_teid;
194
195 /* end user address */
196 struct sockaddr_storage user_addr;
197
198 /* remote GTP/UDP IP+Port */
199 struct sockaddr_storage remote_udp;
200
201 /* local GTP/UDP IP+Port (used to lookup/create local EP) */
202 struct sockaddr_storage local_udp;
203
204 /* local TUN device name (used to lookup/create local tun) */
205 const char *tun_name;
206 const char *tun_netns_name;
207};
208struct gtp_tunnel *gtp_tunnel_alloc(struct gtp_daemon *d, const struct gtp_tunnel_params *cpars);
209
210void _gtp_tunnel_destroy(struct gtp_tunnel *t);
211bool gtp_tunnel_destroy(struct gtp_daemon *d, const struct sockaddr_storage *bind_addr, uint32_t rx_teid);
212
213
214/***********************************************************************
215 * GTP Daemon
216 ***********************************************************************/
217
Harald Welte432a1302020-04-17 12:52:40 +0200218#define UECUPS_SCTP_PORT 4268
219
Harald Welte24557a72020-04-17 22:08:29 +0200220struct osmo_signalfd;
221
Harald Weltef7365592020-04-15 21:48:45 +0200222struct gtp_daemon {
223 /* global lists of various objects */
224 struct llist_head gtp_endpoints;
225 struct llist_head tun_devices;
226 struct llist_head gtp_tunnels;
Harald Welte24557a72020-04-17 22:08:29 +0200227 struct llist_head subprocesses;
Harald Weltef7365592020-04-15 21:48:45 +0200228 /* lock protecting all of the above lists */
229 pthread_rwlock_t rwlock;
230 /* main thread ID */
231 pthread_t main_thread;
232 /* client CUPS interface */
233 struct llist_head cups_clients;
234 struct osmo_stream_srv_link *cups_link;
Harald Welte24557a72020-04-17 22:08:29 +0200235 struct osmo_signalfd *signalfd;
Harald Weltef7365592020-04-15 21:48:45 +0200236
Pau Espin Pedrola459b5c2022-04-11 17:00:36 +0200237 /* inter-thread queue between main thread and workers, pass struct gtp_daemon_itq_msg: */
238 struct osmo_it_q *itq;
239
240 /* Number of tunnels in progrress of being released: */
241 unsigned int reset_all_state_tun_remaining;
242
Harald Weltef7365592020-04-15 21:48:45 +0200243 struct {
244 char *cups_local_ip;
245 uint16_t cups_local_port;
246 } cfg;
247};
248extern struct gtp_daemon *g_daemon;
249
250int gtpud_vty_init(void);