aboutsummaryrefslogtreecommitdiffstats
path: root/src/gtphub/gtphub.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtphub/gtphub.c')
-rw-r--r--src/gtphub/gtphub.c146
1 files changed, 66 insertions, 80 deletions
diff --git a/src/gtphub/gtphub.c b/src/gtphub/gtphub.c
index ca5857b39..937e6a4ff 100644
--- a/src/gtphub/gtphub.c
+++ b/src/gtphub/gtphub.c
@@ -32,7 +32,7 @@
#include <gtp.h>
#include <gtpie.h>
-#include <osmocom/sgsn/gtphub.h>
+#include <osmocom/gtphub/gtphub.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gprs_utils.h>
@@ -59,15 +59,6 @@ void *osmo_gtphub_ctx;
/* TODO move this to osmocom/core/select.h ? */
typedef int (*osmo_fd_cb_t)(struct osmo_fd *fd, unsigned int what);
-/* TODO move this to osmocom/core/linuxlist.h ? */
-#define __llist_first(head) (((head)->next == (head)) ? NULL : (head)->next)
-#define llist_first(head, type, entry) \
- llist_entry(__llist_first(head), type, entry)
-
-#define __llist_last(head) (((head)->next == (head)) ? NULL : (head)->prev)
-#define llist_last(head, type, entry) \
- llist_entry(__llist_last(head), type, entry)
-
/* TODO move GTP header stuff to openggsn/gtp/ ? See gtp_decaps*() */
enum gtp_rc {
@@ -167,12 +158,12 @@ void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src)
}
int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port,
- const struct osmo_sockaddr *sa)
+ const struct sgsn_sockaddr *sa)
{
char addr_str[256];
char port_str[6];
- if (osmo_sockaddr_to_strs(addr_str, sizeof(addr_str),
+ if (sgsn_sockaddr_to_strs(addr_str, sizeof(addr_str),
port_str, sizeof(port_str),
sa, (NI_NUMERICHOST | NI_NUMERICSERV))
!= 0) {
@@ -484,7 +475,7 @@ static int get_ie_imsi_str(union gtpie_member *ie[], int i,
* present but cannot be decoded. */
static int get_ie_apn_str(union gtpie_member *ie[], const char **apn_str)
{
- static char apn_buf[GSM_APN_LENGTH];
+ static char apn_buf[APN_MAXLEN+1];
unsigned int len;
if (gtpie_gettlv(ie, GTPIE_APN, 0,
&len, apn_buf, sizeof(apn_buf)) != 0)
@@ -613,7 +604,7 @@ void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now)
OSMO_ASSERT(llist_empty(&exq->items)
|| (item->expiry
- >= llist_last(&exq->items, struct expiring_item, entry)->expiry));
+ >= llist_last_entry(&exq->items, struct expiring_item, entry)->expiry));
/* Add/move to the tail to always sort by expiry, ascending. */
llist_del(&item->entry);
@@ -853,10 +844,7 @@ static int gtphub_sock_init(struct osmo_fd *ofd,
return -1;
}
- ofd->when = BSC_FD_READ;
- ofd->cb = cb;
- ofd->data = data;
- ofd->priv_nr = ofd_id;
+ osmo_fd_setup(ofd, -1, OSMO_FD_READ, cb, data, ofd_id);
int rc;
rc = osmo_sock_init_ofd(ofd,
@@ -925,7 +913,7 @@ static void gtphub_bind_stop(struct gtphub_bind *b) {
/* Recv datagram from from->fd, write sender's address to *from_addr.
* Return the number of bytes read, zero on error. */
static int gtphub_read(const struct osmo_fd *from,
- struct osmo_sockaddr *from_addr,
+ struct sgsn_sockaddr *from_addr,
uint8_t *buf, size_t buf_len)
{
OSMO_ASSERT(from_addr);
@@ -946,7 +934,7 @@ static int gtphub_read(const struct osmo_fd *from,
}
LOG(LOGL_DEBUG, "Received %d bytes from %s: %s%s\n",
- (int)received, osmo_sockaddr_to_str(from_addr),
+ (int)received, sgsn_sockaddr_to_str(from_addr),
osmo_hexdump(buf, received > 1000? 1000 : received),
received > 1000 ? "..." : "");
@@ -983,7 +971,7 @@ static inline void set_tei(struct gtp_packet_desc *p, uint32_t tei)
static void gtphub_mapping_del_cb(struct expiring_item *expi);
-static struct nr_mapping *gtphub_mapping_new()
+static struct nr_mapping *gtphub_mapping_new(void)
{
struct nr_mapping *nrm;
nrm = talloc_zero(osmo_gtphub_ctx, struct nr_mapping);
@@ -1007,7 +995,7 @@ static const char *gtphub_tunnel_side_str(struct gtphub_tunnel *tun,
char *pos = buf;
int left = sizeof(buf);
int l;
-
+
struct gtphub_tunnel_endpoint *c, *u;
c = &tun->endpoint[side_idx][GTPH_PLANE_CTRL];
u = &tun->endpoint[side_idx][GTPH_PLANE_USER];
@@ -1116,7 +1104,7 @@ static void gtphub_tunnel_del_cb(struct expiring_item *expi)
/* rate counter index for hubs: [7; 10] */
#define CTR_IDX_HUB(s, p) CTR_IDX(s, p, 3, 2)
-static struct gtphub_tunnel *gtphub_tunnel_new()
+static struct gtphub_tunnel *gtphub_tunnel_new(void)
{
struct gtphub_tunnel *tun;
tun = talloc_zero(osmo_gtphub_ctx, struct gtphub_tunnel);
@@ -1145,9 +1133,7 @@ static const char *gtphub_peer_strb(struct gtphub_peer *peer, char *buf,
if (llist_empty(&peer->addresses))
return "(addressless)";
- struct gtphub_peer_addr *a = llist_first(&peer->addresses,
- struct gtphub_peer_addr,
- entry);
+ struct gtphub_peer_addr *a = llist_first_entry_or_null(&peer->addresses, struct gtphub_peer_addr, entry);
return gsn_addr_to_strb(&a->addr, buf, buflen);
}
@@ -1948,14 +1934,14 @@ static int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what)
LOG(LOGL_DEBUG, "=== reading from SGSN (%s)\n",
gtphub_plane_idx_names[plane_idx]);
- if (!(what & BSC_FD_READ))
+ if (!(what & OSMO_FD_READ))
return 0;
struct gtphub *hub = from_sgsns_ofd->data;
static uint8_t buf[4096];
- struct osmo_sockaddr from_addr;
- struct osmo_sockaddr to_addr;
+ struct sgsn_sockaddr from_addr;
+ struct sgsn_sockaddr to_addr;
struct osmo_fd *to_ofd;
int len;
uint8_t *reply_buf;
@@ -1979,14 +1965,14 @@ static int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what)
OSMO_ASSERT(plane_idx < GTPH_PLANE_N);
LOG(LOGL_DEBUG, "=== reading from GGSN (%s)\n",
gtphub_plane_idx_names[plane_idx]);
- if (!(what & BSC_FD_READ))
+ if (!(what & OSMO_FD_READ))
return 0;
struct gtphub *hub = from_ggsns_ofd->data;
static uint8_t buf[4096];
- struct osmo_sockaddr from_addr;
- struct osmo_sockaddr to_addr;
+ struct sgsn_sockaddr from_addr;
+ struct sgsn_sockaddr to_addr;
struct osmo_fd *to_ofd;
int len;
uint8_t *reply_buf;
@@ -2071,9 +2057,9 @@ static int gtphub_unmap(struct gtphub *hub,
static int gsn_addr_to_sockaddr(struct gsn_addr *src,
uint16_t port,
- struct osmo_sockaddr *dst)
+ struct sgsn_sockaddr *dst)
{
- return osmo_sockaddr_init_udp(dst, gsn_addr_to_str(src), port);
+ return sgsn_sockaddr_init_udp(dst, gsn_addr_to_str(src), port);
}
/* If p is an Echo request, replace p's data with the matching response and
@@ -2107,7 +2093,7 @@ static int gtphub_handle_echo_req(struct gtphub *hub, struct gtp_packet_desc *p,
}
struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind,
- const struct osmo_sockaddr *addr);
+ const struct sgsn_sockaddr *addr);
/* Parse buffer as GTP packet, replace elements in-place and return the ofd and
* address to forward to. Return a pointer to the osmo_fd, but copy the
@@ -2117,18 +2103,18 @@ struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *b
int gtphub_handle_buf(struct gtphub *hub,
unsigned int side_idx,
unsigned int plane_idx,
- const struct osmo_sockaddr *from_addr,
+ const struct sgsn_sockaddr *from_addr,
uint8_t *buf,
size_t received,
time_t now,
uint8_t **reply_buf,
struct osmo_fd **to_ofd,
- struct osmo_sockaddr *to_addr)
+ struct sgsn_sockaddr *to_addr)
{
struct gtphub_bind *from_bind = &hub->to_gsns[side_idx][plane_idx];
struct gtphub_bind *to_bind = &hub->to_gsns[other_side_idx(side_idx)][plane_idx];
- rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_IN],
+ rate_ctr_add(rate_ctr_group_get_ctr(from_bind->counters_io, GTPH_CTR_BYTES_IN),
received);
struct gtp_packet_desc p;
@@ -2138,7 +2124,7 @@ int gtphub_handle_buf(struct gtphub *hub,
(side_idx == GTPH_SIDE_GGSN)? "<-" : "->",
gtphub_plane_idx_names[plane_idx],
gtphub_side_idx_names[side_idx],
- osmo_sockaddr_to_str(from_addr),
+ sgsn_sockaddr_to_str(from_addr),
gtp_type_str(p.type));
if (p.rc <= 0) {
@@ -2146,26 +2132,26 @@ int gtphub_handle_buf(struct gtphub *hub,
gtp_type_str(p.type),
gtphub_side_idx_names[side_idx],
gtphub_plane_idx_names[plane_idx],
- osmo_sockaddr_to_str(from_addr));
+ sgsn_sockaddr_to_str(from_addr));
return -1;
}
- rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_IN]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(from_bind->counters_io, GTPH_CTR_PKTS_IN));
int reply_len;
reply_len = gtphub_handle_echo_req(hub, &p, reply_buf);
if (reply_len > 0) {
/* It was an echo. Nothing left to do. */
- osmo_sockaddr_copy(to_addr, from_addr);
+ sgsn_sockaddr_copy(to_addr, from_addr);
*to_ofd = &from_bind->ofd;
- rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
- rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT],
+ rate_ctr_inc(rate_ctr_group_get_ctr(from_bind->counters_io, GTPH_CTR_PKTS_OUT));
+ rate_ctr_add(rate_ctr_group_get_ctr(from_bind->counters_io, GTPH_CTR_BYTES_OUT),
reply_len);
LOG(LOGL_DEBUG, "%s Echo response to %s: %d bytes to %s\n",
(side_idx == GTPH_SIDE_GGSN)? "-->" : "<--",
gtphub_side_idx_names[side_idx],
- (int)reply_len, osmo_sockaddr_to_str(to_addr));
+ (int)reply_len, sgsn_sockaddr_to_str(to_addr));
return reply_len;
}
if (reply_len < 0)
@@ -2178,7 +2164,7 @@ int gtphub_handle_buf(struct gtphub *hub,
* so no-one else is allowed to talk to us from that side. */
struct gtphub_peer_port *from_peer = hub->proxy[side_idx][plane_idx];
if (from_peer) {
- if (osmo_sockaddr_cmp(&from_peer->sa, from_addr) != 0) {
+ if (sgsn_sockaddr_cmp(&from_peer->sa, from_addr) != 0) {
LOG(LOGL_ERROR,
"Rejecting: %s proxy configured, but GTP packet"
" received on %s bind is from another sender:"
@@ -2186,7 +2172,7 @@ int gtphub_handle_buf(struct gtphub *hub,
gtphub_side_idx_names[side_idx],
gtphub_side_idx_names[side_idx],
gtphub_port_str(from_peer),
- osmo_sockaddr_to_str(from_addr));
+ sgsn_sockaddr_to_str(from_addr));
return -1;
}
}
@@ -2204,7 +2190,7 @@ int gtphub_handle_buf(struct gtphub *hub,
if (side_idx == GTPH_SIDE_GGSN) {
LOG(LOGL_ERROR, "Dropping packet%s: unknown GGSN peer: %s\n",
gtp_type_str(p.type),
- osmo_sockaddr_to_str(from_addr));
+ sgsn_sockaddr_to_str(from_addr));
return -1;
} else {
/* SGSN */
@@ -2216,7 +2202,7 @@ int gtphub_handle_buf(struct gtphub *hub,
"Dropping packet%s: User plane peer was not"
"announced by PDP Context: %s\n",
gtp_type_str(p.type),
- osmo_sockaddr_to_str(from_addr));
+ sgsn_sockaddr_to_str(from_addr));
return -1;
}
@@ -2235,13 +2221,13 @@ int gtphub_handle_buf(struct gtphub *hub,
LOG(LOGL_ERROR, "Dropping packet%s: invalid %s peer: %s\n",
gtp_type_str(p.type),
gtphub_side_idx_names[side_idx],
- osmo_sockaddr_to_str(from_addr));
+ sgsn_sockaddr_to_str(from_addr));
return -1;
}
- rate_ctr_add(&from_peer->counters_io->ctr[GTPH_CTR_BYTES_IN],
+ rate_ctr_add(rate_ctr_group_get_ctr(from_peer->counters_io, GTPH_CTR_BYTES_IN),
received);
- rate_ctr_inc(&from_peer->counters_io->ctr[GTPH_CTR_PKTS_IN]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(from_peer->counters_io, GTPH_CTR_PKTS_IN));
LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx],
gtphub_port_str(from_peer));
@@ -2260,9 +2246,9 @@ int gtphub_handle_buf(struct gtphub *hub,
if (p.tun) {
struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[p.side_idx][p.plane_idx];
- rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_IN],
+ rate_ctr_add(rate_ctr_group_get_ctr(te->counters_io, GTPH_CTR_BYTES_IN),
received);
- rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_IN]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(te->counters_io, GTPH_CTR_PKTS_IN));
}
if ((!to_peer) && (side_idx == GTPH_SIDE_SGSN)) {
@@ -2297,7 +2283,7 @@ int gtphub_handle_buf(struct gtphub *hub,
!= 0)
return -1;
}
-
+
/* Either to_peer was resolved from an existing tunnel,
* or a PDP Ctx and thus a tunnel has just been created,
* or the tunnel has been deleted due to this message. */
@@ -2309,24 +2295,24 @@ int gtphub_handle_buf(struct gtphub *hub,
if (!to_peer_from_seq)
gtphub_map_seq(&p, from_peer, to_peer);
- osmo_sockaddr_copy(to_addr, &to_peer->sa);
+ sgsn_sockaddr_copy(to_addr, &to_peer->sa);
*reply_buf = (uint8_t*)p.data;
if (received) {
- rate_ctr_inc(&to_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
- rate_ctr_add(&to_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT],
+ rate_ctr_inc(rate_ctr_group_get_ctr(to_bind->counters_io, GTPH_CTR_PKTS_OUT));
+ rate_ctr_add(rate_ctr_group_get_ctr(to_bind->counters_io, GTPH_CTR_BYTES_OUT),
received);
- rate_ctr_inc(&to_peer->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
- rate_ctr_add(&to_peer->counters_io->ctr[GTPH_CTR_BYTES_OUT],
+ rate_ctr_inc(rate_ctr_group_get_ctr(to_peer->counters_io, GTPH_CTR_PKTS_OUT));
+ rate_ctr_add(rate_ctr_group_get_ctr(to_peer->counters_io, GTPH_CTR_BYTES_OUT),
received);
}
if (p.tun) {
struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[other_side_idx(p.side_idx)][p.plane_idx];
- rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
- rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_OUT],
+ rate_ctr_inc(rate_ctr_group_get_ctr(te->counters_io, GTPH_CTR_PKTS_OUT));
+ rate_ctr_add(rate_ctr_group_get_ctr(te->counters_io, GTPH_CTR_BYTES_OUT),
received);
}
@@ -2335,7 +2321,7 @@ int gtphub_handle_buf(struct gtphub *hub,
(side_idx == GTPH_SIDE_SGSN)? "-->" : "<--",
gtphub_side_idx_names[other_side_idx(side_idx)],
p.header_tei, p.seq,
- (int)received, osmo_sockaddr_to_str(to_addr));
+ (int)received, sgsn_sockaddr_to_str(to_addr));
return received;
}
@@ -2645,7 +2631,7 @@ static struct gtphub_peer_port *gtphub_port_find(const struct gtphub_bind *bind,
}
struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
- const struct osmo_sockaddr *addr)
+ const struct sgsn_sockaddr *addr)
{
struct gsn_addr gsna;
uint16_t port;
@@ -2704,7 +2690,7 @@ static struct gtphub_peer_addr *gtphub_addr_have(struct gtphub *hub,
struct gtphub_peer *peer = gtphub_peer_new(hub, bind);
a = gtphub_peer_add_addr(peer, addr);
-
+
LOG(LOGL_DEBUG, "New peer address: %s %s\n",
bind->label,
gsn_addr_to_str(&a->addr));
@@ -2762,7 +2748,7 @@ struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub,
/* Find a GGSN peer with a matching address. If the address is known but the
* port not, create a new port for that peer address. */
struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind,
- const struct osmo_sockaddr *addr)
+ const struct sgsn_sockaddr *addr)
{
struct gtphub_peer_addr *pa;
struct gtphub_peer_port *pp;
@@ -2817,7 +2803,7 @@ static int gtphub_resolve_ggsn(struct gtphub *hub,
/* TODO move to osmocom/core/socket.c ? */
/* use this in osmo_sock_init() to remove dup. */
-/* Internal: call getaddrinfo for osmo_sockaddr_init(). The caller is required
+/* Internal: call getaddrinfo for sgsn_sockaddr_init(). The caller is required
to call freeaddrinfo(*result), iff zero is returned. */
static int _osmo_getaddrinfo(struct addrinfo **result,
uint16_t family, uint16_t type, uint8_t proto,
@@ -2844,7 +2830,7 @@ static int _osmo_getaddrinfo(struct addrinfo **result,
}
/* TODO move to osmocom/core/socket.c ? */
-int osmo_sockaddr_init(struct osmo_sockaddr *addr,
+int sgsn_sockaddr_init(struct sgsn_sockaddr *addr,
uint16_t family, uint16_t type, uint8_t proto,
const char *host, uint16_t port)
{
@@ -2865,9 +2851,9 @@ int osmo_sockaddr_init(struct osmo_sockaddr *addr,
return 0;
}
-int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
+int sgsn_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
char *port_str, size_t port_str_len,
- const struct osmo_sockaddr *addr,
+ const struct sgsn_sockaddr *addr,
int flags)
{
int rc;
@@ -2896,14 +2882,14 @@ int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
return rc;
}
-const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
+const char *sgsn_sockaddr_to_strb(const struct sgsn_sockaddr *addr,
char *buf, size_t buf_len)
{
+ char portbuf[6];
const int portbuf_len = 6;
OSMO_ASSERT(buf_len > portbuf_len);
- char *portbuf = buf + buf_len - portbuf_len;
buf_len -= portbuf_len;
- if (osmo_sockaddr_to_strs(buf, buf_len,
+ if (sgsn_sockaddr_to_strs(buf, buf_len,
portbuf, portbuf_len,
addr,
NI_NUMERICHOST | NI_NUMERICSERV))
@@ -2918,17 +2904,17 @@ const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
return buf;
}
-const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr)
+const char *sgsn_sockaddr_to_str(const struct sgsn_sockaddr *addr)
{
static char buf[256];
- const char *result = osmo_sockaddr_to_strb(addr, buf, sizeof(buf));
+ const char *result = sgsn_sockaddr_to_strb(addr, buf, sizeof(buf));
if (! result)
return "(invalid)";
return result;
}
-int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
- const struct osmo_sockaddr *b)
+int sgsn_sockaddr_cmp(const struct sgsn_sockaddr *a,
+ const struct sgsn_sockaddr *b)
{
if (a == b)
return 0;
@@ -2938,7 +2924,7 @@ int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
return 1;
if (a->l != b->l) {
/* Lengths are not the same, but determine the order. Will
- * anyone ever sort a list by osmo_sockaddr though...? */
+ * anyone ever sort a list by sgsn_sockaddr though...? */
int cmp = memcmp(&a->a, &b->a, (a->l < b->l)? a->l : b->l);
if (cmp == 0) {
if (a->l < b->l)
@@ -2951,8 +2937,8 @@ int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
return memcmp(&a->a, &b->a, a->l);
}
-void osmo_sockaddr_copy(struct osmo_sockaddr *dst,
- const struct osmo_sockaddr *src)
+void sgsn_sockaddr_copy(struct sgsn_sockaddr *dst,
+ const struct sgsn_sockaddr *src)
{
OSMO_ASSERT(src->l <= sizeof(dst->a));
memcpy(&dst->a, &src->a, src->l);