aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gtphub.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gprs/gtphub.c')
-rw-r--r--openbsc/src/gprs/gtphub.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index 24d0c5829..0218924f0 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -995,9 +995,9 @@ static const char *gtphub_tunnel_side_str(struct gtphub_tunnel *tun,
APPEND("/%s", gsn_addr_to_str(&u->peer->peer_addr->addr));
}
- APPEND(" (TEI C %x=%x/U %x=%x)",
- c->tei_orig, c->tei_repl,
- u->tei_orig, u->tei_repl);
+ APPEND(" (TEI C=%x U=%x)",
+ c->tei_orig,
+ u->tei_orig);
return buf;
}
@@ -1008,6 +1008,7 @@ const char *gtphub_tunnel_str(struct gtphub_tunnel *tun)
int left = sizeof(buf);
int l;
+ APPEND("TEI=%x: ", tun->tei_repl);
APPEND("%s", gtphub_tunnel_side_str(tun, GTPH_SIDE_SGSN));
APPEND(" <-> %s", gtphub_tunnel_side_str(tun, GTPH_SIDE_GGSN));
@@ -1030,12 +1031,14 @@ int gtphub_tunnel_complete(struct gtphub_tunnel *tun)
{
if (!tun)
return 0;
+ if (!tun->tei_repl)
+ return 0;
int side_idx;
int plane_idx;
for_each_side_and_plane(side_idx, plane_idx) {
struct gtphub_tunnel_endpoint *te =
&tun->endpoint[side_idx][plane_idx];
- if (!(te->peer && te->tei_orig && te->tei_repl))
+ if (!(te->peer && te->tei_orig))
return 0;
}
return 1;
@@ -1212,29 +1215,33 @@ static struct gtphub_peer_port *gtphub_unmap_seq(struct gtp_packet_desc *p,
return nrm->origin;
}
-static int gtphub_check_mapped_tei(struct gtphub_tunnel_endpoint *new_te,
- struct gtphub_tunnel_endpoint *iterated_te,
+static int gtphub_check_mapped_tei(struct gtphub_tunnel *new_tun,
+ struct gtphub_tunnel *iterated_tun,
uint32_t *tei_min,
uint32_t *tei_max)
{
- if (!new_te->tei_repl)
+ if (!new_tun->tei_repl || !iterated_tun->tei_repl)
return 1;
- if (new_te->tei_repl != iterated_te->tei_repl)
+
+ *tei_min = (*tei_min < iterated_tun->tei_repl)? *tei_min : iterated_tun->tei_repl;
+ *tei_max = (*tei_max > iterated_tun->tei_repl)? *tei_max : iterated_tun->tei_repl;
+
+ if (new_tun->tei_repl != iterated_tun->tei_repl)
return 1;
- /* new_te->tei_repl is already taken. Try to find one out of the known
+ /* new_tun->tei_repl is already taken. Try to find one out of the known
* range. */
- LOG(LOGL_DEBUG, "TEI replacement %d already taken.\n", new_te->tei_repl);
+ LOG(LOGL_DEBUG, "TEI replacement %d already taken.\n", new_tun->tei_repl);
if ((*tei_max) < 0xffffffff) {
(*tei_max)++;
- new_te->tei_repl = *tei_max;
- LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_te->tei_repl);
+ new_tun->tei_repl = *tei_max;
+ LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl);
return 1;
} else if ((*tei_min) > 1) {
(*tei_min)--;
- new_te->tei_repl = *tei_min;
- LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_te->tei_repl);
+ new_tun->tei_repl = *tei_min;
+ LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl);
return 1;
}
@@ -1249,8 +1256,6 @@ static int gtphub_check_reused_teis(struct gtphub *hub,
uint32_t tei_max = 0;
int side_idx;
int plane_idx;
- int side_idx2;
- int plane_idx2;
struct gtphub_tunnel_endpoint *te;
struct gtphub_tunnel_endpoint *te2;
@@ -1303,23 +1308,14 @@ static int gtphub_check_reused_teis(struct gtphub *hub,
if (tun_continue)
continue;
- /* Check whether the mapped TEIs assigned to the endpoints are
- * used anywhere else. */
- for_each_side_and_plane(side_idx, plane_idx) {
- te = &tun->endpoint[side_idx][plane_idx];
- tei_min = (tei_min < te->tei_repl)? tei_min : te->tei_repl;
- tei_max = (tei_max > te->tei_repl)? tei_max : te->tei_repl;
-
- for_each_side_and_plane(side_idx2, plane_idx2) {
- te2 = &new_tun->endpoint[side_idx2][plane_idx2];
- if (!gtphub_check_mapped_tei(te2, te, &tei_min, &tei_max)) {
- LOG(LOGL_ERROR,
- "No mapped TEI is readily available."
- " Searching for holes between occupied"
- " TEIs not implemented.");
- return 0;
- }
- }
+ /* Check whether the mapped TEI is already used by another
+ * tunnel. */
+ if (!gtphub_check_mapped_tei(new_tun, tun, &tei_min, &tei_max)) {
+ LOG(LOGL_ERROR,
+ "No mapped TEI is readily available."
+ " Searching for holes between occupied"
+ " TEIs not implemented.");
+ return 0;
}
}
@@ -1350,7 +1346,7 @@ static struct gtphub_tunnel_endpoint *gtphub_unmap_tei(struct gtphub *hub,
&tun->endpoint[p->side_idx][p->plane_idx];
struct gtphub_tunnel_endpoint *te_to =
&tun->endpoint[other_side][p->plane_idx];
- if ((te_to->tei_repl == p->header_tei_rx)
+ if ((tun->tei_repl == p->header_tei_rx)
&& te_from->peer
&& gsn_addr_same(&te_from->peer->peer_addr->addr,
&from->peer_addr->addr)) {
@@ -1453,6 +1449,10 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
/* A new tunnel. */
p->tun = tun = gtphub_tunnel_new();
+
+ /* Create TEI mapping */
+ tun->tei_repl = nr_pool_next(&hub->tei_pool);
+
llist_add(&tun->entry, &hub->tunnels);
gtphub_tunnel_refresh(hub, tun, p->timestamp);
/* The endpoint peers on this side (SGSN) will be set from IEs
@@ -1471,8 +1471,7 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
* TEI and be available in tun (== p->tun). Just fill in the
* GSN Addresses below.*/
OSMO_ASSERT(tun);
- OSMO_ASSERT(tun->endpoint[other_side_idx(p->side_idx)][GTPH_PLANE_CTRL].tei_repl
- == p->header_tei_rx);
+ OSMO_ASSERT(tun->tei_repl == p->header_tei_rx);
OSMO_ASSERT(to_ctrl);
}
@@ -1555,12 +1554,9 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
}
if (tei_from_ie) {
- /* Create TEI mapping and replace in GTP packet IE */
- uint32_t mapped_tei = nr_pool_next(&hub->tei_pool);
-
+ /* Replace TEI in GTP packet IE */
tun->endpoint[side_idx][plane_idx].tei_orig = tei_from_ie;
- tun->endpoint[side_idx][plane_idx].tei_repl = mapped_tei;
- p->ie[ie_idx]->tv4.v = hton32(mapped_tei);
+ p->ie[ie_idx]->tv4.v = hton32(tun->tei_repl);
if (!gtphub_check_reused_teis(hub, tun)) {
/* It's highly unlikely that all TEIs are