diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-11-24 13:31:06 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-12-03 11:40:03 +0100 |
commit | e54cd1555a874b132116b1269264de7d6cc3d24d (patch) | |
tree | e508fd06bc542dd6f67abe698f55b8690a4aa683 /openbsc/include/openbsc/gtphub.h | |
parent | 2c8b58139f3e3c29309dd6518f77a62414de560c (diff) |
gtphub: track tunnels explicitly.
So far, gtphub worked perfectly by only tracking single TEIs ... for probably
most uses. But a Ctrl plane tunnel may have expired despite a still active
corresponding User plane tunnel. The User plane would continue to work
indefinitely, but if any Ctrl messages followed after more than six hours of
Ctrl silence, they would have been dropped due to an expired TEI mapping.
We want to
- combine expiry of a user TEI with its ctrl TEI. (done in this patch)
- upon delete PDP context, remove both user and ctrl TEI mappings. (future)
- when a peer indicates a restart counter bump, invalidate its tunnels.
(future)
To facilitate these, track tunnels, complete with both SGSN's and GGSN's
address, original and replaced TEIs, all for both user and ctrl plane, in a
single struct. A single expiry entry handles the entire tunnel, instead of
previously four separate expiries for each endpoint identifier.
Add the concept of a "side", being either GGSN or SGSN, to index tunnel
endpoint structs, and so on.
Track the originating side in the gtp_packet_desc.
Add header_tei_rx: set_tei() overwrites header_tei, but the originally received
header TEI is still needed to match a Create PDP Context Response up with its
Request (and for logging).
Adjust the test suite to expect tunnel listing strings instead of TEI mappings,
with a bonus of making it a lot easier to grok, and including the IP addresses.
Add regression test for refreshing tunnel expiry upon use.
Note: the current implementation is as slow as can possibly be, iterating all
the tunnels all the time. Optimizations are kept for a future commit, on
purpose.
BTW, the sequence number mapping/unmapping structures remain unchanged.
Sponsored-by: On-Waves ehi
Diffstat (limited to 'openbsc/include/openbsc/gtphub.h')
-rw-r--r-- | openbsc/include/openbsc/gtphub.h | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h index f2130844a..5db6f6430 100644 --- a/openbsc/include/openbsc/gtphub.h +++ b/openbsc/include/openbsc/gtphub.h @@ -135,6 +135,17 @@ enum gtphub_plane_idx { GTPH_PLANE_N }; +enum gtphub_side_idx { + GTPH_SIDE_GGSN = 0, + GTPH_SIDE_SGSN = 1, + GTPH_SIDE_N +}; + +static inline int other_side_idx(int side_idx) +{ + return (side_idx + 1) & 1; +} + extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N]; extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N]; @@ -376,6 +387,19 @@ struct gtphub_peer_port { struct osmo_sockaddr sa; }; +struct gtphub_tunnel_endpoint { + struct gtphub_peer_port *peer; + uint32_t tei_orig; /* from/to peer */ + uint32_t tei_repl; /* from/to the other tunnel endpoint */ +}; + +struct gtphub_tunnel { + struct llist_head entry; + struct expiring_item expiry_entry; + + struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N]; +}; + struct gtphub_bind { struct gsn_addr local_addr; uint16_t local_port; @@ -416,9 +440,10 @@ struct gtphub { * uint32_t; if a new TEI were mapped every second, this would take * more than 100 years (in which a single given TEI must not time out) * to cause a problem. */ - struct nr_map tei_map[GTPH_PLANE_N]; struct nr_pool tei_pool[GTPH_PLANE_N]; + struct llist_head tunnels; /* struct gtphub_tunnel */ + struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */ struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */ @@ -454,6 +479,12 @@ const char *gtphub_peer_str(struct gtphub_peer *peer); /* Same with a different static buffer. We often want to print two peers. */ const char *gtphub_peer_str2(struct gtphub_peer *peer); +/* Return a human readable description of tun in a static buffer. */ +const char *gtphub_tunnel_str(struct gtphub_tunnel *tun); + +/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */ +int gtphub_tunnel_complete(struct gtphub_tunnel *tun); + int gtphub_from_sgsns_handle_buf(struct gtphub *hub, unsigned int port_idx, const struct osmo_sockaddr *from_addr, |