aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gtphub.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2015-12-06 23:12:02 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2015-12-07 13:37:15 +0100
commitd010c49407220f7efe55d50d1dbf261a70f756d2 (patch)
treeb28f32d25b3661cd4839b06df5bd3a3896b3576d /openbsc/src/gprs/gtphub.c
parentbee75969cc90d3969dd23c1c79afc70755c87177 (diff)
gtphub: improve handling of restarted peer.
Handle peer restart earlier, so that all the tunnels are deleted by the restart code path, instead of the first one being deleted due to reused TEI. That caused confusing logging messages. Also, when receiving Delete confirmations from the peer that didn't restart, don't complain about unknown peer, but acknowledge and remove the half invalidated tunnel. This means that the pending delete entry from the restart code path is not needed / not used, so don't bother to add pending delete entries upon peer restart. The test test_peer_restarted_reusing_tei() hits the situation where a tunnel is removed because of a reused TEI rather than the restart counter. Adjust the test to expect the "out-of-band" delete request earlier on, and to still see the half invalidated tunnel around. Enhance the test by adding the delete response from the peer that didn't restart, and add a final tunnels_are() verification. Sponsored-by: On-Waves ehi
Diffstat (limited to 'openbsc/src/gprs/gtphub.c')
-rw-r--r--openbsc/src/gprs/gtphub.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index c8dddc5db..a68fa6567 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -1871,14 +1871,6 @@ static void gtphub_restarted(struct gtphub *hub,
* dropped because the tunnel is rendered unusable. */
gtphub_send_del_pdp_ctx(hub, tun, other_side_idx(side_idx));
- struct pending_delete *pd;
- pd = pending_delete_new();
- pd->tun = tun;
- pd->teardown_ind = 0xff;
- pd->nsapi = 0;
- llist_add(&pd->entry, &hub->pending_deletes);
- expiry_add(&hub->expire_quickly, &pd->expiry_entry, p->timestamp);
-
gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_CTRL],
NULL);
gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_USER],
@@ -2228,6 +2220,9 @@ int gtphub_handle_buf(struct gtphub *hub,
LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx],
gtphub_port_str(from_peer));
+ gtphub_check_restart_counter(hub, &p, from_peer);
+ gtphub_map_restart_counter(hub, &p);
+
struct gtphub_peer_port *to_peer_from_seq;
struct gtphub_peer_port *to_peer;
if (gtphub_unmap(hub, &p, from_peer,
@@ -2249,6 +2244,15 @@ int gtphub_handle_buf(struct gtphub *hub,
return -1;
}
+ if (!to_peer && p.tun && p.type == GTP_DELETE_PDP_RSP) {
+ /* It's a delete confirmation for a tunnel that is partly
+ * invalid, probably marked unsuable due to a restarted peer.
+ * Remove the tunnel and be happy without forwarding. */
+ expiring_item_del(&p.tun->expiry_entry);
+ p.tun = NULL;
+ return 0;
+ }
+
if (!to_peer) {
LOG(LOGL_ERROR, "No %s to send to. Dropping packet%s"
" (type=%" PRIu8 ", header-TEI=%" PRIx32 ", seq=%" PRIx16 ").\n",
@@ -2273,9 +2277,6 @@ int gtphub_handle_buf(struct gtphub *hub,
* or the tunnel has been deleted due to this message. */
OSMO_ASSERT(p.tun || (p.type == GTP_DELETE_PDP_RSP));
- gtphub_check_restart_counter(hub, &p, from_peer);
- gtphub_map_restart_counter(hub, &p);
-
/* If the GGSN is replying to an SGSN request, the sequence nr has
* already been unmapped above (to_peer_from_seq != NULL), and we need not
* create a new mapping. */