neels has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-upf/+/30500
)
Change subject: add cfg: tunmap / nft-rule append
......................................................................
add cfg: tunmap / nft-rule append
It can be useful to add 'meta nftrace set 1' to nftables rules to help
analysis / site debugging. Add the possibility to do this by cfg.
Instead of adding the fixed string of 'meta nftrace set 1', allow
appending arbitrary strings to the nftables rules, to accomodate any
other future tweaks that may be useful.
Related: SYS#6192
Change-Id: Ia1fac67108902a48b43d8d1dc184ccf541fd9ba8
---
M include/osmocom/upf/upf.h
M include/osmocom/upf/upf_nft.h
M src/osmo-upf/up_gtp_action.c
M src/osmo-upf/upf.c
M src/osmo-upf/upf_nft.c
M src/osmo-upf/upf_vty.c
M tests/nft-rule.vty
M tests/upf.vty
8 files changed, 153 insertions(+), 15 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-upf refs/changes/00/30500/1
diff --git a/include/osmocom/upf/upf.h b/include/osmocom/upf/upf.h
index 735a724..fd4019c 100644
--- a/include/osmocom/upf/upf.h
+++ b/include/osmocom/upf/upf.h
@@ -66,6 +66,12 @@
struct llist_head devs;
};
+/* Item in an llist of string pointers */
+struct string_listitem {
+ struct llist_head entry;
+ char *str;
+};
+
struct g_upf {
struct ctrl_handle *ctrl;
@@ -100,6 +106,9 @@
char *table_name;
int priority;
uint32_t next_id_state;
+
+ /* list of struct string_listitem */
+ struct llist_head rule_append;
} nft;
struct llist_head netinst;
diff --git a/include/osmocom/upf/upf_nft.h b/include/osmocom/upf/upf_nft.h
index 4cdcb51..8333877 100644
--- a/include/osmocom/upf/upf_nft.h
+++ b/include/osmocom/upf/upf_nft.h
@@ -49,6 +49,7 @@
int upf_nft_init();
int upf_nft_free();
-char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_nft_tunmap_desc *tunmap);
-int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap);
+char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_nft_tunmap_desc *tunmap,
+ const struct llist_head *rule_append);
+int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap, const struct llist_head
*rule_append);
int upf_nft_tunmap_delete(struct upf_nft_tunmap_desc *tunmap);
diff --git a/src/osmo-upf/up_gtp_action.c b/src/osmo-upf/up_gtp_action.c
index 84af8e5..8ce8a6f 100644
--- a/src/osmo-upf/up_gtp_action.c
+++ b/src/osmo-upf/up_gtp_action.c
@@ -130,7 +130,7 @@
return -ENOENT;
}
if (enable)
- rc = upf_nft_tunmap_create(&a->tunmap);
+ rc = upf_nft_tunmap_create(&a->tunmap, &g_upf->nft.rule_append);
else
rc = upf_nft_tunmap_delete(&a->tunmap);
if (rc) {
diff --git a/src/osmo-upf/upf.c b/src/osmo-upf/upf.c
index 0a84799..1476270 100644
--- a/src/osmo-upf/upf.c
+++ b/src/osmo-upf/upf.c
@@ -61,6 +61,7 @@
INIT_LLIST_HEAD(&g_upf->gtp.vty_cfg.devs);
INIT_LLIST_HEAD(&g_upf->gtp.devs);
+ INIT_LLIST_HEAD(&g_upf->nft.rule_append);
INIT_LLIST_HEAD(&g_upf->netinst);
}
diff --git a/src/osmo-upf/upf_nft.c b/src/osmo-upf/upf_nft.c
index a0f005d..bf5d2c7 100644
--- a/src/osmo-upf/upf_nft.c
+++ b/src/osmo-upf/upf_nft.c
@@ -126,9 +126,11 @@
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)
+ const struct upf_nft_args_peer *to_peer,
+ const struct llist_head *rule_append)
{
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 */
@@ -153,12 +155,20 @@
OSMO_STRBUF_PRINTF(sb, " @ih,32,32 set 0x%08x", to_peer->teid_remote);
OSMO_STRBUF_PRINTF(sb, " counter");
+
+ if (rule_append) {
+ struct string_listitem *i;
+ llist_for_each_entry(i, rule_append, entry)
+ OSMO_STRBUF_PRINTF(sb, " %s", i->str);
+ }
+
OSMO_STRBUF_PRINTF(sb, ";\n");
return sb.chars_needed;
}
-static int upf_nft_ruleset_tunmap_create_buf(char *buf, size_t buflen, const struct
upf_nft_args *args)
+static int upf_nft_ruleset_tunmap_create_buf(char *buf, size_t buflen, const struct
upf_nft_args *args,
+ const struct llist_head *rule_append)
{
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
@@ -167,16 +177,17 @@
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);
+ OSMO_STRBUF_APPEND(sb, tunmap_single_direction, args, &args->peer_a,
&args->peer_b, rule_append);
/* And from peer_b to peer_a */
- OSMO_STRBUF_APPEND(sb, tunmap_single_direction, args, &args->peer_b,
&args->peer_a);
+ OSMO_STRBUF_APPEND(sb, tunmap_single_direction, args, &args->peer_b,
&args->peer_a, rule_append);
return sb.chars_needed;
}
-static char *upf_nft_ruleset_tunmap_create_c(void *ctx, const struct upf_nft_args *args)
+static char *upf_nft_ruleset_tunmap_create_c(void *ctx, const struct upf_nft_args *args,
+ const struct llist_head *rule_append)
{
- OSMO_NAME_C_IMPL(ctx, 512, "ERROR", upf_nft_ruleset_tunmap_create_buf, args)
+ OSMO_NAME_C_IMPL(ctx, 512, "ERROR", upf_nft_ruleset_tunmap_create_buf, args,
rule_append)
}
static int upf_nft_ruleset_tunmap_delete_buf(char *buf, size_t buflen, const struct
upf_nft_args *args)
@@ -219,7 +230,8 @@
osmo_sockaddr_set_port(&args->peer_b.addr_local.u.sa, 0);
}
-char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_nft_tunmap_desc *tunmap)
+char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_nft_tunmap_desc *tunmap,
+ const struct llist_head *rule_append)
{
struct upf_nft_args args;
@@ -232,12 +244,12 @@
}
upf_nft_args_from_tunmap_desc(&args, tunmap);
- return upf_nft_ruleset_tunmap_create_c(ctx, &args);
+ return upf_nft_ruleset_tunmap_create_c(ctx, &args, rule_append);
}
-int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap)
+int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap, const struct llist_head
*rule_append)
{
- return upf_nft_run(upf_nft_tunmap_get_ruleset_str(OTC_SELECT, tunmap));
+ return upf_nft_run(upf_nft_tunmap_get_ruleset_str(OTC_SELECT, tunmap, rule_append));
}
int upf_nft_tunmap_delete(struct upf_nft_tunmap_desc *tunmap)
diff --git a/src/osmo-upf/upf_vty.c b/src/osmo-upf/upf_vty.c
index 6d74b21..4c683c8 100644
--- a/src/osmo-upf/upf_vty.c
+++ b/src/osmo-upf/upf_vty.c
@@ -215,6 +215,8 @@
static int config_write_tunmap(struct vty *vty)
{
+ struct string_listitem *i;
+
vty_out(vty, "tunmap%s", VTY_NEWLINE);
if (g_upf->nft.mockup)
@@ -222,6 +224,9 @@
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);
+
+ llist_for_each_entry(i, &g_upf->nft.rule_append, entry)
+ vty_out(vty, " nft-rule tunmap append %s%s", i->str, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -257,6 +262,49 @@
#define NFT_RULE_STR "nftables rule specifics\n"
#define TUNMAP_STR "GTP tunmap use case (a.k.a. forwarding between two GTP
tunnels)\n"
+DEFUN(cfg_tunmap_nft_rule_append, cfg_tunmap_nft_rule_append_cmd,
+ "nft-rule tunmap append .NFT_RULE",
+ NFT_RULE_STR TUNMAP_STR
+ "To each tunmap nft rule, append the given text. For example, 'nft-rule
append meta nftrace set 1' adds the nftables"
+ " instructions 'meta nftrace set 1' to each of the tunmap rules passed
to netfilter. This command is cumulative,"
+ " multiple 'nft-rule append' will append all of the items.\n"
+ "The text to append\n")
+{
+ struct string_listitem *i;
+ i = talloc_zero(g_upf, struct string_listitem);
+ i->str = argv_concat(argv, argc, 0);
+ talloc_steal(i, i->str);
+ llist_add_tail(&i->entry, &g_upf->nft.rule_append);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_tunmap_no_nft_rule_append, cfg_tunmap_no_nft_rule_append_cmd,
+ "no nft-rule tunmap append",
+ NO_STR NFT_RULE_STR TUNMAP_STR
+ "Drop all additions to tunmap nft rules added by earlier 'nft-rule
append' config\n")
+{
+ struct string_listitem *i;
+ while ((i = llist_first_entry_or_null(&g_upf->nft.rule_append, struct
string_listitem, entry))) {
+ llist_del(&i->entry);
+ talloc_free(i);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_nft_rule_append, show_nft_rule_append_cmd,
+ "show nft-rule tunmap append",
+ SHOW_STR NFT_RULE_STR TUNMAP_STR "List all tunmap 'nft-rule append'
entries\n")
+{
+ struct string_listitem *i;
+ if (llist_empty(&g_upf->nft.rule_append)) {
+ vty_out(vty, " no nft-rule tunmap append%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+ llist_for_each_entry(i, &g_upf->nft.rule_append, entry)
+ vty_out(vty, " nft-rule tunmap append %s%s", i->str, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
DEFUN(show_nft_rule_tunmap_example, show_nft_rule_tunmap_example_cmd,
"show nft-rule tunmap example",
SHOW_STR NFT_RULE_STR TUNMAP_STR
@@ -287,7 +335,7 @@
osmo_sockaddr_str_from_str2(&str, "3.3.3.3");
osmo_sockaddr_str_to_sockaddr(&str, &d.core.gtp_remote_addr.u.sas);
- vty_out(vty, "%s%s", upf_nft_tunmap_get_ruleset_str(OTC_SELECT, &d),
VTY_NEWLINE);
+ vty_out(vty, "%s%s", upf_nft_tunmap_get_ruleset_str(OTC_SELECT, &d,
&g_upf->nft.rule_append), VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -449,6 +497,7 @@
install_element_ve(&show_gtp_cmd);
install_element_ve(&show_session_cmd);
install_element_ve(&show_netinst_cmd);
+ install_element_ve(&show_nft_rule_append_cmd);
install_node(&cfg_pfcp_node, config_write_pfcp);
install_element(CONFIG_NODE, &cfg_pfcp_cmd);
@@ -472,6 +521,9 @@
install_element(TUNMAP_NODE, &cfg_tunmap_mockup_cmd);
install_element(TUNMAP_NODE, &cfg_tunmap_no_mockup_cmd);
install_element(TUNMAP_NODE, &cfg_tunmap_table_name_cmd);
+ install_element(TUNMAP_NODE, &cfg_tunmap_nft_rule_append_cmd);
+ install_element(TUNMAP_NODE, &cfg_tunmap_no_nft_rule_append_cmd);
+ install_element(TUNMAP_NODE, &show_nft_rule_append_cmd);
install_element(TUNMAP_NODE, &show_nft_rule_tunmap_example_cmd);
install_node(&cfg_netinst_node, config_write_netinst);
diff --git a/tests/nft-rule.vty b/tests/nft-rule.vty
index f328871..7e8952b 100644
--- a/tests/nft-rule.vty
+++ b/tests/nft-rule.vty
@@ -2,6 +2,52 @@
OsmoUPF# configure terminal
OsmoUPF(config)# tunmap
+OsmoUPF(config-tunmap)# show nft-rule tunmap append
+ no nft-rule tunmap append
+OsmoUPF(config-tunmap)# show nft-rule tunmap example
+add chain inet osmo-upf tunmap123 { type filter hook prerouting priority -300; }
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.1 @ih,32,32 0x00000201
ip saddr set 2.2.2.3 ip daddr set 3.3.3.3 @ih,32,32 set 0x00000302 counter;
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.3 @ih,32,32 0x00000203
ip saddr set 2.2.2.1 ip daddr set 1.1.1.1 @ih,32,32 set 0x00000102 counter;
+
+OsmoUPF(config-tunmap)# nft-rule tunmap append meta nftrace set 1
+OsmoUPF(config-tunmap)# show nft-rule tunmap append
+ nft-rule tunmap append meta nftrace set 1
+OsmoUPF(config-tunmap)# show nft-rule tunmap example
+add chain inet osmo-upf tunmap123 { type filter hook prerouting priority -300; }
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.1 @ih,32,32 0x00000201
ip saddr set 2.2.2.3 ip daddr set 3.3.3.3 @ih,32,32 set 0x00000302 counter meta nftrace
set 1;
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.3 @ih,32,32 0x00000203
ip saddr set 2.2.2.1 ip daddr set 1.1.1.1 @ih,32,32 set 0x00000102 counter meta nftrace
set 1;
+
+OsmoUPF(config-tunmap)# nft-rule tunmap append foo
+OsmoUPF(config-tunmap)# show nft-rule tunmap append
+ nft-rule tunmap append meta nftrace set 1
+ nft-rule tunmap append foo
+OsmoUPF(config-tunmap)# show nft-rule tunmap example
+add chain inet osmo-upf tunmap123 { type filter hook prerouting priority -300; }
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.1 @ih,32,32 0x00000201
ip saddr set 2.2.2.3 ip daddr set 3.3.3.3 @ih,32,32 set 0x00000302 counter meta nftrace
set 1 foo;
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.3 @ih,32,32 0x00000203
ip saddr set 2.2.2.1 ip daddr set 1.1.1.1 @ih,32,32 set 0x00000102 counter meta nftrace
set 1 foo;
+
+OsmoUPF(config-tunmap)# nft-rule tunmap append bar
+OsmoUPF(config-tunmap)# show nft-rule tunmap append
+ nft-rule tunmap append meta nftrace set 1
+ nft-rule tunmap append foo
+ nft-rule tunmap append bar
+OsmoUPF(config-tunmap)# show nft-rule tunmap example
+add chain inet osmo-upf tunmap123 { type filter hook prerouting priority -300; }
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.1 @ih,32,32 0x00000201
ip saddr set 2.2.2.3 ip daddr set 3.3.3.3 @ih,32,32 set 0x00000302 counter meta nftrace
set 1 foo bar;
+add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.3 @ih,32,32 0x00000203
ip saddr set 2.2.2.1 ip daddr set 1.1.1.1 @ih,32,32 set 0x00000102 counter meta nftrace
set 1 foo bar;
+
+OsmoUPF(config-tunmap)# show running-config
+...
+tunmap
+...
+ nft-rule tunmap append meta nftrace set 1
+ nft-rule tunmap append foo
+ nft-rule tunmap append bar
+...
+
+OsmoUPF(config-tunmap)# no nft-rule tunmap append
+OsmoUPF(config-tunmap)# show nft-rule tunmap append
+ no nft-rule tunmap append
OsmoUPF(config-tunmap)# show nft-rule tunmap example
add chain inet osmo-upf tunmap123 { type filter hook prerouting priority -300; }
add rule inet osmo-upf tunmap123 meta l4proto udp ip daddr 2.2.2.1 @ih,32,32 0x00000201
ip saddr set 2.2.2.3 ip daddr set 3.3.3.3 @ih,32,32 set 0x00000302 counter;
diff --git a/tests/upf.vty b/tests/upf.vty
index 8931719..51ebeb3 100644
--- a/tests/upf.vty
+++ b/tests/upf.vty
@@ -52,6 +52,9 @@
mockup
no mockup
table-name TABLE_NAME
+ nft-rule tunmap append .NFT_RULE
+ no nft-rule tunmap append
+ show nft-rule tunmap append
show nft-rule tunmap example
OsmoUPF(config-tunmap)# exit
@@ -61,18 +64,31 @@
mockup
no mockup
table-name TABLE_NAME
+ nft-rule tunmap append .NFT_RULE
+ no nft-rule tunmap append
+ show nft-rule tunmap append
show nft-rule tunmap example
OsmoUPF(config-tunmap)# mockup?
mockup don't actually send rulesets to nftables, just return success
OsmoUPF(config-tunmap)# no ?
- mockup operate nftables rulesets normally
+ mockup operate nftables rulesets normally
+ nft-rule nftables rule specifics
OsmoUPF(config-tunmap)# 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. The default table name is
"osmo-upf".
OsmoUPF(config-tunmap)# table-name ?
TABLE_NAME nft inet table name
+OsmoUPF(config-tunmap)# nft-rule?
+ nft-rule nftables rule specifics
+OsmoUPF(config-tunmap)# nft-rule ?
+ tunmap GTP tunmap use case (a.k.a. forwarding between two GTP tunnels)
+OsmoUPF(config-tunmap)# nft-rule tunmap ?
+ append To each tunmap nft rule, append the given text. For example, 'nft-rule
append meta nftrace set 1' adds the nftables instructions 'meta nftrace set 1'
to each of the tunmap rules passed to netfilter. This command is cumulative, multiple
'nft-rule append' will append all of the items.
+OsmoUPF(config-tunmap)# nft-rule tunmap append ?
+ NFT_RULE The text to append
+
OsmoUPF(config-tunmap)# show?
show Show running system information
OsmoUPF(config-tunmap)# show ?
@@ -82,4 +98,5 @@
OsmoUPF(config-tunmap)# show nft-rule ?
tunmap GTP tunmap use case (a.k.a. forwarding between two GTP tunnels)
OsmoUPF(config-tunmap)# show nft-rule tunmap ?
+ append List all tunmap 'nft-rule append' entries
example Print a complete nftables ruleset for a tunmap filled with example IP
addresses and TEIDs
--
To view, visit
https://gerrit.osmocom.org/c/osmo-upf/+/30500
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: Ia1fac67108902a48b43d8d1dc184ccf541fd9ba8
Gerrit-Change-Number: 30500
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-MessageType: newchange