diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/gprs/gtphub.c | 23 | ||||
-rw-r--r-- | openbsc/tests/gtphub/gtphub_test.c | 50 | ||||
-rw-r--r-- | openbsc/tests/gtphub/gtphub_test.ok | 7 |
3 files changed, 60 insertions, 20 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. */ diff --git a/openbsc/tests/gtphub/gtphub_test.c b/openbsc/tests/gtphub/gtphub_test.c index fa9ad8bb7..8ce83c82e 100644 --- a/openbsc/tests/gtphub/gtphub_test.c +++ b/openbsc/tests/gtphub/gtphub_test.c @@ -905,9 +905,13 @@ static int msg_from_ggsn(int plane_idx, send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, plane_idx, ggsn_sender, buf, msg(msg_from_ggsn), now, &reply_buf, &sgsn_ofd, &sgsn_addr); - LVL2_ASSERT(send > 0); - LVL2_ASSERT(same_addr(&sgsn_addr, sgsn_receiver)); - LVL2_ASSERT(reply_is(msg_to_sgsn)); + if (*msg_to_sgsn) { + LVL2_ASSERT(send > 0); + LVL2_ASSERT(same_addr(&sgsn_addr, sgsn_receiver)); + LVL2_ASSERT(reply_is(msg_to_sgsn)); + } + else + LVL2_ASSERT(send == 0); return 1; } @@ -1410,7 +1414,8 @@ static void test_peer_restarted_reusing_tei(void) ); const char *gtp_req_to_ggsn = MSG_PDP_CTX_REQ("0068", - "6d32", /* mapped seq ("1234") */ + "6d33", /* seq 6d31 + 2, after "out-of-band" Delete PDP Ctx + due to differing restart counter. */ "23", "42000121436587f9", "00000002", /* mapped TEI Data I ("123") */ @@ -1427,7 +1432,31 @@ static void test_peer_restarted_reusing_tei(void) OSMO_ASSERT(was_resolved_for("240010123456789", "internet")); OSMO_ASSERT(tunnels_are( - "TEI=2:" + "TEI=2:" /* being established after restart */ + " 192.168.42.23 (TEI C=321 U=123)" + " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" + " @21955\n" + "TEI=1:" /* invalidated due to restart */ + " (uninitialized) (TEI C=321 U=123)" + " <-> 192.168.43.34 (TEI C=765 U=567)" + " @21945\n" + )); + + /* An "out-of-band" delete request should have been sent to the GGSN + * (checked by expected log output in gtphub_test.ok), and the GGSN + * will (usually) send a Delete Response like this: */ + const char *gtp_del_resp_from_ggsn = + MSG_DEL_PDP_CTX_RSP("00000001", "6d32"); + + /* For this response (due to peer restart) we expect no forwarded + * message. */ + OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, + &sgsn_sender, + gtp_del_resp_from_ggsn, + "")); + + OSMO_ASSERT(tunnels_are( + "TEI=2:" /* still being established after restart */ " 192.168.42.23 (TEI C=321 U=123)" " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" " @21955\n" @@ -1436,7 +1465,7 @@ static void test_peer_restarted_reusing_tei(void) const char *gtp_resp_from_ggsn = MSG_PDP_CTX_RSP("004e", "00000002", /* destination TEI (sent in req above) */ - "6d32", /* mapped seq */ + "6d33", /* mapped seq */ "01", /* restart */ "00000def", /* TEI U */ "00000fde", /* TEI C */ @@ -1446,7 +1475,7 @@ static void test_peer_restarted_reusing_tei(void) const char *gtp_resp_to_sgsn = MSG_PDP_CTX_RSP("004e", "00000321", /* unmapped TEI ("005") */ - "1234", /* unmapped seq ("6d32") */ + "1234", /* unmapped seq ("6d33") */ "23", "00000002", /* mapped TEI from GGSN ("567") */ "00000002", /* mapped TEI from GGSN ("765") */ @@ -1460,6 +1489,13 @@ static void test_peer_restarted_reusing_tei(void) gtp_resp_from_ggsn, gtp_resp_to_sgsn)); + OSMO_ASSERT(tunnels_are( + "TEI=2:" /* still being established after restart */ + " 192.168.42.23 (TEI C=321 U=123)" + " <-> 192.168.43.34 (TEI C=fde U=def)" + " @21955\n" + )); + OSMO_ASSERT(clear_test_hub()); } diff --git a/openbsc/tests/gtphub/gtphub_test.ok b/openbsc/tests/gtphub/gtphub_test.ok index 4a6118f5b..e60d5f2b2 100644 --- a/openbsc/tests/gtphub/gtphub_test.ok +++ b/openbsc/tests/gtphub/gtphub_test.ok @@ -17,14 +17,17 @@ test_reused_tei test_peer_restarted - __wrap_gtphub_resolve_ggsn_addr(): returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 Out-of-band gtphub_write(16): to 192.168.43.34 port 2123 32 14 00 08 00 00 07 65 6d 32 00 00 13 ff 14 00 +- __wrap_gtphub_resolve_ggsn_addr(): + returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 test_peer_restarted_reusing_tei - __wrap_gtphub_resolve_ggsn_addr(): returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 +Out-of-band gtphub_write(16): +to 192.168.43.34 port 2123 +32 14 00 08 00 00 07 65 6d 32 00 00 13 ff 14 00 - __wrap_gtphub_resolve_ggsn_addr(): returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 test_user_data |