diff options
-rw-r--r-- | openbsc/include/openbsc/gtphub.h | 51 | ||||
-rw-r--r-- | openbsc/src/gprs/gtphub.c | 496 | ||||
-rw-r--r-- | openbsc/src/gprs/gtphub_main.c | 25 | ||||
-rw-r--r-- | openbsc/src/gprs/gtphub_vty.c | 66 | ||||
-rw-r--r-- | openbsc/tests/gtphub/gtphub_test.c | 72 |
5 files changed, 293 insertions, 417 deletions
diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h index a142867d6..005c3f85b 100644 --- a/openbsc/include/openbsc/gtphub.h +++ b/openbsc/include/openbsc/gtphub.h @@ -136,8 +136,8 @@ enum gtphub_plane_idx { }; enum gtphub_side_idx { - GTPH_SIDE_GGSN = 0, - GTPH_SIDE_SGSN = 1, + GTPH_SIDE_SGSN = 0, + GTPH_SIDE_GGSN = 1, GTPH_SIDE_N }; @@ -153,6 +153,8 @@ static inline int other_side_idx(int side_idx) extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N]; extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N]; +extern const char* const gtphub_side_idx_names[GTPH_SIDE_N]; + /* A host address in the form that is expected in the 7.7.32 GSN Address IE. * len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no * address is set, len shall be 0. */ @@ -357,10 +359,8 @@ struct gtphub_cfg_bind { }; struct gtphub_cfg { - struct gtphub_cfg_bind to_sgsns[GTPH_PLANE_N]; - struct gtphub_cfg_bind to_ggsns[GTPH_PLANE_N]; - struct gtphub_cfg_addr sgsn_proxy[GTPH_PLANE_N]; - struct gtphub_cfg_addr ggsn_proxy[GTPH_PLANE_N]; + struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; + struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N]; }; @@ -429,14 +429,10 @@ struct gtphub_resolved_ggsn { }; struct gtphub { - struct gtphub_bind to_sgsns[GTPH_PLANE_N]; - struct gtphub_bind to_ggsns[GTPH_PLANE_N]; - - /* pointers to an entry of to_sgsns[x].peers */ - struct gtphub_peer_port *sgsn_proxy[GTPH_PLANE_N]; + struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; - /* pointers to an entry of to_ggsns[x].peers */ - struct gtphub_peer_port *ggsn_proxy[GTPH_PLANE_N]; + /* pointers to an entry of to_gsns[s][p].peers */ + struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N]; /* The TEI numbers will simply wrap and be reused, which will work out * in practice. Problems would arise if one given peer maintained the @@ -490,25 +486,16 @@ 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, - uint8_t *buf, - size_t received, - time_t now, - uint8_t **reply_buf, - struct osmo_fd **to_ofd, - struct osmo_sockaddr *to_addr); - -int gtphub_from_ggsns_handle_buf(struct gtphub *hub, - unsigned int port_idx, - const struct osmo_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); +int gtphub_handle_buf(struct gtphub *hub, + unsigned int side_idx, + unsigned int port_idx, + const struct osmo_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 gtphub_peer_port *gtphub_port_have(struct gtphub *hub, struct gtphub_bind *bind, diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c index 6037d3bbe..110438cc3 100644 --- a/openbsc/src/gprs/gtphub.c +++ b/openbsc/src/gprs/gtphub.c @@ -746,6 +746,11 @@ const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N] = { 2152, }; +const char* const gtphub_side_idx_names[GTPH_SIDE_N] = { + "SGSN", + "GGSN", +}; + time_t gtphub_now(void) { struct timespec now_tp; @@ -1402,56 +1407,52 @@ static int gtphub_unmap_header_tei(struct gtphub_peer_port **to_port_p, return 0; } -/* Read GSN address IEs from p, and make sure these peer addresses exist in - * bind[plane_idx] with default ports, in their respective planes (both Ctrl - * and User). Map TEIs announced in IEs, and write mapped TEIs in-place into - * the packet p. */ -static int gtphub_handle_pdp_ctx_ies(struct gtphub *hub, - struct gtphub_bind from_bind_arr[], - struct gtphub_bind to_bind_arr[], - struct gtphub_peer_port *sgsn_ctrl, - struct gtphub_peer_port *ggsn_ctrl, - struct gtp_packet_desc *p) +static int gtphub_handle_create_pdp_ctx(struct gtphub *hub, + struct gtp_packet_desc *p, + struct gtphub_peer_port *from_ctrl, + struct gtphub_peer_port *to_ctrl) { - OSMO_ASSERT(p->plane_idx == GTPH_PLANE_CTRL); - int rc; int plane_idx; - switch (p->type) { - case GTP_CREATE_PDP_REQ: - case GTP_CREATE_PDP_RSP: - /* Go for it below */ - break; - default: - /* Nothing to do for this message type. */ - return 0; - } - /* TODO enforce a Request only from SGSN, a Response only from GGSN? */ - osmo_static_assert((GTPH_PLANE_CTRL == 0) && (GTPH_PLANE_USER == 1), plane_nrs_match_GSN_addr_IE_indices); struct gtphub_tunnel *tun = NULL; if (p->type == GTP_CREATE_PDP_REQ) { + if (p->side_idx != GTPH_SIDE_SGSN) { + LOG(LOGL_ERROR, "Wrong side: Create PDP Context" + " Request from the GGSN side"); + return -1; + } + /* A new tunnel. */ tun = gtphub_tunnel_new(); 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 + * below. Also set the GGSN Ctrl endpoint, for logging. */ gtphub_tunnel_endpoint_set_peer(&tun->endpoint[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - ggsn_ctrl); + to_ctrl); } else if (p->type == GTP_CREATE_PDP_RSP) { - /* Find the tunnel created during request */ - OSMO_ASSERT(sgsn_ctrl); + if (p->side_idx != GTPH_SIDE_GGSN) { + LOG(LOGL_ERROR, "Wrong side: Create PDP Context" + " Response from the SGSN side"); + return -1; + } + + /* Find the tunnel created during request. This is coming from + * the GGSN side, so to_ctrl corresponds to the SGSN. */ + OSMO_ASSERT(to_ctrl); tun = gtphub_tun_find(hub, other_side_idx(p->side_idx), - p->plane_idx, sgsn_ctrl, 0, p->header_tei_rx); + p->plane_idx, to_ctrl, 0, p->header_tei_rx); if (!tun) { LOG(LOGL_ERROR, "Create PDP Context Response: cannot" " find matching request from SGSN %s, mapped TEI %x.\n", - gtphub_port_str(sgsn_ctrl), p->header_tei_rx); + gtphub_port_str(to_ctrl), p->header_tei_rx); return -1; } } @@ -1496,7 +1497,7 @@ static int gtphub_handle_pdp_ctx_ies(struct gtphub *hub, /* Make sure an entry for this peer address with default port * exists */ struct gtphub_peer_port *peer_from_ie = - gtphub_port_have(hub, &from_bind_arr[plane_idx], + gtphub_port_have(hub, &hub->to_gsns[side_idx][plane_idx], &addr_from_ie, gtphub_plane_idx_default_port[plane_idx]); @@ -1516,8 +1517,8 @@ static int gtphub_handle_pdp_ctx_ies(struct gtphub *hub, } /* Replace the GSN address to reflect gtphub. */ - rc = gsn_addr_put(&to_bind_arr[plane_idx].local_addr, p, - plane_idx); + rc = gsn_addr_put(&hub->to_gsns[other_side_idx(side_idx)][plane_idx].local_addr, + p, plane_idx); if (rc) { LOG(LOGL_ERROR, "Cannot write %s GSN Address IE\n", gtphub_plane_idx_names[plane_idx]); @@ -1536,6 +1537,30 @@ static int gtphub_handle_pdp_ctx_ies(struct gtphub *hub, return 0; } +/* Read GSN address IEs from p, and make sure these peer addresses exist in + * bind[plane_idx] with default ports, in their respective planes (both Ctrl + * and User). Map TEIs announced in IEs, and write mapped TEIs in-place into + * the packet p. */ +static int gtphub_handle_pdp_ctx(struct gtphub *hub, + struct gtp_packet_desc *p, + struct gtphub_peer_port *from_ctrl, + struct gtphub_peer_port *to_ctrl) +{ + OSMO_ASSERT(p->plane_idx == GTPH_PLANE_CTRL); + + switch (p->type) { + case GTP_CREATE_PDP_REQ: + case GTP_CREATE_PDP_RSP: + return gtphub_handle_create_pdp_ctx(hub, p, + from_ctrl, to_ctrl); + default: + /* Nothing to do for this message type. */ + return 0; + } + +} + + static int gtphub_write(const struct osmo_fd *to, const struct osmo_sockaddr *to_addr, const uint8_t *buf, size_t buf_len) @@ -1582,9 +1607,9 @@ static int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what) if (len < 1) return 0; - len = gtphub_from_ggsns_handle_buf(hub, plane_idx, &from_addr, buf, len, - gtphub_now(), - &reply_buf, &to_ofd, &to_addr); + len = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, plane_idx, &from_addr, + buf, len, gtphub_now(), + &reply_buf, &to_ofd, &to_addr); if (len < 1) return 0; @@ -1705,29 +1730,34 @@ struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *b * sockaddr to *to_addr. The reason for this is that the sockaddr may expire at * any moment, while the osmo_fd is guaranteed to persist. Return the number of * bytes to forward, 0 or less on failure. */ -int gtphub_from_ggsns_handle_buf(struct gtphub *hub, - unsigned int plane_idx, - const struct osmo_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) -{ +int gtphub_handle_buf(struct gtphub *hub, + unsigned int side_idx, + unsigned int plane_idx, + const struct osmo_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 gtphub_bind *from_bind_arr = hub->to_ggsns; struct gtphub_bind *to_bind_arr = hub->to_sgsns; - struct gtphub_bind *from_bind = &from_bind_arr[plane_idx]; - struct gtphub_bind *to_bind = &to_bind_arr[plane_idx]; + */ + 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], received); - LOG(LOGL_DEBUG, "<- rx %s from GGSN %s\n", + LOG(LOGL_DEBUG, "%s rx %s from %s %s\n", + (side_idx == GTPH_SIDE_GGSN)? "<-" : "->", gtphub_plane_idx_names[plane_idx], + gtphub_side_idx_names[side_idx], osmo_sockaddr_to_str(from_addr)); static struct gtp_packet_desc p; - gtp_decode(buf, received, GTPH_SIDE_GGSN, plane_idx, &p, now); + gtp_decode(buf, received, side_idx, plane_idx, &p, now); if (p.rc <= 0) return -1; @@ -1744,7 +1774,9 @@ int gtphub_from_ggsns_handle_buf(struct gtphub *hub, rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]); rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT], reply_len); - LOG(LOGL_DEBUG, "--> Echo response to GGSN: %d bytes to %s\n", + 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)); return reply_len; } @@ -1756,51 +1788,88 @@ int gtphub_from_ggsns_handle_buf(struct gtphub *hub, /* If a GGSN proxy is configured, check that it's indeed that proxy * talking to us. A proxy is a forced 1:1 connection, e.g. to another * gtphub, so no-one else is allowed to talk to us from that side. */ - struct gtphub_peer_port *ggsn = hub->ggsn_proxy[plane_idx]; - if (ggsn) { - if (osmo_sockaddr_cmp(&ggsn->sa, from_addr) != 0) { + 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) { LOG(LOGL_ERROR, - "Rejecting: GGSN proxy configured, but GTP packet" - " received on GGSN bind is from another sender:" + "Rejecting: %s proxy configured, but GTP packet" + " received on %s bind is from another sender:" " proxy: %s sender: %s\n", - gtphub_port_str(ggsn), + gtphub_side_idx_names[side_idx], + gtphub_side_idx_names[side_idx], + gtphub_port_str(from_peer), osmo_sockaddr_to_str(from_addr)); return -1; } } - if (!ggsn) { - /* Find a GGSN peer with a matching address. The sender's port - * may in fact differ. */ - ggsn = gtphub_known_addr_have_port(from_bind, from_addr); + if (!from_peer) { + /* Find or create a peer with a matching address. The sender's + * port may in fact differ. */ + from_peer = gtphub_known_addr_have_port(from_bind, from_addr); } /* If any PDP context has been created, we already have an entry for * this GGSN. If we don't have an entry, the GGSN has nothing to tell * us about. */ - if (!ggsn) { - LOG(LOGL_ERROR, "Dropping packet: unknown GGSN peer: %s\n", + if (!from_peer) { + if (side_idx == GTPH_SIDE_GGSN) { + LOG(LOGL_ERROR, "Dropping packet: unknown GGSN peer: %s\n", + osmo_sockaddr_to_str(from_addr)); + return -1; + } else { + /* SGSN */ + /* A new peer. If this is on the Ctrl plane, an SGSN + * may make first contact without being known yet, so + * create the peer struct for the current sender. */ + if (plane_idx != GTPH_PLANE_CTRL) { + LOG(LOGL_ERROR, + "Dropping packet: User plane peer was not" + "announced by PDP Context: %s\n", + osmo_sockaddr_to_str(from_addr)); + return -1; + } + + struct gsn_addr from_gsna; + uint16_t from_port; + if (gsn_addr_from_sockaddr(&from_gsna, &from_port, from_addr) != 0) + return -1; + + from_peer = gtphub_port_have(hub, from_bind, &from_gsna, from_port); + } + } + + if (!from_peer) { + /* This could theoretically happen for invalid address data or + * somesuch. */ + LOG(LOGL_ERROR, "Dropping packet: invalid %s peer: %s\n", + gtphub_side_idx_names[side_idx], osmo_sockaddr_to_str(from_addr)); return -1; } - LOG(LOGL_DEBUG, "GGSN peer: %s\n", gtphub_port_str(ggsn)); + LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx], + gtphub_port_str(from_peer)); - struct gtphub_peer_port *sgsn_from_seq; - struct gtphub_peer_port *sgsn; - if (gtphub_unmap(hub, &p, ggsn, - hub->sgsn_proxy[plane_idx], - &sgsn, &sgsn_from_seq, - NULL /* not interested, got it in &sgsn already */ + struct gtphub_peer_port *to_peer_from_seq; + struct gtphub_peer_port *to_peer; + if (gtphub_unmap(hub, &p, from_peer, + hub->proxy[other_side_idx(side_idx)][plane_idx], + &to_peer, &to_peer_from_seq, + NULL /* not interested, got it in &to_peer already */ ) != 0) { return -1; } - if (!sgsn) { - /* A GGSN initiated request would go to a known TEI. So this is - * bogus. */ - LOG(LOGL_ERROR, "No SGSN to send to. Dropping packet.\n"); + if ((!to_peer) && (side_idx == GTPH_SIDE_SGSN)) { + if (gtphub_resolve_ggsn(hub, &p, &to_peer) < 0) + return -1; + } + + if (!to_peer) { + LOG(LOGL_ERROR, "No %s to send to. Dropping packet.\n", + gtphub_side_idx_names[other_side_idx(side_idx)]); return -1; } @@ -1808,22 +1877,21 @@ int gtphub_from_ggsns_handle_buf(struct gtphub *hub, /* This may be a Create PDP Context response. If it is, there * are other addresses in the GTP message to set up apart from * the sender. */ - if (gtphub_handle_pdp_ctx_ies(hub, from_bind_arr, to_bind_arr, - sgsn, ggsn, &p) + if (gtphub_handle_pdp_ctx(hub, &p, from_peer, to_peer) != 0) return -1; } - gtphub_check_restart_counter(hub, &p, ggsn); - gtphub_map_restart_counter(hub, &p, ggsn, sgsn); + gtphub_check_restart_counter(hub, &p, from_peer); + gtphub_map_restart_counter(hub, &p, from_peer, to_peer); /* If the GGSN is replying to an SGSN request, the sequence nr has - * already been unmapped above (sgsn_from_seq != NULL), and we need not + * already been unmapped above (to_peer_from_seq != NULL), and we need not * create a new mapping. */ - if (!sgsn_from_seq) - gtphub_map_seq(&p, ggsn, sgsn); + if (!to_peer_from_seq) + gtphub_map_seq(&p, from_peer, to_peer); - osmo_sockaddr_copy(to_addr, &sgsn->sa); + osmo_sockaddr_copy(to_addr, &to_peer->sa); *reply_buf = (uint8_t*)p.data; @@ -1832,7 +1900,9 @@ int gtphub_from_ggsns_handle_buf(struct gtphub *hub, rate_ctr_add(&to_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT], received); } - LOG(LOGL_DEBUG, "<-- Forward to SGSN: %d bytes to %s\n", + LOG(LOGL_DEBUG, "%s Forward to %s: %d bytes to %s\n", + (side_idx == GTPH_SIDE_SGSN)? "-->" : "<--", + gtphub_side_idx_names[other_side_idx(side_idx)], (int)received, osmo_sockaddr_to_str(to_addr)); return received; } @@ -1860,169 +1930,15 @@ static int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what) if (len < 1) return 0; - len = gtphub_from_sgsns_handle_buf(hub, plane_idx, &from_addr, buf, len, - gtphub_now(), - &reply_buf, &to_ofd, &to_addr); + len = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, plane_idx, &from_addr, + buf, len, gtphub_now(), + &reply_buf, &to_ofd, &to_addr); if (len < 1) return 0; return gtphub_write(to_ofd, &to_addr, reply_buf, len); } -/* Analogous to gtphub_from_ggsns_handle_buf(), see the comment there. */ -int gtphub_from_sgsns_handle_buf(struct gtphub *hub, - unsigned int plane_idx, - const struct osmo_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 gtphub_bind *from_bind_arr = hub->to_sgsns; - struct gtphub_bind *to_bind_arr = hub->to_ggsns; - struct gtphub_bind *from_bind = &from_bind_arr[plane_idx]; - struct gtphub_bind *to_bind = &to_bind_arr[plane_idx]; - - rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_IN], - received); - LOG(LOGL_DEBUG, "-> rx %s from SGSN %s\n", - gtphub_plane_idx_names[plane_idx], - osmo_sockaddr_to_str(from_addr)); - - static struct gtp_packet_desc p; - gtp_decode(buf, received, GTPH_SIDE_SGSN, plane_idx, &p, now); - - if (p.rc <= 0) - return -1; - - rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_IN]); - - int reply_len; - reply_len = gtphub_handle_echo(hub, &p, reply_buf); - if (reply_len > 0) { - /* It was an echo. Nothing left to do. */ - osmo_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], - reply_len); - LOG(LOGL_DEBUG, "<-- Echo response to SGSN: %d bytes to %s\n", - (int)reply_len, osmo_sockaddr_to_str(to_addr)); - return reply_len; - } - if (reply_len < 0) - return -1; - - *to_ofd = &to_bind->ofd; - - /* If an SGSN proxy is configured, check that it's indeed that proxy - * talking to us. A proxy is a forced 1:1 connection, e.g. to another - * gtphub, so no-one else is allowed to talk to us from that side. */ - struct gtphub_peer_port *sgsn = hub->sgsn_proxy[plane_idx]; - if (sgsn) { - if (osmo_sockaddr_cmp(&sgsn->sa, from_addr) != 0) { - LOG(LOGL_ERROR, - "Rejecting: GGSN proxy configured, but GTP packet" - " received on GGSN bind is from another sender:" - " proxy: %s sender: %s\n", - gtphub_port_str(sgsn), - osmo_sockaddr_to_str(from_addr)); - return -1; - } - } - - if (!sgsn) { - /* If any contact has been made before, we already have an - * entry for this SGSN. The port may differ. */ - sgsn = gtphub_known_addr_have_port(from_bind, from_addr); - } - - if (!sgsn) { - /* A new peer. If this is on the Ctrl plane, an SGSN may make - * first contact without being known yet, so create the peer - * struct for the current sender. */ - if (plane_idx != GTPH_PLANE_CTRL) { - LOG(LOGL_ERROR, - "User plane peer was not announced by PDP Context," - " discarding: %s\n", - osmo_sockaddr_to_str(from_addr)); - return -1; - } - - struct gsn_addr from_gsna; - uint16_t from_port; - if (gsn_addr_from_sockaddr(&from_gsna, &from_port, from_addr) != 0) - return -1; - - sgsn = gtphub_port_have(hub, from_bind, &from_gsna, from_port); - } - - if (!sgsn) { - /* This could theoretically happen for invalid address data or - * somesuch. */ - LOG(LOGL_ERROR, "Dropping packet: invalid SGSN peer: %s\n", - osmo_sockaddr_to_str(from_addr)); - return -1; - } - LOG(LOGL_DEBUG, "SGSN peer: %s\n", gtphub_port_str(sgsn)); - - struct gtphub_peer_port *ggsn_from_seq; - struct gtphub_peer_port *ggsn; - if (gtphub_unmap(hub, &p, sgsn, - hub->ggsn_proxy[plane_idx], - &ggsn, &ggsn_from_seq, - NULL /* not interested, got it in &ggsn already */ - ) - != 0) { - return -1; - } - - if (!ggsn) { - if (gtphub_resolve_ggsn(hub, &p, &ggsn) < 0) - return -1; - } - - if (!ggsn) { - LOG(LOGL_ERROR, "No GGSN to send to. Dropping packet.\n"); - return -1; - } - - if (plane_idx == GTPH_PLANE_CTRL) { - /* This may be a Create PDP Context request. If it is, there are - * other addresses in the GTP message to set up apart from the - * sender. */ - if (gtphub_handle_pdp_ctx_ies(hub, from_bind_arr, to_bind_arr, - sgsn, ggsn, &p) - != 0) - return -1; - } - - gtphub_check_restart_counter(hub, &p, sgsn); - gtphub_map_restart_counter(hub, &p, sgsn, ggsn); - - /* If the SGSN is replying to a GGSN request, the sequence nr has - * already been unmapped above (unmap_ggsn != NULL), and we need not - * create a new outgoing sequence map. */ - if (!ggsn_from_seq) - gtphub_map_seq(&p, sgsn, ggsn); - - osmo_sockaddr_copy(to_addr, &ggsn->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], - received); - } - LOG(LOGL_DEBUG, "--> Forward to GGSN: %d bytes to %s\n", - (int)received, osmo_sockaddr_to_str(to_addr)); - return received; -} - static void resolved_gssn_del_cb(struct expiring_item *expi) { struct gtphub_resolved_ggsn *ggsn; @@ -2048,7 +1964,7 @@ void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str, apn_oi_str, osmo_hexdump((unsigned char*)resolved_addr, sizeof(*resolved_addr))); - pp = gtphub_port_have(hub, &hub->to_ggsns[GTPH_PLANE_CTRL], + pp = gtphub_port_have(hub, &hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], resolved_addr, 2123); if (!pp) { LOG(LOGL_ERROR, "Internal: Cannot create/find peer '%s'\n", @@ -2127,10 +2043,9 @@ void gtphub_gc(struct gtphub *hub, time_t now) /* ... */ if (expired) { - int i; - for_each_plane(i) { - gtphub_gc_bind(&hub->to_sgsns[i]); - gtphub_gc_bind(&hub->to_ggsns[i]); + int s, p; + for_each_side_and_plane(s, p) { + gtphub_gc_bind(&hub->to_gsns[s][p]); } } } @@ -2162,16 +2077,16 @@ void gtphub_init(struct gtphub *hub) nr_pool_init(&hub->tei_pool, 1, 0xffffffff); + int side_idx; int plane_idx; - for_each_plane(plane_idx) { - gtphub_bind_init(&hub->to_ggsns[plane_idx]); - gtphub_bind_init(&hub->to_sgsns[plane_idx]); + for_each_side_and_plane(side_idx, plane_idx) { + gtphub_bind_init(&hub->to_gsns[side_idx][plane_idx]); } - hub->to_sgsns[GTPH_PLANE_CTRL].label = "SGSN Ctrl"; - hub->to_ggsns[GTPH_PLANE_CTRL].label = "GGSN Ctrl"; - hub->to_sgsns[GTPH_PLANE_USER].label = "SGSN User"; - hub->to_ggsns[GTPH_PLANE_USER].label = "GGSN User"; + hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].label = "SGSN Ctrl"; + hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].label = "GGSN Ctrl"; + hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].label = "SGSN User"; + hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].label = "GGSN User"; } /* For the test suite, this is kept separate from gtphub_stop(), which also @@ -2185,22 +2100,20 @@ void gtphub_free(struct gtphub *hub) expiry_clear(&hub->expire_quickly); expiry_clear(&hub->expire_slowly); + int side_idx; int plane_idx; - for_each_plane(plane_idx) { - gtphub_gc_bind(&hub->to_ggsns[plane_idx]); - gtphub_bind_free(&hub->to_ggsns[plane_idx]); - - gtphub_gc_bind(&hub->to_sgsns[plane_idx]); - gtphub_bind_free(&hub->to_sgsns[plane_idx]); + for_each_side_and_plane(side_idx, plane_idx) { + gtphub_gc_bind(&hub->to_gsns[side_idx][plane_idx]); + gtphub_bind_free(&hub->to_gsns[side_idx][plane_idx]); } } void gtphub_stop(struct gtphub *hub) { + int side_idx; int plane_idx; - for_each_plane(plane_idx) { - gtphub_bind_stop(&hub->to_ggsns[plane_idx]); - gtphub_bind_stop(&hub->to_sgsns[plane_idx]); + for_each_side_and_plane(side_idx, plane_idx) { + gtphub_bind_stop(&hub->to_gsns[side_idx][plane_idx]); } gtphub_free(hub); } @@ -2234,7 +2147,7 @@ int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, hub->restart_counter = restart_counter; /* If a Ctrl plane proxy is configured, ares will never be used. */ - if (!cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str) { + if (!cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) { if (gtphub_ares_init(hub) != 0) { LOG(LOGL_FATAL, "Failed to initialize ares\n"); return -1; @@ -2243,61 +2156,44 @@ int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, /* TODO set hub->restart_counter from external file. */ + int side_idx; int plane_idx; - for_each_plane(plane_idx) { - rc = gtphub_bind_start(&hub->to_ggsns[plane_idx], - &cfg->to_ggsns[plane_idx], - from_ggsns_read_cb, hub, plane_idx); - if (rc) { - LOG(LOGL_FATAL, "Failed to bind for GGSNs (%s)\n", - gtphub_plane_idx_names[plane_idx]); - return rc; - } - - rc = gtphub_bind_start(&hub->to_sgsns[plane_idx], - &cfg->to_sgsns[plane_idx], - from_sgsns_read_cb, hub, plane_idx); + for_each_side_and_plane(side_idx, plane_idx) { + rc = gtphub_bind_start(&hub->to_gsns[side_idx][plane_idx], + &cfg->to_gsns[side_idx][plane_idx], + (side_idx == GTPH_SIDE_SGSN) + ? from_sgsns_read_cb + : from_ggsns_read_cb, + hub, plane_idx); if (rc) { - LOG(LOGL_FATAL, "Failed to bind for SGSNs (%s)\n", + LOG(LOGL_FATAL, "Failed to bind for %ss (%s)\n", + gtphub_side_idx_names[side_idx], gtphub_plane_idx_names[plane_idx]); return rc; } } - for_each_plane(plane_idx) { + for_each_side_and_plane(side_idx, plane_idx) { if (gtphub_make_proxy(hub, - &hub->sgsn_proxy[plane_idx], - &hub->to_sgsns[plane_idx], - &cfg->sgsn_proxy[plane_idx]) + &hub->proxy[side_idx][plane_idx], + &hub->to_gsns[side_idx][plane_idx], + &cfg->proxy[side_idx][plane_idx]) != 0) { - LOG(LOGL_FATAL, "Cannot configure SGSN proxy" + LOG(LOGL_FATAL, "Cannot configure %s proxy" " %s port %d.\n", - cfg->sgsn_proxy[plane_idx].addr_str, - (int)cfg->sgsn_proxy[plane_idx].port); - return -1; - } - if (gtphub_make_proxy(hub, - &hub->ggsn_proxy[plane_idx], - &hub->to_ggsns[plane_idx], - &cfg->ggsn_proxy[plane_idx]) - != 0) { - LOG(LOGL_ERROR, "Cannot configure GGSN proxy.\n"); + gtphub_side_idx_names[side_idx], + cfg->proxy[side_idx][plane_idx].addr_str, + (int)cfg->proxy[side_idx][plane_idx].port); return -1; } } - for_each_plane(plane_idx) { - if (hub->sgsn_proxy[plane_idx]) - LOG(LOGL_NOTICE, "Using SGSN %s proxy %s\n", - gtphub_plane_idx_names[plane_idx], - gtphub_port_str(hub->sgsn_proxy[plane_idx])); - } - - for_each_plane(plane_idx) { - if (hub->ggsn_proxy[plane_idx]) - LOG(LOGL_NOTICE, "Using GGSN %s proxy %s\n", + for_each_side_and_plane(side_idx, plane_idx) { + if (hub->proxy[side_idx][plane_idx]) + LOG(LOGL_NOTICE, "Using %s %s proxy %s\n", + gtphub_side_idx_names[side_idx], gtphub_plane_idx_names[plane_idx], - gtphub_port_str(hub->ggsn_proxy[plane_idx])); + gtphub_port_str(hub->proxy[side_idx][plane_idx])); } gtphub_gc_start(hub); diff --git a/openbsc/src/gprs/gtphub_main.c b/openbsc/src/gprs/gtphub_main.c index 6dd316ace..a330b9d39 100644 --- a/openbsc/src/gprs/gtphub_main.c +++ b/openbsc/src/gprs/gtphub_main.c @@ -83,22 +83,15 @@ static const struct log_info gtphub_log_info = { void log_cfg(struct gtphub_cfg *cfg) { struct gtphub_cfg_addr *a; - a = &cfg->to_sgsns[GTPH_PLANE_CTRL].bind; - LOGP(DGTPHUB, LOGL_NOTICE, - "to-SGSNs bind, Control: %s port %d\n", - a->addr_str, a->port); - a = &cfg->to_sgsns[GTPH_PLANE_USER].bind; - LOGP(DGTPHUB, LOGL_NOTICE, - "to-SGSNs bind, User: %s port %d\n", - a->addr_str, a->port); - a = &cfg->to_ggsns[GTPH_PLANE_CTRL].bind; - LOGP(DGTPHUB, LOGL_NOTICE, - "to-GGSNs bind, Control: %s port %d\n", - a->addr_str, a->port); - a = &cfg->to_ggsns[GTPH_PLANE_USER].bind; - LOGP(DGTPHUB, LOGL_NOTICE, - "to-GGSNs bind, User: %s port %d\n", - a->addr_str, a->port); + int side_idx, plane_idx; + for_each_side_and_plane(side_idx, plane_idx) { + a = &cfg->to_gsns[side_idx][plane_idx].bind; + LOGP(DGTPHUB, LOGL_NOTICE, + "to-%ss bind, %s: %s port %d\n", + gtphub_side_idx_names[side_idx], + gtphub_plane_idx_names[plane_idx], + a->addr_str, a->port); + } } static void signal_handler(int signal) diff --git a/openbsc/src/gprs/gtphub_vty.c b/openbsc/src/gprs/gtphub_vty.c index 5e5c1ddf7..e79cdd00e 100644 --- a/openbsc/src/gprs/gtphub_vty.c +++ b/openbsc/src/gprs/gtphub_vty.c @@ -80,17 +80,17 @@ static int config_write_gtphub(struct vty *vty) vty_out(vty, "gtphub%s", VTY_NEWLINE); write_addrs(vty, "bind-to-sgsns", - &g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind, - &g_cfg->to_sgsns[GTPH_PLANE_USER].bind); + &g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].bind, + &g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].bind); write_addrs(vty, "bind-to-ggsns", - &g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind, - &g_cfg->to_ggsns[GTPH_PLANE_USER].bind); + &g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].bind, + &g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].bind); - if (g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str) { + if (g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) { write_addrs(vty, "ggsn-proxy", - &g_cfg->ggsn_proxy[GTPH_PLANE_CTRL], - &g_cfg->ggsn_proxy[GTPH_PLANE_USER]); + &g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], + &g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER]); } return CMD_SUCCESS; @@ -123,9 +123,9 @@ DEFUN(cfg_gtphub_bind_to_sgsns_short, cfg_gtphub_bind_to_sgsns_short_cmd, { int i; for_each_plane(i) - g_cfg->to_sgsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->to_sgsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; + g_cfg->to_gsns[GTPH_SIDE_SGSN][i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; return CMD_SUCCESS; } @@ -138,9 +138,9 @@ DEFUN(cfg_gtphub_bind_to_ggsns_short, cfg_gtphub_bind_to_ggsns_short_cmd, { int i; for_each_plane(i) - g_cfg->to_ggsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->to_ggsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; + g_cfg->to_gsns[GTPH_SIDE_GGSN][i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; return CMD_SUCCESS; } @@ -161,7 +161,7 @@ DEFUN(cfg_gtphub_bind_to_sgsns, cfg_gtphub_bind_to_sgsns_cmd, BIND_DOCS ) { - return handle_binds(g_cfg->to_sgsns, argv); + return handle_binds(g_cfg->to_gsns[GTPH_SIDE_SGSN], argv); } DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd, @@ -171,7 +171,7 @@ DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd, BIND_DOCS ) { - return handle_binds(g_cfg->to_ggsns, argv); + return handle_binds(g_cfg->to_gsns[GTPH_SIDE_GGSN], argv); } DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd, @@ -181,10 +181,10 @@ DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd, "Remote IP address (v4 or v6)\n" ) { - g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; return CMD_SUCCESS; } @@ -195,10 +195,10 @@ DEFUN(cfg_gtphub_ggsn_proxy, cfg_gtphub_ggsn_proxy_cmd, BIND_DOCS ) { - g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]); - g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); - g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].port = atoi(argv[1]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); + g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].port = atoi(argv[3]); return CMD_SUCCESS; } @@ -209,10 +209,10 @@ DEFUN(cfg_gtphub_sgsn_proxy_short, cfg_gtphub_sgsn_proxy_short_cmd, "Remote IP address (v4 or v6)\n" ) { - g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; return CMD_SUCCESS; } @@ -223,10 +223,10 @@ DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd, BIND_DOCS ) { - g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]); - g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); - g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].port = atoi(argv[1]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); + g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].port = atoi(argv[3]); return CMD_SUCCESS; } @@ -258,13 +258,13 @@ static void show_bind_stats_all(struct vty *vty) vty_out(vty, "- %s Plane:%s", gtphub_plane_idx_names[plane_idx], VTY_NEWLINE); - struct gtphub_bind *b = &g_hub->to_ggsns[plane_idx]; + struct gtphub_bind *b = &g_hub->to_gsns[GTPH_SIDE_GGSN][plane_idx]; vty_out(vty, " - to/from GGSNs: %s port %d%s", gsn_addr_to_str(&b->local_addr), (int)b->local_port, VTY_NEWLINE); vty_out_rate_ctr_group(vty, " ", b->counters_io); - b = &g_hub->to_sgsns[plane_idx]; + b = &g_hub->to_gsns[GTPH_SIDE_SGSN][plane_idx]; vty_out(vty, " - to/from SGSNs: %s port %d%s", gsn_addr_to_str(&b->local_addr), (int)b->local_port, VTY_NEWLINE); diff --git a/openbsc/tests/gtphub/gtphub_test.c b/openbsc/tests/gtphub/gtphub_test.c index 8347f3b74..b0ede11b9 100644 --- a/openbsc/tests/gtphub/gtphub_test.c +++ b/openbsc/tests/gtphub/gtphub_test.c @@ -444,7 +444,7 @@ struct gtphub_peer_port *__wrap_gtphub_resolve_ggsn_addr(struct gtphub *hub, &resolved_ggsn_addr) == 0); struct gtphub_peer_port *pp; - pp = gtphub_port_have(hub, &hub->to_ggsns[GTPH_PLANE_CTRL], + pp = gtphub_port_have(hub, &hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], &resolved_gsna, resolved_port); printf("- __wrap_gtphub_resolve_ggsn_addr():\n" " returning GGSN addr from imsi %s ni %s: %s\n", @@ -584,13 +584,13 @@ static int setup_test_hub() gtphub_init(hub); /* Tell this mock gtphub its local address for this test. */ - LVL2_ASSERT(gsn_addr_from_str(&hub->to_sgsns[GTPH_PLANE_CTRL].local_addr, + LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].local_addr, "127.0.1.1") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_sgsns[GTPH_PLANE_USER].local_addr, + LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].local_addr, "127.0.1.2") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_ggsns[GTPH_PLANE_CTRL].local_addr, + LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].local_addr, "127.0.2.1") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_ggsns[GTPH_PLANE_USER].local_addr, + LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].local_addr, "127.0.2.2") == 0); hub->restart_counter = 0x23; @@ -604,10 +604,10 @@ static int setup_test_hub() #define GGSNS_USER_FD 2 #define SGSNS_CTRL_FD 3 #define SGSNS_USER_FD 4 - hub->to_ggsns[GTPH_PLANE_CTRL].ofd.priv_nr = GGSNS_CTRL_FD; - hub->to_ggsns[GTPH_PLANE_USER].ofd.priv_nr = GGSNS_USER_FD; - hub->to_sgsns[GTPH_PLANE_CTRL].ofd.priv_nr = SGSNS_CTRL_FD; - hub->to_sgsns[GTPH_PLANE_USER].ofd.priv_nr = SGSNS_USER_FD; + hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].ofd.priv_nr = GGSNS_CTRL_FD; + hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].ofd.priv_nr = GGSNS_USER_FD; + hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].ofd.priv_nr = SGSNS_CTRL_FD; + hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].ofd.priv_nr = SGSNS_USER_FD; return 1; } @@ -619,11 +619,11 @@ static int clear_test_hub() int plane_idx; plane_idx = GTPH_PLANE_CTRL; - LVL2_ASSERT(llist_empty(&hub->to_ggsns[plane_idx].peers)); - LVL2_ASSERT(llist_empty(&hub->to_sgsns[plane_idx].peers)); + LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_GGSN][plane_idx].peers)); + LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_SGSN][plane_idx].peers)); plane_idx = GTPH_PLANE_USER; - LVL2_ASSERT(llist_empty(&hub->to_ggsns[plane_idx].peers)); - LVL2_ASSERT(llist_empty(&hub->to_sgsns[plane_idx].peers)); + LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_GGSN][plane_idx].peers)); + LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_SGSN][plane_idx].peers)); gtphub_free(hub); return 1; @@ -689,16 +689,16 @@ static void test_echo(void) to_ofd = NULL; ZERO_STRUCT(&to_addr); - send = gtphub_from_sgsns_handle_buf(hub, GTPH_PLANE_CTRL, &sgsn_sender, - buf, msg(gtp_ping_from_sgsn), now, - &reply_buf, &to_ofd, &to_addr); + send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, GTPH_PLANE_CTRL, + &sgsn_sender, buf, msg(gtp_ping_from_sgsn), + now, &reply_buf, &to_ofd, &to_addr); OSMO_ASSERT(send > 0); OSMO_ASSERT(to_addr.l); OSMO_ASSERT(same_addr(&to_addr, &sgsn_sender)); OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == SGSNS_CTRL_FD)); OSMO_ASSERT(reply_is(gtp_pong_to_sgsn)); - pp = gtphub_port_find_sa(&hub->to_sgsns[GTPH_PLANE_CTRL], + pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL], &sgsn_sender); /* We don't record Echo peers. */ OSMO_ASSERT(!pp); @@ -724,15 +724,15 @@ static void test_echo(void) to_ofd = NULL; ZERO_STRUCT(&to_addr); - send = gtphub_from_ggsns_handle_buf(hub, GTPH_PLANE_CTRL, &ggsn_sender, - buf, msg(gtp_ping_from_ggsn), now, - &reply_buf, &to_ofd, &to_addr); + send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, GTPH_PLANE_CTRL, + &ggsn_sender, buf, msg(gtp_ping_from_ggsn), + now, &reply_buf, &to_ofd, &to_addr); OSMO_ASSERT(send > 0); OSMO_ASSERT(same_addr(&to_addr, &ggsn_sender)); OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == GGSNS_CTRL_FD)); OSMO_ASSERT(reply_is(gtp_pong_to_ggsn)); - pp = gtphub_port_find_sa(&hub->to_ggsns[GTPH_PLANE_CTRL], + pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], &sgsn_sender); OSMO_ASSERT(!pp); @@ -741,30 +741,30 @@ static void test_echo(void) to_ofd = NULL; ZERO_STRUCT(&to_addr); - send = gtphub_from_sgsns_handle_buf(hub, GTPH_PLANE_USER, &sgsn_sender, - buf, msg(gtp_ping_from_sgsn), now, - &reply_buf, &to_ofd, &to_addr); + send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, GTPH_PLANE_USER, + &sgsn_sender, buf, msg(gtp_ping_from_sgsn), + now, &reply_buf, &to_ofd, &to_addr); OSMO_ASSERT(send > 0); OSMO_ASSERT(to_addr.l); OSMO_ASSERT(same_addr(&to_addr, &sgsn_sender)); OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == SGSNS_USER_FD)); OSMO_ASSERT(reply_is(gtp_pong_to_sgsn)); - pp = gtphub_port_find_sa(&hub->to_sgsns[GTPH_PLANE_USER], + pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER], &sgsn_sender); OSMO_ASSERT(!pp); to_ofd = NULL; ZERO_STRUCT(&to_addr); - send = gtphub_from_ggsns_handle_buf(hub, GTPH_PLANE_USER, &ggsn_sender, - buf, msg(gtp_ping_from_ggsn), now, - &reply_buf, &to_ofd, &to_addr); + send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, GTPH_PLANE_USER, + &ggsn_sender, buf, msg(gtp_ping_from_ggsn), + now, &reply_buf, &to_ofd, &to_addr); OSMO_ASSERT(send > 0); OSMO_ASSERT(same_addr(&to_addr, &ggsn_sender)); OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == GGSNS_USER_FD)); OSMO_ASSERT(reply_is(gtp_pong_to_ggsn)); - pp = gtphub_port_find_sa(&hub->to_ggsns[GTPH_PLANE_USER], + pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER], &sgsn_sender); OSMO_ASSERT(!pp); @@ -859,9 +859,9 @@ static int msg_from_sgsn(int plane_idx, struct osmo_fd *ggsn_ofd = NULL; struct osmo_sockaddr ggsn_addr; int send; - send = gtphub_from_sgsns_handle_buf(hub, plane_idx, _sgsn_sender, buf, - msg(hex_from_sgsn), now, - &reply_buf, &ggsn_ofd, &ggsn_addr); + send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, plane_idx, _sgsn_sender, + buf, msg(hex_from_sgsn), now, + &reply_buf, &ggsn_ofd, &ggsn_addr); LVL2_ASSERT(send > 0); LVL2_ASSERT(same_addr(&ggsn_addr, ggsn_receiver)); LVL2_ASSERT(reply_is(hex_to_ggsn)); @@ -879,9 +879,9 @@ static int msg_from_ggsn(int plane_idx, struct osmo_fd *sgsn_ofd; struct osmo_sockaddr sgsn_addr; int send; - send = gtphub_from_ggsns_handle_buf(hub, plane_idx, ggsn_sender, buf, - msg(msg_from_ggsn), now, - &reply_buf, &sgsn_ofd, &sgsn_addr); + 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)); @@ -962,7 +962,7 @@ static void test_create_pdp_ctx(void) OSMO_ASSERT(create_pdp_ctx()); struct gtphub_peer_port *ggsn_port = - gtphub_port_find_sa(&hub->to_ggsns[GTPH_PLANE_CTRL], + gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], &resolved_ggsn_addr); OSMO_ASSERT(ggsn_port); struct gtphub_peer *ggsn = ggsn_port->peer_addr->peer; |