tunmap: refactor nft ruleset: fix "martians" and "1024"
Take care of two problems: - limitation of <= 1024 base chains in nftables, so far meaning we can establish at most 1024 GTP tunnel mappings. - mangling of source IP in prerouting so far meaning that the system needs to be configured to permit 'martian' packets The new ruleset separates in pre- and post-routing, so that we set a new destination IP address in pre-routing, and set a new source IP address in post-routing. Hence no problem with martian packet rejection. The new ruleset uses verdict maps, which are more efficient, and do not hit a limit of 1024 as base chains do. Before, the nft rule used one chain id. In the new ruleset, each tunmap now needs two distinct chain ids. Refactor. Related: SYS#6327 SYS#6264 Change-Id: Iccb975a1c0f8a2087f7b7dc4942a6b41f5675a13
This commit is contained in:
parent
fbe70076eb
commit
4e1c680e59
|
@ -110,8 +110,9 @@ struct g_upf {
|
|||
|
||||
struct nft_ctx *nft_ctx;
|
||||
char *table_name;
|
||||
int priority;
|
||||
uint32_t next_id_state;
|
||||
int priority_pre;
|
||||
int priority_post;
|
||||
uint32_t next_chain_id_state;
|
||||
} nft;
|
||||
|
||||
struct llist_head netinst;
|
||||
|
|
|
@ -27,28 +27,32 @@
|
|||
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
#define NFT_CHAIN_NAME_PREFIX_TUNMAP "tunmap"
|
||||
|
||||
struct upf_nft_tunmap_desc {
|
||||
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;
|
||||
/* id as in ruleset name 'tunmap<id>'. If zero, no id has been assigned yet. */
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
int upf_nft_tunmap_to_str_buf(char *buf, size_t buflen, const struct upf_nft_tunmap_desc *tunmap);
|
||||
char *upf_nft_tunmap_to_str_c(void *ctx, const struct upf_nft_tunmap_desc *tunmap);
|
||||
|
||||
int upf_nft_init();
|
||||
int upf_nft_free();
|
||||
|
||||
char *upf_nft_tunmap_get_table_init_str(void *ctx);
|
||||
char *upf_nft_tunmap_get_vmap_init_str(void *ctx);
|
||||
char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_nft_tunmap_desc *tunmap);
|
||||
char *upf_nft_tunmap_get_ruleset_del_str(void *ctx, struct upf_nft_tunmap_desc *tunmap);
|
||||
int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap);
|
||||
int upf_nft_tunmap_delete(struct upf_nft_tunmap_desc *tunmap);
|
||||
|
|
|
@ -107,11 +107,11 @@ static int up_gtp_action_enable_disable(struct up_gtp_action *a, bool enable)
|
|||
else
|
||||
rc = upf_gtp_dev_tunend_del(gtp_dev, &a->tunend);
|
||||
if (rc) {
|
||||
LOG_UP_GTP_ACTION(a, LOGL_ERROR, "Failed to %s GTP tunnel: %d %s\n",
|
||||
enable ? "enable" : "disable", rc, strerror(-rc));
|
||||
LOG_UP_GTP_ACTION(a, LOGL_ERROR, "Failed to %s GTP tunnel (rc=%d)\n",
|
||||
enable ? "enable" : "disable", rc);
|
||||
return rc;
|
||||
}
|
||||
LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s GTP tunnel on dev %s\n", enable ? "Enabled" : "Disabled",
|
||||
LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s tunend on dev %s\n", enable ? "Enabled" : "Disabled",
|
||||
gtp_dev->name);
|
||||
return 0;
|
||||
|
||||
|
@ -122,32 +122,18 @@ static int up_gtp_action_enable_disable(struct up_gtp_action *a, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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 rule id %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 rule 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 %u:"
|
||||
" %d %s\n", enable ? "enable" : "disable", a->tunmap.id, rc, strerror(-rc));
|
||||
LOG_UP_GTP_ACTION(a, LOGL_ERROR, "Failed to %s nft GTP tunnel mapping (rc=%d)\n",
|
||||
enable ? "enable" : "disable", rc);
|
||||
return rc;
|
||||
}
|
||||
LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s nft GTP tunnel mapping %u\n",
|
||||
enable ? "Enabled" : "Disabled", a->tunmap.id);
|
||||
if (!enable)
|
||||
a->tunmap.id = 0;
|
||||
LOG_UP_GTP_ACTION(a, LOGL_NOTICE, "%s tunmap, nft chain IDs: access--%u-> <-%u--core\n",
|
||||
enable ? "Enabled" : "Disabled",
|
||||
a->tunmap.access.chain_id, a->tunmap.core.chain_id);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
|
|
@ -51,7 +51,8 @@ void g_upf_alloc(void *ctx)
|
|||
},
|
||||
},
|
||||
.nft = {
|
||||
.priority = -300,
|
||||
.priority_pre = -300,
|
||||
.priority_post = 400,
|
||||
},
|
||||
.gtp = {
|
||||
/* TODO: recovery count state file; use lower byte of current time, poor person's random. */
|
||||
|
|
|
@ -35,6 +35,30 @@ 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 char *upf_nft_ruleset_vmap_init(void *ctx, const char *table_name, int priority_pre, int priority_post)
|
||||
{
|
||||
/* add chain inet osmo-upf pre { type filter hook prerouting priority -300; policy accept; }
|
||||
* add chain inet osmo-upf post { type filter hook postrouting priority 400; policy accept; }
|
||||
* add map inet osmo-upf tunmap-pre { typeof ip daddr . @ih,32,32 : verdict; }
|
||||
* add map inet osmo-upf tunmap-post { typeof meta mark : verdict; }
|
||||
* add rule inet osmo-upf pre udp dport 2152 ip daddr . @ih,32,32 vmap @tunmap-pre
|
||||
* add rule inet osmo-upf post meta mark vmap @tunmap-post
|
||||
*/
|
||||
return talloc_asprintf(ctx,
|
||||
"add chain inet %s pre { type filter hook prerouting priority %d; policy accept; };\n"
|
||||
"add chain inet %s post { type filter hook postrouting priority %d; policy accept; };\n"
|
||||
"add map inet %s tunmap-pre { typeof ip daddr . @ih,32,32 : verdict; };\n"
|
||||
"add map inet %s tunmap-post { typeof meta mark : verdict; };\n"
|
||||
"add rule inet %s pre udp dport %u ip daddr . @ih,32,32 vmap @tunmap-pre;\n"
|
||||
"add rule inet %s post meta mark vmap @tunmap-post;\n",
|
||||
table_name, priority_pre,
|
||||
table_name, priority_post,
|
||||
table_name,
|
||||
table_name,
|
||||
table_name, PORT_GTP1_U,
|
||||
table_name);
|
||||
}
|
||||
|
||||
static int upf_nft_run(const char *ruleset)
|
||||
{
|
||||
int rc;
|
||||
|
@ -82,13 +106,19 @@ int upf_nft_init()
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
rc = upf_nft_run(upf_nft_ruleset_table_create(OTC_SELECT, g_upf->nft.table_name));
|
||||
rc = upf_nft_run(upf_nft_tunmap_get_table_init_str(OTC_SELECT));
|
||||
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));
|
||||
|
||||
rc = upf_nft_run(upf_nft_tunmap_get_vmap_init_str(OTC_SELECT));
|
||||
if (rc) {
|
||||
LOGP(DNFT, LOGL_ERROR, "Failed to initialize nft verdict map in table %s\n", g_upf->nft.table_name);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -110,53 +140,112 @@ struct upf_nft_args_peer {
|
|||
const struct osmo_sockaddr *addr_local;
|
||||
/* The TEID that the peer sends to us in GTP packets. */
|
||||
uint32_t teid_local;
|
||||
/* The nft chain id that forwards packets received on addr_local,teid_local. Also used for the 'mark' id in
|
||||
* the verdict map ruleset. */
|
||||
uint32_t chain_id;
|
||||
};
|
||||
|
||||
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)
|
||||
static int tunmap_add_single_direction(char *buf, size_t buflen,
|
||||
const struct upf_nft_args *args,
|
||||
bool dir_a2b)
|
||||
{
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||
const struct upf_nft_args_peer *from_peer;
|
||||
const struct upf_nft_args_peer *to_peer;
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s " NFT_CHAIN_NAME_PREFIX_TUNMAP "%u", args->table_name, args->chain_id);
|
||||
if (dir_a2b) {
|
||||
from_peer = &args->peer_a;
|
||||
to_peer = &args->peer_b;
|
||||
} else {
|
||||
from_peer = &args->peer_b;
|
||||
to_peer = &args->peer_a;
|
||||
}
|
||||
|
||||
/* Match only UDP packets */
|
||||
OSMO_STRBUF_PRINTF(sb, " meta l4proto udp");
|
||||
/* # add chain for verdict map in prerouting
|
||||
* add chain inet osmo-upf tunmap-pre-123
|
||||
* # mangle destination address at prerouting
|
||||
* add rule inet osmo-upf tunmap-pre-123 ip daddr set 1.1.1.1 meta mark set 123 counter accept
|
||||
*
|
||||
* # add chain for verdict map in postrouting
|
||||
* add chain inet osmo-upf tunmap-post-123
|
||||
* # mangle source address and GTP TID at postrouting
|
||||
* add rule inet osmo-upf tunmap-post-123 ip saddr set 2.2.2.1 @ih,32,32 set 0x00000102 counter accept
|
||||
*
|
||||
* # add elements to verdict map, jump to chain
|
||||
* add element inet osmo-upf tunmap-pre { 2.2.2.3 . 0x00000203 : jump tunmap-pre-123 }
|
||||
* add element inet osmo-upf tunmap-post { 123 : jump tunmap-post-123 }
|
||||
*/
|
||||
|
||||
/* Match on packets coming in at specific local IP */
|
||||
OSMO_STRBUF_PRINTF(sb, " ip daddr ");
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, from_peer->addr_local);
|
||||
OSMO_STRBUF_PRINTF(sb, "add chain inet %s tunmap-pre-%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
/* Match on the TEID in the header */
|
||||
OSMO_STRBUF_PRINTF(sb, " @ih,32,32 0x%08x", from_peer->teid_local);
|
||||
|
||||
/* Change outgoing address to local IP on outgoing interface */
|
||||
OSMO_STRBUF_PRINTF(sb, " ip saddr set ");
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, to_peer->addr_local);
|
||||
|
||||
/* Change destination address to to_peer */
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s tunmap-pre-%u",
|
||||
args->table_name, from_peer->chain_id);
|
||||
OSMO_STRBUF_PRINTF(sb, " ip daddr set ");
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, to_peer->addr_remote);
|
||||
OSMO_STRBUF_PRINTF(sb, " meta mark set %u counter accept;\n", from_peer->chain_id);
|
||||
|
||||
/* 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, "add chain inet %s tunmap-post-%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, " counter");
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s tunmap-post-%u",
|
||||
args->table_name, from_peer->chain_id);
|
||||
OSMO_STRBUF_PRINTF(sb, " ip saddr set ");
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, to_peer->addr_local);
|
||||
OSMO_STRBUF_PRINTF(sb, " @ih,32,32 set 0x%x", to_peer->teid_remote);
|
||||
OSMO_STRBUF_PRINTF(sb, " counter accept;\n");
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, " accept");
|
||||
OSMO_STRBUF_PRINTF(sb, ";\n");
|
||||
OSMO_STRBUF_PRINTF(sb, "add element inet %s tunmap-pre { ",
|
||||
args->table_name);
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, from_peer->addr_local);
|
||||
OSMO_STRBUF_PRINTF(sb, " . 0x%x : jump tunmap-pre-%u };\n",
|
||||
from_peer->teid_local, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add element inet %s tunmap-post { %u : jump tunmap-post-%u };\n",
|
||||
args->table_name, from_peer->chain_id, from_peer->chain_id);
|
||||
|
||||
return sb.chars_needed;
|
||||
}
|
||||
|
||||
static int tunmap_del_single_direction(char *buf, size_t buflen,
|
||||
const struct upf_nft_args *args,
|
||||
bool dir_a2b)
|
||||
{
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||
const struct upf_nft_args_peer *from_peer;
|
||||
|
||||
if (dir_a2b)
|
||||
from_peer = &args->peer_a;
|
||||
else
|
||||
from_peer = &args->peer_b;
|
||||
|
||||
/* delete element inet osmo-upf tunmap-pre { 2.2.2.3 . 0x203 }
|
||||
* delete element inet osmo-upf tunmap-post { 123 }
|
||||
* delete chain inet osmo-upf tunmap-pre-123
|
||||
* delete chain inet osmo-upf tunmap-post-123
|
||||
*/
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete element inet %s tunmap-pre { ",
|
||||
args->table_name);
|
||||
OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, from_peer->addr_local);
|
||||
OSMO_STRBUF_PRINTF(sb, " . 0x%x };\n", from_peer->teid_local);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete element inet %s tunmap-post { %u };\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s tunmap-pre-%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s tunmap-post-%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
return sb.chars_needed;
|
||||
}
|
||||
|
@ -165,34 +254,56 @@ static int upf_nft_ruleset_tunmap_create_buf(char *buf, size_t buflen, const str
|
|||
{
|
||||
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);
|
||||
OSMO_STRBUF_APPEND(sb, tunmap_add_single_direction, args, true);
|
||||
/* 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_add_single_direction, args, false);
|
||||
|
||||
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)
|
||||
OSMO_NAME_C_IMPL(ctx, 1024, "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);
|
||||
|
||||
/* Forwarding from peer_a to peer_b */
|
||||
OSMO_STRBUF_APPEND(sb, tunmap_del_single_direction, args, true);
|
||||
/* And from peer_b to peer_a */
|
||||
OSMO_STRBUF_APPEND(sb, tunmap_del_single_direction, args, false);
|
||||
|
||||
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)
|
||||
OSMO_NAME_C_IMPL(ctx, 512, "ERROR", upf_nft_ruleset_tunmap_delete_buf, args)
|
||||
}
|
||||
|
||||
int upf_nft_tunmap_to_str_buf(char *buf, size_t buflen, const struct upf_nft_tunmap_desc *tunmap)
|
||||
{
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||
|
||||
/* 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);
|
||||
return sb.chars_needed;
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_to_str_c(void *ctx, const struct upf_nft_tunmap_desc *tunmap)
|
||||
{
|
||||
OSMO_NAME_C_IMPL(ctx, 128, "ERROR", upf_nft_tunmap_to_str_buf, tunmap)
|
||||
}
|
||||
|
||||
static void upf_nft_args_from_tunmap_desc(struct upf_nft_args *args, const struct upf_nft_tunmap_desc *tunmap)
|
||||
|
@ -204,39 +315,62 @@ static void upf_nft_args_from_tunmap_desc(struct upf_nft_args *args, const struc
|
|||
|
||||
*args = (struct upf_nft_args){
|
||||
.table_name = g_upf->nft.table_name,
|
||||
.chain_id = tunmap->id,
|
||||
.priority = g_upf->nft.priority,
|
||||
.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,
|
||||
.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,
|
||||
.chain_id = tunmap->core.chain_id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_table_init_str(void *ctx)
|
||||
{
|
||||
return upf_nft_ruleset_table_create(ctx, g_upf->nft.table_name);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_vmap_init_str(void *ctx)
|
||||
{
|
||||
return upf_nft_ruleset_vmap_init(ctx, g_upf->nft.table_name, g_upf->nft.priority_pre,
|
||||
g_upf->nft.priority_post);
|
||||
}
|
||||
|
||||
static uint32_t chain_id_next(void)
|
||||
{
|
||||
g_upf->nft.next_chain_id_state++;
|
||||
if (!g_upf->nft.next_chain_id_state)
|
||||
g_upf->nft.next_chain_id_state++;
|
||||
return g_upf->nft.next_chain_id_state;
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_str(void *ctx, 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 */
|
||||
if (!tunmap->id) {
|
||||
g_upf->nft.next_id_state++;
|
||||
if (!g_upf->nft.next_id_state)
|
||||
g_upf->nft.next_id_state++;
|
||||
tunmap->id = g_upf->nft.next_id_state;
|
||||
}
|
||||
if (!tunmap->access.chain_id)
|
||||
tunmap->access.chain_id = chain_id_next();
|
||||
if (!tunmap->core.chain_id)
|
||||
tunmap->core.chain_id = chain_id_next();
|
||||
|
||||
upf_nft_args_from_tunmap_desc(&args, tunmap);
|
||||
return upf_nft_ruleset_tunmap_create_c(ctx, &args);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_del_str(void *ctx, struct upf_nft_tunmap_desc *tunmap)
|
||||
{
|
||||
struct upf_nft_args args;
|
||||
upf_nft_args_from_tunmap_desc(&args, tunmap);
|
||||
return upf_nft_ruleset_tunmap_delete_c(ctx, &args);
|
||||
}
|
||||
|
||||
int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap)
|
||||
{
|
||||
return upf_nft_run(upf_nft_tunmap_get_ruleset_str(OTC_SELECT, tunmap));
|
||||
|
@ -244,7 +378,5 @@ int upf_nft_tunmap_create(struct upf_nft_tunmap_desc *tunmap)
|
|||
|
||||
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));
|
||||
return upf_nft_run(upf_nft_tunmap_get_ruleset_del_str(OTC_SELECT, tunmap));
|
||||
}
|
||||
|
|
|
@ -300,12 +300,13 @@ DEFUN(show_nft_rule_tunmap_example, show_nft_rule_tunmap_example_cmd,
|
|||
.access = {
|
||||
.local_teid = 0x201,
|
||||
.remote_teid = 0x102,
|
||||
.chain_id = 123,
|
||||
},
|
||||
.core = {
|
||||
.local_teid = 0x203,
|
||||
.remote_teid = 0x302,
|
||||
.chain_id = 321,
|
||||
},
|
||||
.id = 123,
|
||||
};
|
||||
|
||||
osmo_sockaddr_str_from_str2(&str, "1.1.1.1");
|
||||
|
@ -320,7 +321,14 @@ DEFUN(show_nft_rule_tunmap_example, show_nft_rule_tunmap_example_cmd,
|
|||
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, "%% init verdict map:%s", VTY_NEWLINE);
|
||||
vty_out(vty, "%s%s", upf_nft_tunmap_get_table_init_str(OTC_SELECT), VTY_NEWLINE);
|
||||
vty_out(vty, "%s%s", upf_nft_tunmap_get_vmap_init_str(OTC_SELECT), VTY_NEWLINE);
|
||||
vty_out(vty, "%% add tunmap:%s", VTY_NEWLINE);
|
||||
vty_out(vty, "%% %s%s", upf_nft_tunmap_to_str_c(OTC_SELECT, &d), VTY_NEWLINE);
|
||||
vty_out(vty, "%s%s", upf_nft_tunmap_get_ruleset_str(OTC_SELECT, &d), VTY_NEWLINE);
|
||||
vty_out(vty, "%% delete tunmap:%s", VTY_NEWLINE);
|
||||
vty_out(vty, "%s%s", upf_nft_tunmap_get_ruleset_del_str(OTC_SELECT, &d), VTY_NEWLINE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,40 @@ OsmoUPF# configure terminal
|
|||
OsmoUPF(config)# tunmap
|
||||
|
||||
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 accept;
|
||||
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 accept;
|
||||
% init verdict map:
|
||||
add table inet osmo-upf
|
||||
|
||||
add chain inet osmo-upf pre { type filter hook prerouting priority -300; policy accept; };
|
||||
add chain inet osmo-upf post { type filter hook postrouting priority 400; policy accept; };
|
||||
add map inet osmo-upf tunmap-pre { typeof ip daddr . @ih,32,32 : verdict; };
|
||||
add map inet osmo-upf tunmap-post { typeof meta mark : verdict; };
|
||||
add rule inet osmo-upf pre udp dport 2152 ip daddr . @ih,32,32 vmap @tunmap-pre;
|
||||
add rule inet osmo-upf post meta mark vmap @tunmap-post;
|
||||
|
||||
% add tunmap:
|
||||
% ACCESS 1.1.1.1:0x102 <---> 2.2.2.1:0x201 UPF 2.2.2.3:0x203 <---> 3.3.3.3:0x302 CORE
|
||||
add chain inet osmo-upf tunmap-pre-123;
|
||||
add rule inet osmo-upf tunmap-pre-123 ip daddr set 3.3.3.3 meta mark set 123 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-123;
|
||||
add rule inet osmo-upf tunmap-post-123 ip saddr set 2.2.2.3 @ih,32,32 set 0x302 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 2.2.2.1 . 0x201 : jump tunmap-pre-123 };
|
||||
add element inet osmo-upf tunmap-post { 123 : jump tunmap-post-123 };
|
||||
add chain inet osmo-upf tunmap-pre-321;
|
||||
add rule inet osmo-upf tunmap-pre-321 ip daddr set 1.1.1.1 meta mark set 321 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-321;
|
||||
add rule inet osmo-upf tunmap-post-321 ip saddr set 2.2.2.1 @ih,32,32 set 0x102 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 2.2.2.3 . 0x203 : jump tunmap-pre-321 };
|
||||
add element inet osmo-upf tunmap-post { 321 : jump tunmap-post-321 };
|
||||
|
||||
% delete tunmap:
|
||||
delete element inet osmo-upf tunmap-pre { 2.2.2.1 . 0x201 };
|
||||
delete element inet osmo-upf tunmap-post { 123 };
|
||||
delete chain inet osmo-upf tunmap-pre-123;
|
||||
delete chain inet osmo-upf tunmap-post-123;
|
||||
delete element inet osmo-upf tunmap-pre { 2.2.2.3 . 0x203 };
|
||||
delete element inet osmo-upf tunmap-post { 321 };
|
||||
delete chain inet osmo-upf tunmap-pre-321;
|
||||
delete chain inet osmo-upf tunmap-post-321;
|
||||
|
||||
OsmoUPF(config-tunmap)# show nft-rule tunmap append
|
||||
% deprecated config option: 'show nft-rule tunmap append'
|
||||
|
|
Loading…
Reference in New Issue