sgsn: Integrate the GSUP client into the SGSN
This commit adds GSUP client configuration (via VTY), connection set up, and real message sending. The following configuration commands are added: - gsup remote-ip A.B.C.D set server IP address - gsup remote-port PORT set server TCP port Ticket: OW#1338 Sponsored-by: On-Waves ehf
This commit is contained in:
parent
bb23dc17f8
commit
39f040d62b
|
@ -305,7 +305,7 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
|
||||||
GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \
|
GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \
|
||||||
)
|
)
|
||||||
|
|
||||||
void gprs_subscr_init(struct sgsn_instance *sgi);
|
int gprs_subscr_init(struct sgsn_instance *sgi);
|
||||||
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
|
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
|
||||||
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
|
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
|
||||||
void gprs_subscr_delete(struct gsm_subscriber *subscr);
|
void gprs_subscr_delete(struct gsm_subscriber *subscr);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <osmocom/gprs/gprs_ns.h>
|
#include <osmocom/gprs/gprs_ns.h>
|
||||||
#include <openbsc/gprs_sgsn.h>
|
#include <openbsc/gprs_sgsn.h>
|
||||||
|
|
||||||
|
struct gprs_gsup_client;
|
||||||
|
|
||||||
enum sgsn_auth_policy {
|
enum sgsn_auth_policy {
|
||||||
SGSN_AUTH_POLICY_OPEN,
|
SGSN_AUTH_POLICY_OPEN,
|
||||||
SGSN_AUTH_POLICY_CLOSED,
|
SGSN_AUTH_POLICY_CLOSED,
|
||||||
|
@ -25,6 +27,9 @@ struct sgsn_config {
|
||||||
|
|
||||||
enum sgsn_auth_policy auth_policy;
|
enum sgsn_auth_policy auth_policy;
|
||||||
struct llist_head imsi_acl;
|
struct llist_head imsi_acl;
|
||||||
|
|
||||||
|
struct sockaddr_in gsup_server_addr;
|
||||||
|
int gsup_server_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sgsn_instance {
|
struct sgsn_instance {
|
||||||
|
@ -38,6 +43,8 @@ struct sgsn_instance {
|
||||||
struct osmo_timer_list gtp_timer;
|
struct osmo_timer_list gtp_timer;
|
||||||
/* GSN instance for libgtp */
|
/* GSN instance for libgtp */
|
||||||
struct gsn_t *gsn;
|
struct gsn_t *gsn;
|
||||||
|
/* Subscriber */
|
||||||
|
struct gprs_gsup_client *gsup_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct sgsn_instance *sgsn;
|
extern struct sgsn_instance *sgsn;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <openbsc/gsm_subscriber.h>
|
#include <openbsc/gsm_subscriber.h>
|
||||||
|
#include <openbsc/gprs_gsup_client.h>
|
||||||
|
|
||||||
#include <openbsc/sgsn.h>
|
#include <openbsc/sgsn.h>
|
||||||
#include <openbsc/gprs_sgsn.h>
|
#include <openbsc/gprs_sgsn.h>
|
||||||
|
@ -28,10 +29,47 @@
|
||||||
|
|
||||||
#include <openbsc/debug.h>
|
#include <openbsc/debug.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
extern void *tall_bsc_ctx;
|
extern void *tall_bsc_ctx;
|
||||||
|
|
||||||
void gprs_subscr_init(struct sgsn_instance *sgi)
|
static int gsup_read_cb(struct gprs_gsup_client *gsupc, struct msgb *msg);
|
||||||
|
|
||||||
|
/* TODO: Some functions are specific to the SGSN, but this file is more general
|
||||||
|
* (it has gprs_* name). Either move these functions elsewhere, split them and
|
||||||
|
* move a part, or replace the gprs_ prefix by sgsn_. The applies to
|
||||||
|
* gprs_subscr_init, gsup_read_cb, and gprs_subscr_tx_gsup_message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int gprs_subscr_init(struct sgsn_instance *sgi)
|
||||||
{
|
{
|
||||||
|
const char *addr_str;
|
||||||
|
|
||||||
|
if (!sgi->cfg.gsup_server_addr.sin_addr.s_addr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr_str = inet_ntoa(sgi->cfg.gsup_server_addr.sin_addr);
|
||||||
|
|
||||||
|
sgi->gsup_client = gprs_gsup_client_create(
|
||||||
|
addr_str, sgi->cfg.gsup_server_port,
|
||||||
|
&gsup_read_cb);
|
||||||
|
|
||||||
|
if (!sgi->gsup_client)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsup_read_cb(struct gprs_gsup_client *gsupc, struct msgb *msg)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = gprs_subscr_rx_gsup_message(msg);
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx)
|
static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx)
|
||||||
|
@ -96,17 +134,21 @@ void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr)
|
||||||
static int gprs_subscr_tx_gsup_message(struct gsm_subscriber *subscr,
|
static int gprs_subscr_tx_gsup_message(struct gsm_subscriber *subscr,
|
||||||
struct gprs_gsup_message *gsup_msg)
|
struct gprs_gsup_message *gsup_msg)
|
||||||
{
|
{
|
||||||
struct msgb *msg = msgb_alloc(4096, __func__);
|
struct msgb *msg = gprs_gsup_msgb_alloc();
|
||||||
|
|
||||||
strncpy(gsup_msg->imsi, subscr->imsi, sizeof(gsup_msg->imsi) - 1);
|
strncpy(gsup_msg->imsi, subscr->imsi, sizeof(gsup_msg->imsi) - 1);
|
||||||
|
|
||||||
gprs_gsup_encode(msg, gsup_msg);
|
gprs_gsup_encode(msg, gsup_msg);
|
||||||
|
|
||||||
LOGMMCTXP(LOGL_INFO, subscr->sgsn_data->mm,
|
LOGMMCTXP(LOGL_INFO, subscr->sgsn_data->mm,
|
||||||
"Sending GSUP NYI, would send: %s\n", msgb_hexdump(msg));
|
"Sending GSUP, will send: %s\n", msgb_hexdump(msg));
|
||||||
msgb_free(msg);
|
|
||||||
|
|
||||||
return -ENOTSUP;
|
if (!sgsn->gsup_client) {
|
||||||
|
msgb_free(msg);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gprs_gsup_client_send(sgsn->gsup_client, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr,
|
static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr,
|
||||||
|
|
|
@ -357,6 +357,12 @@ int main(int argc, char **argv)
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = gprs_subscr_init(&sgsn_inst);
|
||||||
|
if (rc < 0) {
|
||||||
|
LOGP(DGPRS, LOGL_FATAL, "Cannot set up subscriber management\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
rc = gprs_ns_nsip_listen(sgsn_nsi);
|
rc = gprs_ns_nsip_listen(sgsn_nsi);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n");
|
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n");
|
||||||
|
|
|
@ -139,6 +139,12 @@ static int config_write_sgsn(struct vty *vty)
|
||||||
vty_out(vty, " auth-policy %s%s",
|
vty_out(vty, " auth-policy %s%s",
|
||||||
get_value_string(sgsn_auth_pol_strs, g_cfg->auth_policy),
|
get_value_string(sgsn_auth_pol_strs, g_cfg->auth_policy),
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
|
if (g_cfg->gsup_server_addr.sin_addr.s_addr)
|
||||||
|
vty_out(vty, " gsup remote-ip %s%s",
|
||||||
|
inet_ntoa(g_cfg->gsup_server_addr.sin_addr), VTY_NEWLINE);
|
||||||
|
if (g_cfg->gsup_server_port)
|
||||||
|
vty_out(vty, " gsup remote-port %d%s",
|
||||||
|
g_cfg->gsup_server_port, VTY_NEWLINE);
|
||||||
llist_for_each_entry(acl, &g_cfg->imsi_acl, list)
|
llist_for_each_entry(acl, &g_cfg->imsi_acl, list)
|
||||||
vty_out(vty, " imsi-acl add %s%s", acl->imsi, VTY_NEWLINE);
|
vty_out(vty, " imsi-acl add %s%s", acl->imsi, VTY_NEWLINE);
|
||||||
|
|
||||||
|
@ -650,6 +656,29 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN(cfg_gsup_remote_ip, cfg_gsup_remote_ip_cmd,
|
||||||
|
"gsup remote-ip A.B.C.D",
|
||||||
|
"GSUP Parameters\n"
|
||||||
|
"Set the IP address of the remote GSUP server\n"
|
||||||
|
"IPv4 Address\n")
|
||||||
|
{
|
||||||
|
inet_aton(argv[0], &g_cfg->gsup_server_addr.sin_addr);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(cfg_gsup_remote_port, cfg_gsup_remote_port_cmd,
|
||||||
|
"gsup remote-port <0-65535>",
|
||||||
|
"GSUP Parameters\n"
|
||||||
|
"Set the TCP port of the remote GSUP server\n"
|
||||||
|
"Remote TCP port\n")
|
||||||
|
{
|
||||||
|
g_cfg->gsup_server_port = atoi(argv[0]);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sgsn_vty_init(void)
|
int sgsn_vty_init(void)
|
||||||
{
|
{
|
||||||
|
@ -676,6 +705,8 @@ int sgsn_vty_init(void)
|
||||||
install_element(SGSN_NODE, &cfg_ggsn_gtp_version_cmd);
|
install_element(SGSN_NODE, &cfg_ggsn_gtp_version_cmd);
|
||||||
install_element(SGSN_NODE, &cfg_imsi_acl_cmd);
|
install_element(SGSN_NODE, &cfg_imsi_acl_cmd);
|
||||||
install_element(SGSN_NODE, &cfg_auth_policy_cmd);
|
install_element(SGSN_NODE, &cfg_auth_policy_cmd);
|
||||||
|
install_element(SGSN_NODE, &cfg_gsup_remote_ip_cmd);
|
||||||
|
install_element(SGSN_NODE, &cfg_gsup_remote_port_cmd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,11 @@ sgsn_test_LDADD = \
|
||||||
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
||||||
$(top_builddir)/src/gprs/sgsn_auth.o \
|
$(top_builddir)/src/gprs/sgsn_auth.o \
|
||||||
$(top_builddir)/src/gprs/gprs_gsup_messages.o \
|
$(top_builddir)/src/gprs/gprs_gsup_messages.o \
|
||||||
|
$(top_builddir)/src/gprs/gprs_gsup_client.o \
|
||||||
$(top_builddir)/src/gprs/gprs_utils.o \
|
$(top_builddir)/src/gprs/gprs_utils.o \
|
||||||
$(top_builddir)/src/gprs/gprs_subscriber.o \
|
$(top_builddir)/src/gprs/gprs_subscriber.o \
|
||||||
$(top_builddir)/src/libcommon/libcommon.a \
|
$(top_builddir)/src/libcommon/libcommon.a \
|
||||||
|
$(LIBOSMOABIS_LIBS) \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
$(LIBOSMOGB_LIBS) \
|
$(LIBOSMOGB_LIBS) \
|
||||||
|
|
Loading…
Reference in New Issue