cosmetic: reduce dup in tunnel struct definitions

Use a common struct upf_tun_ep and struct upf_tun for both tunend and
tunmap definitions, with a nicer local / remote sub-structuring.

Change-Id: I07866e2acbeb74914e1fd6f66839a5a8ae247b1e
This commit is contained in:
Neels Janosch Hofmeyr
2023-02-09 01:54:18 +01:00
parent 75c07af406
commit 0a87f42f10
9 changed files with 139 additions and 94 deletions

View File

@@ -7,5 +7,6 @@ noinst_HEADERS = \
upf_gtp.h \
upf_gtpu_echo.h \
upf_nft.h \
upf_tun.h \
up_gtp_action.h \
$(NULL)

View File

@@ -27,6 +27,8 @@
#include <osmocom/core/select.h>
#include <osmocom/core/logging.h>
#include <osmocom/upf/upf_tun.h>
#define LOG_GTP_DEV(DEV, LEVEL, FMT, ARGS...) \
LOGP(DGTP, LEVEL, "%s: " FMT, upf_gtp_dev_to_str_c(OTC_SELECT, (DEV)), ##ARGS)
@@ -58,12 +60,7 @@ struct upf_gtp_dev {
/* Description of a GTP encapsulation / decapsulation.
* The active state to operate the GTP kernel module accordingly is kept in struct upf_gtp_tunend. */
struct upf_tunend {
struct {
struct osmo_sockaddr gtp_local_addr;
uint32_t local_teid;
struct osmo_sockaddr gtp_remote_addr;
uint32_t remote_teid;
} access;
struct upf_tun access;
struct {
struct osmo_sockaddr ue_local_addr;
} core;

View File

@@ -25,23 +25,16 @@
#include <stdint.h>
#include <osmocom/core/socket.h>
#include <osmocom/upf/upf_tun.h>
struct upf_nft_tun {
struct upf_tun tun;
uint32_t chain_id;
};
struct upf_tunmap {
struct {
struct osmo_sockaddr gtp_local_addr;
uint32_t local_teid;
struct osmo_sockaddr gtp_remote_addr;
uint32_t remote_teid;
uint32_t chain_id;
} access;
struct {
struct osmo_sockaddr gtp_local_addr;
uint32_t local_teid;
struct osmo_sockaddr gtp_remote_addr;
uint32_t remote_teid;
uint32_t chain_id;
} core;
struct upf_nft_tun access;
struct upf_nft_tun core;
};
int upf_nft_tunmap_to_str_buf(char *buf, size_t buflen, const struct upf_tunmap *tunmap);

View File

@@ -0,0 +1,38 @@
/*
* (C) 2023 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/>.
*
*/
#pragma once
#include <stdint.h>
#include <osmocom/core/socket.h>
struct upf_tun_ep {
struct osmo_sockaddr addr;
uint32_t teid;
};
struct upf_tun {
struct upf_tun_ep local;
struct upf_tun_ep remote;
};

View File

@@ -48,11 +48,11 @@ int up_gtp_action_cmp(const struct up_gtp_action *a, const struct up_gtp_action
switch (a->kind) {
case UP_GTP_U_TUNEND:
if ((cmp = CMP_MEMB(tunend.access.local_teid)))
if ((cmp = CMP_MEMB(tunend.access.local.teid)))
return cmp;
if ((cmp = CMP_MEMB(tunend.access.remote_teid)))
if ((cmp = CMP_MEMB(tunend.access.remote.teid)))
return cmp;
cmp = osmo_sockaddr_cmp(&a->tunend.access.gtp_remote_addr, &b->tunend.access.gtp_remote_addr);
cmp = osmo_sockaddr_cmp(&a->tunend.access.remote.addr, &b->tunend.access.remote.addr);
if (cmp)
return cmp;
cmp = osmo_sockaddr_cmp(&a->tunend.core.ue_local_addr, &b->tunend.core.ue_local_addr);
@@ -61,13 +61,13 @@ int up_gtp_action_cmp(const struct up_gtp_action *a, const struct up_gtp_action
break;
case UP_GTP_U_TUNMAP:
if ((cmp = CMP_MEMB(tunmap.access.local_teid)))
if ((cmp = CMP_MEMB(tunmap.access.tun.local.teid)))
return cmp;
if ((cmp = CMP_MEMB(tunmap.access.remote_teid)))
if ((cmp = CMP_MEMB(tunmap.access.tun.remote.teid)))
return cmp;
if ((cmp = CMP_MEMB(tunmap.core.local_teid)))
if ((cmp = CMP_MEMB(tunmap.core.tun.local.teid)))
return cmp;
if ((cmp = CMP_MEMB(tunmap.core.remote_teid)))
if ((cmp = CMP_MEMB(tunmap.core.tun.remote.teid)))
return cmp;
break;
default:
@@ -91,7 +91,7 @@ static int up_gtp_action_enable_disable(struct up_gtp_action *a, bool enable)
}
/* Pick GTP device matching the local F-TEID set up for the GTP tunnel (it is on the Access side) */
gtp_addr = &a->tunend.access.gtp_local_addr;
gtp_addr = &a->tunend.access.local.addr;
gtp_dev = upf_gtp_dev_find_by_local_addr(gtp_addr);
if (!gtp_dev) {
LOG_UP_GTP_ACTION(a, LOGL_ERROR, "No GTP device open for local address %s, cannot %s"
@@ -158,26 +158,26 @@ int up_gtp_action_to_str_buf(char *buf, size_t buflen, const struct up_gtp_actio
switch (a->kind) {
case UP_GTP_U_TUNEND:
OSMO_STRBUF_PRINTF(sb, "GTP:tunend GTP-access-r:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunend.access.gtp_remote_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-r:0x%"PRIx32, a->tunend.access.remote_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunend.access.remote.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-r:0x%"PRIx32, a->tunend.access.remote.teid);
OSMO_STRBUF_PRINTF(sb, " GTP-access-l:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunend.access.gtp_local_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-l:0x%"PRIx32" IP-core-l:", a->tunend.access.local_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunend.access.local.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-l:0x%"PRIx32" IP-core-l:", a->tunend.access.local.teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunend.core.ue_local_addr);
break;
case UP_GTP_U_TUNMAP:
OSMO_STRBUF_PRINTF(sb, "GTP:tunmap GTP-access-r:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.access.gtp_remote_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-r:0x%"PRIx32, a->tunmap.access.remote_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.access.tun.remote.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-r:0x%"PRIx32, a->tunmap.access.tun.remote.teid);
OSMO_STRBUF_PRINTF(sb, " GTP-access-l:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.access.gtp_local_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-l:0x%"PRIx32, a->tunmap.access.local_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.access.tun.local.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-access-l:0x%"PRIx32, a->tunmap.access.tun.local.teid);
OSMO_STRBUF_PRINTF(sb, " GTP-core-r:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.core.gtp_remote_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-core-r:0x%"PRIx32, a->tunmap.core.remote_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.core.tun.remote.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-core-r:0x%"PRIx32, a->tunmap.core.tun.remote.teid);
OSMO_STRBUF_PRINTF(sb, " GTP-core-l:");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.core.gtp_local_addr);
OSMO_STRBUF_PRINTF(sb, " TEID-core-l:0x%"PRIx32, a->tunmap.core.local_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &a->tunmap.core.tun.local.addr);
OSMO_STRBUF_PRINTF(sb, " TEID-core-l:0x%"PRIx32, a->tunmap.core.tun.local.teid);
break;
case UP_GTP_DROP:
OSMO_STRBUF_PRINTF(sb, "GTP:drop");

View File

@@ -1227,10 +1227,14 @@ static void add_gtp_action_tunend(void *ctx, struct llist_head *dst, struct pdr
.kind = UP_GTP_U_TUNEND,
.tunend = {
.access = {
.gtp_local_addr = pdr->local_f_teid->fixed.ip_addr.v4,
.local_teid = pdr->local_f_teid->fixed.teid,
.gtp_remote_addr = rfar_forw->outer_header_creation.ip_addr.v4,
.remote_teid = rfar_forw->outer_header_creation.teid,
.local = {
.addr = pdr->local_f_teid->fixed.ip_addr.v4,
.teid = pdr->local_f_teid->fixed.teid,
},
.remote = {
.addr = rfar_forw->outer_header_creation.ip_addr.v4,
.teid = rfar_forw->outer_header_creation.teid,
},
},
.core = {
.ue_local_addr = rpdr->desc.pdi.ue_ip_address.ip_addr.v4,
@@ -1336,17 +1340,25 @@ static void add_gtp_action_tunmap(void *ctx, struct llist_head *dst, struct pdr
.pdr_core = rpdr->desc.pdr_id,
.kind = UP_GTP_U_TUNMAP,
.tunmap = {
.access = {
.gtp_local_addr = pdr->local_f_teid->fixed.ip_addr.v4,
.local_teid = pdr->local_f_teid->fixed.teid,
.gtp_remote_addr = rfar_forw->outer_header_creation.ip_addr.v4,
.remote_teid = rfar_forw->outer_header_creation.teid,
.access.tun = {
.local = {
.addr = pdr->local_f_teid->fixed.ip_addr.v4,
.teid = pdr->local_f_teid->fixed.teid,
},
.remote = {
.addr = rfar_forw->outer_header_creation.ip_addr.v4,
.teid = rfar_forw->outer_header_creation.teid,
},
},
.core = {
.gtp_local_addr = rpdr->local_f_teid->fixed.ip_addr.v4,
.local_teid = rpdr->local_f_teid->fixed.teid,
.gtp_remote_addr = far_forw->outer_header_creation.ip_addr.v4,
.remote_teid = far_forw->outer_header_creation.teid,
.core.tun = {
.local = {
.addr = rpdr->local_f_teid->fixed.ip_addr.v4,
.teid = rpdr->local_f_teid->fixed.teid,
},
.remote = {
.addr = far_forw->outer_header_creation.ip_addr.v4,
.teid = far_forw->outer_header_creation.teid,
},
},
},
};

View File

@@ -320,9 +320,9 @@ static int upf_gtp_tunend_to_str_buf(char *buf, size_t buflen, const struct upf_
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
/* "tunend{dev=apn0 access(GTP-r=1.2.3.4 TEID:l=0x1234,r=0x5678) core(UE-l=10.9.8.7)}" */
OSMO_STRBUF_PRINTF(sb, "tunend{dev=%s access(GTP-r=", tun->dev->name);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tun->desc.access.gtp_remote_addr);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tun->desc.access.remote.addr);
OSMO_STRBUF_PRINTF(sb, " TEID:l=0x%x,r=0x%x) core(UE-l=",
tun->desc.access.local_teid, tun->desc.access.remote_teid);
tun->desc.access.local.teid, tun->desc.access.remote.teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tun->desc.core.ue_local_addr);
OSMO_STRBUF_PRINTF(sb, ")}");
return sb.chars_needed;
@@ -345,8 +345,8 @@ static int upf_gtp_tunend_destruct(struct upf_gtp_tunend *tun)
#define tunend_validate(TUNEND) \
do { \
OSMO_ASSERT(osmo_sockaddr_port(&(TUNEND)->access.gtp_local_addr.u.sa) == 0); \
OSMO_ASSERT(osmo_sockaddr_port(&(TUNEND)->access.gtp_remote_addr.u.sa) == 0); \
OSMO_ASSERT(osmo_sockaddr_port(&(TUNEND)->access.local.addr.u.sa) == 0); \
OSMO_ASSERT(osmo_sockaddr_port(&(TUNEND)->access.remote.addr.u.sa) == 0); \
OSMO_ASSERT(osmo_sockaddr_port(&(TUNEND)->core.ue_local_addr.u.sa) == 0); \
} while (0)
@@ -369,7 +369,7 @@ static struct gtp_tunnel *upf_gtp_tunend_to_gtp_tunnel(struct upf_gtp_tunend *tu
struct gtp_tunnel *t;
if (tun->desc.core.ue_local_addr.u.sas.ss_family != AF_INET
|| tun->desc.access.gtp_remote_addr.u.sas.ss_family != AF_INET) {
|| tun->desc.access.remote.addr.u.sas.ss_family != AF_INET) {
LOG_GTP_TUN(tun, LOGL_ERROR, "Only capabale of IPv4\n");
return NULL;
}
@@ -378,9 +378,9 @@ static struct gtp_tunnel *upf_gtp_tunend_to_gtp_tunnel(struct upf_gtp_tunend *tu
OSMO_ASSERT(t);
gtp_tunnel_set_ifidx(t, tun->dev->ifidx);
gtp_tunnel_set_version(t, GTP_V1);
gtp_tunnel_set_i_tei(t, tun->desc.access.local_teid);
gtp_tunnel_set_o_tei(t, tun->desc.access.remote_teid);
gtp_tunnel_set_sgsn_ip4(t, &tun->desc.access.gtp_remote_addr.u.sin.sin_addr);
gtp_tunnel_set_i_tei(t, tun->desc.access.local.teid);
gtp_tunnel_set_o_tei(t, tun->desc.access.remote.teid);
gtp_tunnel_set_sgsn_ip4(t, &tun->desc.access.remote.addr.u.sin.sin_addr);
gtp_tunnel_set_ms_ip4(t, &tun->desc.core.ue_local_addr.u.sin.sin_addr);
return t;
}
@@ -503,9 +503,9 @@ int upf_gtp_tunend_cmp(const struct upf_tunend *a, const struct upf_tunend *b)
return 1;
#define CMP_MEMB(MEMB) OSMO_CMP(a->MEMB, b->MEMB)
if ((r = CMP_MEMB(access.local_teid)))
if ((r = CMP_MEMB(access.local.teid)))
return r;
if ((r = CMP_MEMB(access.remote_teid)))
if ((r = CMP_MEMB(access.remote.teid)))
return r;
return osmo_sockaddr_cmp(&a->access.gtp_remote_addr, &b->access.gtp_remote_addr);
return osmo_sockaddr_cmp(&a->access.remote.addr, &b->access.remote.addr);
}

View File

@@ -290,14 +290,14 @@ int upf_nft_tunmap_to_str_buf(char *buf, size_t buflen, const struct upf_tunmap
/* ACCESS 1.1.1.2:0x102 <---> 2.2.2.1:0x201 UPF 2.2.2.3:0x203 <---> 3.3.3.2:0x302 CORE */
OSMO_STRBUF_PRINTF(sb, "ACCESS ");
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->access.gtp_remote_addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x <---> ", tunmap->access.remote_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->access.gtp_local_addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x UPF ", tunmap->access.local_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->core.gtp_local_addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x <---> ", tunmap->core.local_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->core.gtp_remote_addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x CORE", tunmap->core.remote_teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->access.tun.remote.addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x <---> ", tunmap->access.tun.remote.teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->access.tun.local.addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x UPF ", tunmap->access.tun.local.teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->core.tun.local.addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x <---> ", tunmap->core.tun.local.teid);
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &tunmap->core.tun.remote.addr);
OSMO_STRBUF_PRINTF(sb, ":0x%x CORE", tunmap->core.tun.remote.teid);
return sb.chars_needed;
}
@@ -308,25 +308,25 @@ char *upf_nft_tunmap_to_str_c(void *ctx, const struct upf_tunmap *tunmap)
static void upf_nft_args_from_tunmap(struct upf_nft_args *args, const struct upf_tunmap *tunmap)
{
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->access.gtp_remote_addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->access.gtp_local_addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->core.gtp_remote_addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->core.gtp_local_addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->access.tun.remote.addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->access.tun.local.addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->core.tun.remote.addr.u.sa) == 0);
OSMO_ASSERT(osmo_sockaddr_port(&tunmap->core.tun.local.addr.u.sa) == 0);
*args = (struct upf_nft_args){
.table_name = g_upf->nft.table_name,
.peer_a = {
.addr_remote = &tunmap->access.gtp_remote_addr,
.teid_remote = tunmap->access.remote_teid,
.addr_local = &tunmap->access.gtp_local_addr,
.teid_local = tunmap->access.local_teid,
.addr_remote = &tunmap->access.tun.remote.addr,
.teid_remote = tunmap->access.tun.remote.teid,
.addr_local = &tunmap->access.tun.local.addr,
.teid_local = tunmap->access.tun.local.teid,
.chain_id = tunmap->access.chain_id,
},
.peer_b = {
.addr_remote = &tunmap->core.gtp_remote_addr,
.teid_remote = tunmap->core.remote_teid,
.addr_local = &tunmap->core.gtp_local_addr,
.teid_local = tunmap->core.local_teid,
.addr_remote = &tunmap->core.tun.remote.addr,
.teid_remote = tunmap->core.tun.remote.teid,
.addr_local = &tunmap->core.tun.local.addr,
.teid_local = tunmap->core.tun.local.teid,
.chain_id = tunmap->core.chain_id,
},
};

View File

@@ -298,28 +298,32 @@ DEFUN(show_nft_rule_tunmap_example, show_nft_rule_tunmap_example_cmd,
struct osmo_sockaddr_str str = {};
struct upf_tunmap tunmap = {
.access = {
.local_teid = 0x201,
.remote_teid = 0x102,
.tun = {
.local.teid = 0x201,
.remote.teid = 0x102,
},
.chain_id = 123,
},
.core = {
.local_teid = 0x203,
.remote_teid = 0x302,
.tun = {
.local.teid = 0x203,
.remote.teid = 0x302,
},
.chain_id = 321,
},
};
osmo_sockaddr_str_from_str2(&str, "1.1.1.1");
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.access.gtp_remote_addr.u.sas);
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.access.tun.remote.addr.u.sas);
osmo_sockaddr_str_from_str2(&str, "2.2.2.1");
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.access.gtp_local_addr.u.sas);
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.access.tun.local.addr.u.sas);
osmo_sockaddr_str_from_str2(&str, "2.2.2.3");
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.core.gtp_local_addr.u.sas);
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.core.tun.local.addr.u.sas);
osmo_sockaddr_str_from_str2(&str, "3.3.3.3");
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.core.gtp_remote_addr.u.sas);
osmo_sockaddr_str_to_sockaddr(&str, &tunmap.core.tun.remote.addr.u.sas);
vty_out(vty, "%% init verdict map:%s", VTY_NEWLINE);
vty_out(vty, "%s%s", upf_nft_tunmap_get_table_init_str(OTC_SELECT), VTY_NEWLINE);