osmo-upf/src/osmo-upf/upf.c

100 lines
2.8 KiB
C

/*
* (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved.
*
* Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
*
* SPDX-License-Identifier: GPL-2.0+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/core/utils.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/pfcp/pfcp_endpoint.h>
#include <osmocom/upf/upf.h>
#include <osmocom/upf/up_endpoint.h>
#include <osmocom/upf/upf_gtp.h>
struct g_upf *g_upf = NULL;
struct osmo_tdef_group g_upf_tdef_groups[] = {
{ "pfcp", "PFCP endpoint timers", osmo_pfcp_tdefs, },
{}
};
void g_upf_alloc(void *ctx)
{
OSMO_ASSERT(g_upf == NULL);
g_upf = talloc_zero(ctx, struct g_upf);
*g_upf = (struct g_upf){
.pfcp = {
.vty_cfg = {
.local_addr = talloc_strdup(g_upf, UPF_PFCP_LISTEN_DEFAULT),
.local_port = OSMO_PFCP_PORT,
},
},
.nft = {
.priority = -300,
},
.gtp = {
/* TODO: recovery count state file; use lower byte of current time, poor person's random. */
.recovery_count = time(NULL),
},
};
INIT_LLIST_HEAD(&g_upf->gtp.vty_cfg.devs);
INIT_LLIST_HEAD(&g_upf->gtp.devs);
INIT_LLIST_HEAD(&g_upf->netinst);
}
int upf_pfcp_listen()
{
struct osmo_sockaddr_str local_addr_str;
struct osmo_sockaddr local_addr;
OSMO_ASSERT(g_upf);
OSMO_ASSERT(g_upf->pfcp.ep == NULL);
/* Translate address string from VTY config to osmo_sockaddr: first read into osmo_sockaddr_str, then write to
* osmo_sockaddr. */
osmo_sockaddr_str_from_str(&local_addr_str, g_upf->pfcp.vty_cfg.local_addr, g_upf->pfcp.vty_cfg.local_port);
osmo_sockaddr_str_to_sockaddr(&local_addr_str, &local_addr.u.sas);
LOGP(DLPFCP, LOGL_NOTICE, "PFCP: Listening on %s\n", osmo_sockaddr_to_str_c(OTC_SELECT, &local_addr));
g_upf->pfcp.ep = up_endpoint_init(g_upf, &local_addr);
if (!g_upf->pfcp.ep) {
fprintf(stderr, "Failed to allocate PFCP endpoint.\n");
return -1;
}
return 0;
}
int upf_gtp_devs_open()
{
struct tunend_vty_cfg *c = &g_upf->gtp.vty_cfg;
struct tunend_vty_cfg_dev *d;
llist_for_each_entry(d, &c->devs, entry) {
if (upf_gtp_dev_open(d->dev_name, d->create, d->local_addr, false, false))
return -1;
}
return 0;
}