neels has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-upf/+/28309
)
Change subject: add nft
......................................................................
add nft
Related: SYS#5599
Change-Id: Ic0d319eb4f98cd51a5999c804c4203ab0bdda650
---
M configure.ac
M include/osmocom/upf/upf.h
M include/osmocom/upf/upf_nft.h
M src/osmo-upf/Makefile.am
M src/osmo-upf/osmo_upf_main.c
M src/osmo-upf/up_gtp_action.c
M src/osmo-upf/up_session.c
M src/osmo-upf/upf.c
A src/osmo-upf/upf_nft.c
M src/osmo-upf/upf_vty.c
10 files changed, 419 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-upf refs/changes/09/28309/1
diff --git a/configure.ac b/configure.ac
index 119aa6c..fea27c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,8 @@
PKG_CHECK_MODULES(LIBOSMOGTLV, libosmo-gtlv >= 0.1.0)
PKG_CHECK_MODULES(LIBOSMOPFCP, libosmo-pfcp >= 0.1.0)
PKG_CHECK_MODULES(LIBGTPNL, libgtpnl >= 1.2.0)
+PKG_CHECK_MODULES(LIBNFTNL, libnftnl >= 1.2.1)
+PKG_CHECK_MODULES(LIBNFTABLES, libnftables >= 1.0.2)
dnl checks for header files
AC_HEADER_STDC
diff --git a/include/osmocom/upf/upf.h b/include/osmocom/upf/upf.h
index b8065dd..49217c6 100644
--- a/include/osmocom/upf/upf.h
+++ b/include/osmocom/upf/upf.h
@@ -33,6 +33,7 @@
struct ctrl_handle;
struct upf_gtp_dev;
+struct nft_ctx;
#define UPF_PFCP_LISTEN_DEFAULT "0.0.0.0"
@@ -72,6 +73,8 @@
struct pfcp_vty_cfg vty_cfg;
struct up_endpoint *ep;
} pfcp;
+
+ /* Tunnel encaps decaps via GTP kernel module */
struct {
/* GTP devices as in osmo-upf.cfg */
struct gtp_vty_cfg vty_cfg;
@@ -82,6 +85,14 @@
struct mnl_socket *nl;
int32_t genl_id;
} gtp;
+
+ /* Tunnel forwarding via linux netfilter */
+ struct {
+ struct nft_ctx *nft_ctx;
+ char *table_name;
+ int priority;
+ uint32_t next_id_state;
+ } nft;
};
extern struct g_upf *g_upf;
@@ -91,6 +102,7 @@
DPEER,
DSESSION,
DGTP,
+ DNFT,
};
void g_upf_alloc(void *ctx);
diff --git a/include/osmocom/upf/upf_nft.h b/include/osmocom/upf/upf_nft.h
index 569eadb..113bfd8 100644
--- a/include/osmocom/upf/upf_nft.h
+++ b/include/osmocom/upf/upf_nft.h
@@ -27,6 +27,8 @@
#include <osmocom/core/socket.h>
+#define NFT_CHAIN_NAME_PREFIX_TUNMAP "tunmap"
+
struct upf_nft_tunmap_desc {
struct {
struct osmo_sockaddr gtp_remote_addr;
diff --git a/src/osmo-upf/Makefile.am b/src/osmo-upf/Makefile.am
index d8aa5a0..1265051 100644
--- a/src/osmo-upf/Makefile.am
+++ b/src/osmo-upf/Makefile.am
@@ -13,11 +13,15 @@
$(LIBOSMOGTLV_CFLAGS) \
$(LIBOSMOPFCP_CFLAGS) \
$(LIBGTPNL_CFLAGS) \
+ $(LIBNFTNL_CFLAGS) \
+ $(LIBNFTABLES_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
$(LIBGTPNL_LDFLAGS) \
+ $(LIBNFTNL_LDFLAGS) \
+ $(LIBNFTABLES_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
$(NULL)
@@ -33,6 +37,7 @@
up_session.c \
upf.c \
upf_gtp.c \
+ upf_nft.c \
upf_vty.c \
$(NULL)
@@ -43,5 +48,7 @@
$(LIBOSMOGTLV_LIBS) \
$(LIBOSMOPFCP_LIBS) \
$(LIBGTPNL_LIBS) \
+ $(LIBNFTNL_LIBS) \
+ $(LIBNFTABLES_LIBS) \
$(COVERAGE_LDFLAGS) \
$(NULL)
diff --git a/src/osmo-upf/osmo_upf_main.c b/src/osmo-upf/osmo_upf_main.c
index 302d957..81102dd 100644
--- a/src/osmo-upf/osmo_upf_main.c
+++ b/src/osmo-upf/osmo_upf_main.c
@@ -44,6 +44,7 @@
#include <osmocom/upf/upf.h>
#include <osmocom/upf/up_endpoint.h>
#include <osmocom/upf/upf_gtp.h>
+#include <osmocom/upf/upf_nft.h>
#define _GNU_SOURCE
#include <getopt.h>
@@ -237,6 +238,12 @@
.enabled = 0, .loglevel = LOGL_NOTICE,
.color = OSMO_LOGCOLOR_PURPLE,
},
+ [DNFT] = {
+ .name = "DNFT",
+ .description = "GTP forwarding rules via linux netfilter",
+ .enabled = 0, .loglevel = LOGL_NOTICE,
+ .color = OSMO_LOGCOLOR_PURPLE,
+ },
};
const struct log_info log_info = {
@@ -330,6 +337,9 @@
if (upf_gtp_devs_open())
return -1;
+ if (upf_nft_init())
+ return -1;
+
if (upf_pfcp_listen())
return -1;
@@ -356,6 +366,8 @@
upf_gtp_genl_close();
+ upf_nft_free();
+
/* Report the heap state of talloc contexts, then free, so both ASAN and Valgrind are
happy... */
talloc_report_full(tall_upf_ctx, stderr);
talloc_free(tall_upf_ctx);
diff --git a/src/osmo-upf/up_gtp_action.c b/src/osmo-upf/up_gtp_action.c
index 840944e..cf5981e 100644
--- a/src/osmo-upf/up_gtp_action.c
+++ b/src/osmo-upf/up_gtp_action.c
@@ -100,9 +100,36 @@
}
LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s GTP tunnel\n", enable ?
"Enabled" : "Disabled");
return 0;
+
case UP_GTP_U_TUNMAP:
- LOG_UP_GTP_ACTION(a, LOGL_ERROR, "TEID translation not yet implemented\n");
- return -ENOTSUP;
+ if (enable && a->tunmap.id != 0) {
+ LOG_UP_GTP_ACTION(a, LOGL_ERROR,
+ "Cannot enable: nft GTP tunnel mapping rule has been enabled before"
+ " as " NFT_CHAIN_NAME_PREFIX_TUNMAP "%u\n", a->tunmap.id);
+ return -EALREADY;
+ }
+ if (!enable && a->tunmap.id == 0) {
+ LOG_UP_GTP_ACTION(a, LOGL_ERROR,
+ "Cannot disable: nft GTP tunnel mapping rule has not been enabled"
+ " (no " NFT_CHAIN_NAME_PREFIX_TUNMAP " id)\n");
+ return -ENOENT;
+ }
+ if (enable)
+ rc = upf_nft_tunmap_create(&a->tunmap);
+ else
+ rc = upf_nft_tunmap_delete(&a->tunmap);
+ if (rc) {
+ LOG_UP_GTP_ACTION(a, LOGL_ERROR,
+ "Failed to %s nft GTP tunnel mapping " NFT_CHAIN_NAME_PREFIX_TUNMAP
"%u:"
+ " %d %s\n", enable ? "enable" : "disable",
a->tunmap.id, rc, strerror(-rc));
+ return rc;
+ }
+ LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s nft GTP tunnel mapping "
NFT_CHAIN_NAME_PREFIX_TUNMAP "%u\n",
+ enable ? "Enabled" : "Disabled", a->tunmap.id);
+ if (!enable)
+ a->tunmap.id = 0;
+ return 0;
+
default:
LOG_UP_GTP_ACTION(a, LOGL_ERROR, "Invalid action\n");
return -ENOTSUP;
diff --git a/src/osmo-upf/up_session.c b/src/osmo-upf/up_session.c
index d1479b1..00299d3 100644
--- a/src/osmo-upf/up_session.c
+++ b/src/osmo-upf/up_session.c
@@ -1141,7 +1141,107 @@
static void add_gtp_action_forw(void *ctx, struct llist_head *dst, struct pdr *pdr)
{
- /* TODO implement GTP forwarding with TEID translation */
+ struct up_session *session = pdr->session;
+ struct up_gtp_action *a;
+ struct pdr *rpdr;
+ struct far *far;
+ struct osmo_pfcp_ie_forw_params *far_forw;
+ struct far *rfar;
+ struct osmo_pfcp_ie_forw_params *rfar_forw;
+
+ OSMO_ASSERT(pdr->far);
+ OSMO_ASSERT(pdr->reverse_pdr);
+ OSMO_ASSERT(pdr->reverse_pdr->far);
+
+ far = pdr->far;
+ far_forw = &far->desc.forw_params;
+ rpdr = pdr->reverse_pdr;
+ rfar = rpdr->far;
+ rfar_forw = &rfar->desc.forw_params;
+
+ /* To decaps, we need to have a local TEID assigned for which to receive GTP packets.
*/
+ /* decaps from CORE */
+ if (!pdr->local_f_teid || pdr->local_f_teid->choose_flag) {
+ log_inactive_pdr_set(pdr, "missing local TEID (CORE side)", pdr);
+ return;
+ }
+ /* decaps from ACCESS */
+ if (!rpdr->local_f_teid || rpdr->local_f_teid->choose_flag) {
+ log_inactive_pdr_set(pdr, "missing local TEID (ACCESS side)", pdr);
+ return;
+ }
+
+ /* To encaps, we need to have a remote TEID assigned to send out in GTP packets, and we
need to know where to
+ * send GTP to. */
+ /* encaps towards ACCESS */
+ if (!far->desc.forw_params_present) {
+ log_inactive_pdr_set(pdr, "missing FAR Forwarding Parameters", pdr);
+ return;
+ }
+ if (!far_forw->outer_header_creation_present) {
+ log_inactive_pdr_set(pdr, "missing FAR Outer Header Creation", pdr);
+ return;
+ }
+ if (!far_forw->outer_header_creation.teid_present) {
+ log_inactive_pdr_set(pdr, "missing TEID in FAR Outer Header Creation", pdr);
+ return;
+ }
+ if (!far_forw->outer_header_creation.ip_addr.v4_present) {
+ log_inactive_pdr_set(pdr, "missing IPv4 in FAR Outer Header Creation", pdr);
+ return;
+ }
+ /* encaps towards CORE */
+ if (!rfar->desc.forw_params_present) {
+ log_inactive_pdr_set(pdr, "missing FAR Forwarding Parameters", rpdr);
+ return;
+ }
+ if (!rfar_forw->outer_header_creation_present) {
+ log_inactive_pdr_set(pdr, "missing FAR Outer Header Creation", rpdr);
+ return;
+ }
+ if (!rfar_forw->outer_header_creation.teid_present) {
+ log_inactive_pdr_set(pdr, "missing TEID in FAR Outer Header Creation",
rpdr);
+ return;
+ }
+ if (!rfar_forw->outer_header_creation.ip_addr.v4_present) {
+ log_inactive_pdr_set(pdr, "missing IPv4 in FAR Outer Header Creation",
rpdr);
+ return;
+ }
+
+ pdr->active = true;
+ far->active = true;
+ rpdr->active = true;
+ rfar->active = true;
+ LOGPFSML(session->fi, LOGL_DEBUG, "Active PDR set: %s\n",
pdr_to_str_c(OTC_SELECT, pdr));
+ LOGPFSML(session->fi, LOGL_DEBUG, "Active PDR set: + %s\n",
pdr_to_str_c(OTC_SELECT, rpdr));
+
+ talloc_free(pdr->inactive_reason);
+ pdr->inactive_reason = NULL;
+ talloc_free(rpdr->inactive_reason);
+ rpdr->inactive_reason = NULL;
+
+ a = talloc(ctx, struct up_gtp_action);
+ OSMO_ASSERT(a);
+ *a = (struct up_gtp_action){
+ .session = session,
+ .pdr_core = pdr->desc.pdr_id,
+ .pdr_access = rpdr->desc.pdr_id,
+ .kind = UP_GTP_U_TUNMAP,
+ .tunmap = {
+ .core = {
+ .local_teid = pdr->local_f_teid->fixed.teid,
+ .remote_teid = rfar_forw->outer_header_creation.teid,
+ .gtp_remote_addr = rfar_forw->outer_header_creation.ip_addr.v4,
+ },
+ .access = {
+ .local_teid = rpdr->local_f_teid->fixed.teid,
+ .remote_teid = far_forw->outer_header_creation.teid,
+ .gtp_remote_addr = far_forw->outer_header_creation.ip_addr.v4,
+ },
+ },
+ };
+
+ llist_add_tail(&a->entry, dst);
}
/* Analyse all PDRs and FARs and find configurations that match either a GTP
encaps/decaps or a GTP forward rule. Add to
@@ -1294,11 +1394,12 @@
{
struct llist_head empty;
INIT_LLIST_HEAD(&empty);
+ /* Call setup_gtp_actions() with an empty list, to clean up all active GTP actions */
setup_gtp_actions(session, &empty);
}
-/* Check whether the Packet Detection and Forwarding Action Rules amount to an
encaps/decaps of GTP or a GTP forwarding,
- * or none of the two. */
+/* Check whether the Packet Detection and Forwarding Action Rules amount to an
encaps/decaps of GTP or a GTP tunnel
+ * mapping, or none of the two. */
static enum osmo_pfcp_cause up_session_setup_gtp(struct up_session *session)
{
enum osmo_pfcp_cause cause;
diff --git a/src/osmo-upf/upf.c b/src/osmo-upf/upf.c
index 234368a..9677147 100644
--- a/src/osmo-upf/upf.c
+++ b/src/osmo-upf/upf.c
@@ -50,6 +50,9 @@
.local_port = OSMO_PFCP_PORT,
},
},
+ .nft = {
+ .priority = -300,
+ },
};
INIT_LLIST_HEAD(&g_upf->gtp.vty_cfg.devs);
diff --git a/src/osmo-upf/upf_nft.c b/src/osmo-upf/upf_nft.c
new file mode 100644
index 0000000..d93dc39
--- /dev/null
+++ b/src/osmo-upf/upf_nft.c
@@ -0,0 +1,207 @@
+/*
+ * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * All Rights Reserved.
+ *
+ * Author: Neels Janosch Hofmeyr <nhofmeyr(a)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 <errno.h>
+#include <nftables/libnftables.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/logging.h>
+
+#include <osmocom/upf/upf.h>
+#include <osmocom/upf/upf_nft.h>
+
+static char *upf_nft_ruleset_table_create(void *ctx, const char *table_name)
+{
+ return talloc_asprintf(ctx, "add table inet %s\n", table_name);
+}
+
+static int upf_nft_run(const char *ruleset)
+{
+ int rc;
+ if (!g_upf->nft.nft_ctx) {
+ rc = upf_nft_init();
+ if (rc)
+ return rc;
+ }
+
+ rc = nft_run_cmd_from_buffer(g_upf->nft.nft_ctx, ruleset);
+ if (rc < 0) {
+ LOGP(DNFT, LOGL_ERROR, "error running nft ruleset: rc=%d ruleset=%s\n",
+ rc, osmo_quote_str_c(OTC_SELECT, ruleset, -1));
+ return -EIO;
+ }
+ return 0;
+}
+
+int upf_nft_init()
+{
+ int rc;
+ g_upf->nft.nft_ctx = nft_ctx_new(NFT_CTX_DEFAULT);
+ if (!g_upf->nft.nft_ctx) {
+ LOGP(DNFT, LOGL_ERROR, "cannot allocate libnftables nft_ctx\n");
+ return -EIO;
+ }
+
+ if (!g_upf->nft.table_name)
+ g_upf->nft.table_name = talloc_strdup(g_upf, "osmo-upf");
+
+ rc = upf_nft_run(upf_nft_ruleset_table_create(OTC_SELECT, g_upf->nft.table_name));
+ if (rc) {
+ LOGP(DNFT, LOGL_ERROR, "Failed to create nft table %s\n",
+ osmo_quote_str_c(OTC_SELECT, g_upf->nft.table_name, -1));
+ return rc;
+ }
+ LOGP(DNFT, LOGL_NOTICE, "Created nft table %s\n", osmo_quote_str_c(OTC_SELECT,
g_upf->nft.table_name, -1));
+ return 0;
+}
+
+int upf_nft_free()
+{
+ if (!g_upf->nft.nft_ctx)
+ return 0;
+ nft_ctx_free(g_upf->nft.nft_ctx);
+ g_upf->nft.nft_ctx = NULL;
+ return 0;
+}
+
+struct upf_nft_args_peer {
+ /* The source IP address in packets received from this peer */
+ const struct osmo_sockaddr *addr;
+ /* The TEID that we send to the peer in GTP packets. */
+ uint32_t teid_remote;
+ /* The TEID that the peer sends to us in GTP packets. */
+ uint32_t teid_local;
+};
+
+struct upf_nft_args {
+ /* global table name */
+ const char *table_name;
+ /* chain name for this specific tunnel mapping */
+ uint32_t chain_id;
+ int priority;
+
+ struct upf_nft_args_peer peer_a;
+ struct upf_nft_args_peer peer_b;
+};
+
+static int tunmap_single_direction(char *buf, size_t buflen,
+ const struct upf_nft_args *args,
+ const struct upf_nft_args_peer *from_peer,
+ const struct upf_nft_args_peer *to_peer)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ OSMO_STRBUF_PRINTF(sb, "add rule inet %s " NFT_CHAIN_NAME_PREFIX_TUNMAP
"%u", args->table_name, args->chain_id);
+
+ /* Match only UDP packets */
+ OSMO_STRBUF_PRINTF(sb, " meta l4proto udp");
+
+ /* Match on packets coming in from from_peer */
+ OSMO_STRBUF_PRINTF(sb, " ip saddr ");
+ OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, from_peer->addr);
+
+ /* Match on the TEID in the header */
+ OSMO_STRBUF_PRINTF(sb, " @ih,32,32 0x%08x", from_peer->teid_local);
+
+ /* Change destination address to to_peer */
+ OSMO_STRBUF_PRINTF(sb, " ip daddr set ");
+ OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, to_peer->addr);
+
+ /* Change the TEID in the header to the one to_peer expects */
+ OSMO_STRBUF_PRINTF(sb, " @ih,32,32 set 0x%08x", to_peer->teid_remote);
+
+ OSMO_STRBUF_PRINTF(sb, " counter\n");
+
+ return sb.chars_needed;
+}
+
+static int upf_nft_ruleset_tunmap_create_buf(char *buf, size_t buflen, const struct
upf_nft_args *args)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+
+ /* Add a chain for this tunnel mapping */
+ OSMO_STRBUF_PRINTF(sb, "add chain inet %s " NFT_CHAIN_NAME_PREFIX_TUNMAP
"%u { type filter hook prerouting priority %d; }\n",
+ args->table_name, args->chain_id, args->priority);
+
+ /* Forwarding from peer_a to peer_b */
+ OSMO_STRBUF_APPEND(sb, tunmap_single_direction, args, &args->peer_a,
&args->peer_b);
+ /* And from peer_b to peer_a */
+ OSMO_STRBUF_APPEND(sb, tunmap_single_direction, args, &args->peer_b,
&args->peer_a);
+
+ return sb.chars_needed;
+}
+
+static char *upf_nft_ruleset_tunmap_create_c(void *ctx, const struct upf_nft_args *args)
+{
+ OSMO_NAME_C_IMPL(ctx, 512, "ERROR", upf_nft_ruleset_tunmap_create_buf, args)
+}
+
+static int upf_nft_ruleset_tunmap_delete_buf(char *buf, size_t buflen, const struct
upf_nft_args *args)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ OSMO_STRBUF_PRINTF(sb, "delete chain inet %s " NFT_CHAIN_NAME_PREFIX_TUNMAP
"%u\n",
+ args->table_name, args->chain_id);
+ return sb.chars_needed;
+}
+
+static char *upf_nft_ruleset_tunmap_delete_c(void *ctx, const struct upf_nft_args *args)
+{
+ OSMO_NAME_C_IMPL(ctx, 64, "ERROR", upf_nft_ruleset_tunmap_delete_buf, args)
+}
+
+static void upf_nft_args_from_tunmap_desc(struct upf_nft_args *args, const struct
upf_nft_tunmap_desc *tunmap)
+{
+ *args = (struct upf_nft_args){
+ .table_name = g_upf->nft.table_name,
+ .chain_id = tunmap->id,
+ .priority = g_upf->nft.priority,
+ .peer_a = {
+ .addr = &tunmap->access.gtp_remote_addr,
+ .teid_remote = tunmap->access.remote_teid,
+ .teid_local = tunmap->access.local_teid,
+ },
+ .peer_b = {
+ .addr = &tunmap->core.gtp_remote_addr,
+ .teid_remote = tunmap->core.remote_teid,
+ .teid_local = tunmap->core.local_teid,
+ },
+ };
+}
+
+int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap)
+{
+ struct upf_nft_args args;
+
+ /* Give this tunnel mapping a new id, returned to the caller so that the tunnel mapping
can be deleted later */
+ g_upf->nft.next_id_state++;
+ tunmap->id = g_upf->nft.next_id_state;
+
+ upf_nft_args_from_tunmap_desc(&args, tunmap);
+ return upf_nft_run(upf_nft_ruleset_tunmap_create_c(OTC_SELECT, &args));
+}
+
+int upf_nft_tunmap_delete(struct upf_nft_tunmap_desc *tunmap)
+{
+ struct upf_nft_args args;
+ upf_nft_args_from_tunmap_desc(&args, tunmap);
+ return upf_nft_run(upf_nft_ruleset_tunmap_delete_c(OTC_SELECT, &args));
+}
diff --git a/src/osmo-upf/upf_vty.c b/src/osmo-upf/upf_vty.c
index 73d86d1..0e51cd4 100644
--- a/src/osmo-upf/upf_vty.c
+++ b/src/osmo-upf/upf_vty.c
@@ -41,6 +41,7 @@
enum upf_vty_node {
PFCP_NODE = _LAST_OSMOVTY_NODE + 1,
GTP_NODE,
+ NFT_NODE,
};
static struct cmd_node cfg_pfcp_node = {
@@ -85,7 +86,7 @@
DEFUN(cfg_gtp, cfg_gtp_cmd,
"gtp",
- "Enter the GTP configuration node\n")
+ "Enter the 'gtp' node to configure GTP kernel module usage\n")
{
vty->node = GTP_NODE;
return CMD_SUCCESS;
@@ -169,6 +170,40 @@
return CMD_SUCCESS;
}
+static struct cmd_node cfg_nft_node = {
+ NFT_NODE,
+ "%s(config-nft)# ",
+ 1,
+};
+
+DEFUN(cfg_nft, cfg_nft_cmd,
+ "nft",
+ "Enter the 'nft' node to configure nftables usage\n")
+{
+ vty->node = NFT_NODE;
+ return CMD_SUCCESS;
+}
+
+static int config_write_nft(struct vty *vty)
+{
+ vty_out(vty, "nft%s", VTY_NEWLINE);
+
+ if (g_upf->nft.table_name && strcmp(g_upf->nft.table_name,
"osmo-upf"))
+ vty_out(vty, " table-name %s%s", g_upf->nft.table_name, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_nft_table_name, cfg_nft_table_name_cmd,
+ "table-name TABLE_NAME",
+ "Set the nft inet table name to create and place GTP tunnel forwarding chains
in"
+ " (as in 'nft add table inet foo'). If multiple instances of osmo-upf
are running on the same system, each"
+ " osmo-upf must have its own table name. Otherwise the names of created
forwarding chains will collide.\n"
+ "nft inet table name\n")
+{
+ osmo_talloc_replace_string(g_upf, &g_upf->nft.table_name, argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(show_pdr, show_pdr_cmd,
"show pdr",
SHOW_STR
@@ -282,5 +317,10 @@
install_element(GTP_NODE, &cfg_gtp_dev_create_cmd);
install_element(GTP_NODE, &cfg_gtp_dev_use_cmd);
install_element(GTP_NODE, &cfg_gtp_dev_del_cmd);
+
+ install_node(&cfg_nft_node, config_write_nft);
+ install_element(CONFIG_NODE, &cfg_nft_cmd);
+
+ install_element(NFT_NODE, &cfg_nft_table_name_cmd);
}
--
To view, visit
https://gerrit.osmocom.org/c/osmo-upf/+/28309
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: Ic0d319eb4f98cd51a5999c804c4203ab0bdda650
Gerrit-Change-Number: 28309
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-MessageType: newchange