mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-upf.git
synced 2025-11-02 13:03:35 +00:00
Compare commits
23 Commits
7d2c272047
...
neels/nftc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7df62a281 | ||
|
|
d9e653c46b | ||
|
|
de1569327f | ||
|
|
a71e1d7c3e | ||
|
|
0e9724e0df | ||
|
|
048fee5059 | ||
|
|
1e4b5aae65 | ||
|
|
a3ee024150 | ||
|
|
97cf37ee7a | ||
|
|
2a5ee44e06 | ||
|
|
3e2cbe57d4 | ||
|
|
5db4af220a | ||
|
|
2aab3f62dd | ||
|
|
2ddb739ee3 | ||
|
|
077eba97ab | ||
|
|
340c1abd44 | ||
|
|
9d56082698 | ||
|
|
44a574b6b6 | ||
|
|
b85a53ccf8 | ||
|
|
50e70f61bb | ||
|
|
61379149d3 | ||
|
|
bbe0cfc8c0 | ||
|
|
f85f180aa6 |
@@ -198,6 +198,7 @@ AC_OUTPUT(
|
||||
include/Makefile
|
||||
include/osmocom/Makefile
|
||||
include/osmocom/upf/Makefile
|
||||
include/osmocom/pfcptool/Makefile
|
||||
src/Makefile
|
||||
src/osmo-upf/Makefile
|
||||
src/osmo-pfcp-tool/Makefile
|
||||
|
||||
8
contrib/perf/osmo-pfcp-tool.cfg
Normal file
8
contrib/perf/osmo-pfcp-tool.cfg
Normal file
@@ -0,0 +1,8 @@
|
||||
log stderr
|
||||
logging level set-all error
|
||||
|
||||
timer pfcp x23 5
|
||||
timer pfcp x24 5000
|
||||
|
||||
local-addr 127.0.0.2
|
||||
listen
|
||||
26
contrib/perf/osmo-upf.cfg
Normal file
26
contrib/perf/osmo-upf.cfg
Normal file
@@ -0,0 +1,26 @@
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print level 1
|
||||
logging print category 1
|
||||
logging print category-hex 0
|
||||
logging print file basename last
|
||||
#logging print timestamp date
|
||||
logging level set-all info
|
||||
|
||||
line vty
|
||||
bind 127.0.0.1
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
|
||||
# PFCP retransmissions
|
||||
timer pfcp x23 0
|
||||
# PFCP response timeout
|
||||
timer pfcp x24 0
|
||||
|
||||
pfcp
|
||||
local-addr 127.0.0.1
|
||||
tunmap
|
||||
table-name osmo-upf
|
||||
tunend
|
||||
dev create apn23 192.168.2.52
|
||||
7
contrib/perf/tunend.vty
Normal file
7
contrib/perf/tunend.vty
Normal file
@@ -0,0 +1,7 @@
|
||||
pfcp-peer 127.0.0.1
|
||||
tx assoc-setup-req
|
||||
sleep 1
|
||||
date
|
||||
n 10000 session create tunend
|
||||
wait responses
|
||||
date
|
||||
34
contrib/perf/tunmap.vty
Normal file
34
contrib/perf/tunmap.vty
Normal file
@@ -0,0 +1,34 @@
|
||||
pfcp-peer 127.0.0.1
|
||||
tx assoc-setup-req
|
||||
sleep 1
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
n 1000 session create tunmap
|
||||
wait responses
|
||||
date
|
||||
97
contrib/perf/upf-1.bt
Normal file
97
contrib/perf/upf-1.bt
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
uprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_fd_cb {
|
||||
@pfcp_rx_start_at = nsecs;
|
||||
}
|
||||
|
||||
uprobe:/usr/local/bin/osmo-upf:up_endpoint_rx_cb {
|
||||
@pfcp_handle_start_at = nsecs;
|
||||
}
|
||||
|
||||
uprobe:/usr/local/lib/libnftables.so.1.1.0:nft_run_cmd_from_buffer {
|
||||
@nft_run_cmd_from_buffer_start_at = nsecs;
|
||||
@nft_run_cmd_from_buffer_us_val = (uint64)0;
|
||||
}
|
||||
|
||||
uretprobe:/usr/local/lib/libnftables.so.1.1.0:nft_run_cmd_from_buffer {
|
||||
@nft_run_cmd_from_buffer_us_val = (nsecs - @nft_run_cmd_from_buffer_start_at)/1000;
|
||||
@nft_run_cmd_from_buffer_us = hist(@nft_run_cmd_from_buffer_us_val);
|
||||
}
|
||||
|
||||
uprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_fd_write_cb {
|
||||
@pfcp_write_cb_start_at = nsecs;
|
||||
@pfcp_write_cb_us_val = (uint64)0;
|
||||
}
|
||||
uretprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_fd_write_cb {
|
||||
@pfcp_write_cb_us_val = (nsecs - @pfcp_write_cb_start_at) / 1000;
|
||||
@pfcp_write_cb_us = hist(@pfcp_write_cb_us_val);
|
||||
}
|
||||
|
||||
uprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_endpoint_tx_data_no_logging {
|
||||
@pfcp_tx_start_at = nsecs;
|
||||
@pfcp_tx_us_val = (uint64)0;
|
||||
}
|
||||
uretprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_endpoint_tx_data_no_logging {
|
||||
@pfcp_tx_us_val = (nsecs - @pfcp_tx_start_at) / 1000;
|
||||
@pfcp_tx_us = hist(@pfcp_tx_us_val);
|
||||
}
|
||||
|
||||
uretprobe:/usr/local/lib/libosmo-pfcp.so.0.1.0:osmo_pfcp_fd_cb {
|
||||
@pfcp_rx_count = @pfcp_rx_count + 1;
|
||||
|
||||
$pfcp_rx_end_at = nsecs;
|
||||
|
||||
|
||||
if (@pfcp_handle_start_at > @pfcp_rx_start_at) {
|
||||
$pfcp_rx_total_us_val = ($pfcp_rx_end_at - @pfcp_rx_start_at) / 1000;
|
||||
|
||||
$pfcp_decode_us_val = (@pfcp_handle_start_at - @pfcp_rx_start_at) / 1000;
|
||||
@pfcp_decode_us = hist($pfcp_decode_us_val);
|
||||
|
||||
$pfcp_decode_percent_val = 100 * $pfcp_decode_us_val / $pfcp_rx_total_us_val;
|
||||
@pfcp_decode_percent = lhist($pfcp_decode_percent_val, 0, 120, 10);
|
||||
|
||||
$pfcp_handle_us_val = ($pfcp_rx_end_at - @pfcp_handle_start_at) / 1000;
|
||||
@pfcp_handle_us = hist($pfcp_handle_us_val);
|
||||
|
||||
$pfcp_handle_percent_val = 100 * $pfcp_handle_us_val / $pfcp_rx_total_us_val;
|
||||
@pfcp_handle_percent = lhist($pfcp_handle_percent_val, 0, 120, 10);
|
||||
|
||||
if (@nft_run_cmd_from_buffer_start_at > @pfcp_rx_start_at && @nft_run_cmd_from_buffer_us_val) {
|
||||
$nft_run_cmd_from_buffer_percent_val = 100 * @nft_run_cmd_from_buffer_us_val / $pfcp_rx_total_us_val;
|
||||
@nft_run_cmd_from_buffer_percent = lhist($nft_run_cmd_from_buffer_percent_val, 0, 100, 10);
|
||||
}
|
||||
|
||||
if (@pfcp_tx_start_at > @pfcp_rx_start_at && @pfcp_tx_us_val) {
|
||||
$pfcp_tx_percent_val = 100 * @pfcp_tx_us_val / $pfcp_rx_total_us_val;
|
||||
@pfcp_tx_percent = lhist($pfcp_tx_percent_val, 0, 120, 10);
|
||||
}
|
||||
if (@pfcp_write_cb_start_at > @pfcp_rx_start_at && @pfcp_write_cb_us_val) {
|
||||
$pfcp_write_cb_percent_val = 100 * @pfcp_write_cb_us_val / $pfcp_rx_total_us_val;
|
||||
@pfcp_write_cb_percent = lhist($pfcp_write_cb_percent_val, 0, 120, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interval:s:1 {
|
||||
$pfcp_rx_per_s_val = @pfcp_rx_count;
|
||||
@pfcp_rx_count = 0;
|
||||
@pfcp_rx_per_s = hist($pfcp_rx_per_s_val);
|
||||
}
|
||||
|
||||
interval:s:10 {
|
||||
printf("==========================================================");
|
||||
time("%Y-%m-%d %H:%M:%S\n");
|
||||
print(@pfcp_decode_us);
|
||||
print(@pfcp_handle_us);
|
||||
print(@nft_run_cmd_from_buffer_us);
|
||||
print(@pfcp_tx_us);
|
||||
print(@pfcp_write_cb_us);
|
||||
|
||||
print(@pfcp_decode_percent);
|
||||
print(@pfcp_handle_percent);
|
||||
print(@nft_run_cmd_from_buffer_percent);
|
||||
print(@pfcp_tx_percent);
|
||||
print(@pfcp_write_cb_percent);
|
||||
|
||||
print(@pfcp_rx_per_s);
|
||||
}
|
||||
44
contrib/perf/upf-2.bt
Normal file
44
contrib/perf/upf-2.bt
Normal file
@@ -0,0 +1,44 @@
|
||||
BEGIN {
|
||||
@poll__last_nsecs = nsecs;
|
||||
}
|
||||
|
||||
tracepoint:syscalls:sys_enter_poll /comm == "osmo-upf"/ {
|
||||
$elapsed = (nsecs - @poll__last_nsecs)/1000000;
|
||||
@poll__last_nsecs = nsecs;
|
||||
@poll__ms = hist($elapsed);
|
||||
}
|
||||
|
||||
uprobe:/usr/local/bin/osmo-upf:up_gtp_action_enable {
|
||||
@up_gtp_action_enable__start = nsecs;
|
||||
}
|
||||
|
||||
uprobe:/usr/local/lib/libnftables.so.1.1.0:nft_run_cmd_from_buffer {
|
||||
$up_gtp_action_enable__duration = (nsecs - @up_gtp_action_enable__start)/1000;
|
||||
@up_gtp_action_enable__us = hist($up_gtp_action_enable__duration);
|
||||
|
||||
@nft_run_cmd_from_buffer__start = nsecs;
|
||||
}
|
||||
|
||||
uretprobe:/usr/local/lib/libnftables.so.1.1.0:nft_run_cmd_from_buffer {
|
||||
$nft_run_cmd_from_buffer__duration = (nsecs - @nft_run_cmd_from_buffer__start)/1000000;
|
||||
@nft_run_cmd_from_buffer__ms = hist($nft_run_cmd_from_buffer__duration);
|
||||
}
|
||||
|
||||
uprobe:/usr/local/lib/libosmocore.so.20.0.0:logp2 {
|
||||
@logp2__start = nsecs;
|
||||
}
|
||||
|
||||
uretprobe:/usr/local/lib/libosmocore.so.20.0.0:logp2 {
|
||||
$logp2__duration = (nsecs - @logp2__start)/1000;
|
||||
@logp2__us = hist($logp2__duration);
|
||||
}
|
||||
|
||||
|
||||
interval:s:10 {
|
||||
printf("==========================================================");
|
||||
time("%Y-%m-%d %H:%M:%S\n");
|
||||
print(@poll__ms);
|
||||
print(@logp2__us);
|
||||
print(@up_gtp_action_enable__us);
|
||||
print(@nft_run_cmd_from_buffer__ms);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
SUBDIRS = \
|
||||
upf \
|
||||
pfcptool \
|
||||
$(NULL)
|
||||
|
||||
4
include/osmocom/pfcptool/Makefile.am
Normal file
4
include/osmocom/pfcptool/Makefile.am
Normal file
@@ -0,0 +1,4 @@
|
||||
noinst_HEADERS = \
|
||||
gtp_probe.h \
|
||||
pfcp_tool.h \
|
||||
$(NULL)
|
||||
33
include/osmocom/pfcptool/gtp_probe.h
Normal file
33
include/osmocom/pfcptool/gtp_probe.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
struct pfcp_tool_gtp_tun;
|
||||
|
||||
struct gtp_probe_target {
|
||||
struct osmo_sockaddr_str cfg;
|
||||
|
||||
struct osmo_sockaddr addr;
|
||||
struct osmo_fd ofd;
|
||||
};
|
||||
|
||||
struct gtp_probe_state {
|
||||
struct gtp_probe_target ip_target;
|
||||
struct gtp_probe_target gtp_target;
|
||||
};
|
||||
|
||||
int gtp_probe_target_bind(struct gtp_probe_state *s, struct gtp_probe_target *t);
|
||||
|
||||
int gtp_probe_bind_ip_target(struct gtp_probe_state *state);
|
||||
int gtp_probe_bind_gtp_target(struct gtp_probe_state *state);
|
||||
|
||||
int gtp_probe_run_tunend(void *ctx,
|
||||
struct gtp_probe_state *s, struct pfcp_tool_gtp_tun *inject_gtp,
|
||||
struct osmo_sockaddr_str *ue_ip,
|
||||
struct gtp_probe_target *expect_rx_on_ip);
|
||||
|
||||
extern unsigned int g_gtp_probes_submitted;
|
||||
extern unsigned int g_gtp_probes_pending;
|
||||
extern unsigned int g_gtp_probes_successful;
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <osmocom/pfcp/pfcp_msg.h>
|
||||
|
||||
#include <osmocom/upf/up_gtp_action.h>
|
||||
#include <osmocom/pfcptool/gtp_probe.h>
|
||||
|
||||
struct osmo_tdef;
|
||||
struct ctrl_handle;
|
||||
@@ -48,6 +49,7 @@ struct pfcp_tool_peer {
|
||||
|
||||
uint64_t next_seid_state;
|
||||
|
||||
/* list of struct pfcp_tool_session */
|
||||
struct llist_head sessions;
|
||||
};
|
||||
|
||||
@@ -57,6 +59,7 @@ struct pfcp_tool_gtp_tun_ep {
|
||||
};
|
||||
|
||||
struct pfcp_tool_gtp_tun {
|
||||
uint16_t local_pdr_id;
|
||||
struct pfcp_tool_gtp_tun_ep local;
|
||||
struct pfcp_tool_gtp_tun_ep remote;
|
||||
};
|
||||
@@ -100,6 +103,16 @@ struct g_pfcp_tool {
|
||||
|
||||
struct osmo_pfcp_endpoint *ep;
|
||||
struct llist_head peers;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
struct pfcp_tool_gtp_tun_ep remote;
|
||||
} access;
|
||||
} gtp_state;
|
||||
|
||||
uint32_t next_ue_addr_state;
|
||||
|
||||
struct gtp_probe_state gtp_probe;
|
||||
};
|
||||
|
||||
extern struct g_pfcp_tool *g_pfcp_tool;
|
||||
@@ -108,7 +121,7 @@ void g_pfcp_tool_alloc(void *ctx);
|
||||
void pfcp_tool_vty_init_cfg();
|
||||
void pfcp_tool_vty_init_cmds();
|
||||
|
||||
int pfcp_tool_mainloop();
|
||||
int pfcp_tool_mainloop(int poll);
|
||||
|
||||
struct pfcp_tool_peer *pfcp_tool_peer_find_or_create(const struct osmo_sockaddr *remote_addr);
|
||||
struct pfcp_tool_session *pfcp_tool_session_find_or_create(struct pfcp_tool_peer *peer, uint64_t cp_seid,
|
||||
@@ -117,3 +130,6 @@ void pfcp_tool_rx_msg(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m, st
|
||||
|
||||
int peer_tx(struct pfcp_tool_peer *peer, struct osmo_pfcp_msg *m);
|
||||
uint64_t peer_new_seid(struct pfcp_tool_peer *peer);
|
||||
|
||||
uint32_t pfcp_tool_new_teid(void);
|
||||
int pfcp_tool_next_ue_addr(struct osmo_sockaddr_str *dst);
|
||||
@@ -44,6 +44,7 @@ struct nft_ctx;
|
||||
#define PORT_GTP1_U 2152
|
||||
|
||||
extern struct osmo_tdef_group g_upf_tdef_groups[];
|
||||
extern struct osmo_tdef g_upf_nft_tdefs[];
|
||||
|
||||
struct pfcp_vty_cfg {
|
||||
char *local_addr;
|
||||
|
||||
@@ -49,3 +49,6 @@ char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_tunmap *tunmap);
|
||||
char *upf_nft_tunmap_get_ruleset_del_str(void *ctx, struct upf_tunmap *tunmap);
|
||||
int upf_nft_tunmap_create(struct upf_tunmap *tunmap);
|
||||
int upf_nft_tunmap_delete(struct upf_tunmap *tunmap);
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_dump_all(void *ctx);
|
||||
char *upf_nft_tunmap_get_ruleset_dump(void *ctx, const char *countername, uint32_t chain_id);
|
||||
|
||||
@@ -22,10 +22,6 @@ AM_LDFLAGS = \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
noinst_HEADERS = \
|
||||
pfcp_tool.h \
|
||||
$(NULL)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
osmo-pfcp-tool \
|
||||
$(NULL)
|
||||
@@ -34,4 +30,6 @@ osmo_pfcp_tool_SOURCES = \
|
||||
osmo_pfcp_tool_main.c \
|
||||
pfcp_tool.c \
|
||||
pfcp_tool_vty.c \
|
||||
gtp_probe.c \
|
||||
checksum.c \
|
||||
$(NULL)
|
||||
|
||||
211
src/osmo-pfcp-tool/checksum.c
Normal file
211
src/osmo-pfcp-tool/checksum.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* IP/TCP/UDP checksumming routines
|
||||
*
|
||||
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
|
||||
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
|
||||
* Tom May, <ftom@netcom.com>
|
||||
* Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
|
||||
* Lots of code moved from tcp.c and ip.c; see those files
|
||||
* for more names.
|
||||
*
|
||||
* 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
|
||||
* Fixed some nasty bugs, causing some horrible crashes.
|
||||
* A: At some points, the sum (%0) was used as
|
||||
* length-counter instead of the length counter
|
||||
* (%1). Thanks to Roman Hodek for pointing this out.
|
||||
* B: GCC seems to mess up if one uses too many
|
||||
* data-registers to hold input values and one tries to
|
||||
* specify d0 and d1 as scratch registers. Letting gcc
|
||||
* choose these registers itself solves the problem.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
|
||||
kills, so most of the assembly has to go. */
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define _KERNEL /* needed on FreeBSD 10.x for s6_addr32 */
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#include "checksum.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
static inline unsigned short from32to16(unsigned int x)
|
||||
{
|
||||
/* add up 16-bit and 16-bit for 16+c bit */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned int do_csum(const unsigned char *buff, int len)
|
||||
{
|
||||
int odd;
|
||||
unsigned int result = 0;
|
||||
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
odd = 1 & (unsigned long) buff;
|
||||
if (odd) {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
result += (*buff << 8);
|
||||
#else
|
||||
result = *buff;
|
||||
#endif
|
||||
len--;
|
||||
buff++;
|
||||
}
|
||||
if (len >= 2) {
|
||||
if (2 & (unsigned long) buff) {
|
||||
result += *(unsigned short *) buff;
|
||||
len -= 2;
|
||||
buff += 2;
|
||||
}
|
||||
if (len >= 4) {
|
||||
const unsigned char *end = buff + ((unsigned)len & ~3);
|
||||
unsigned int carry = 0;
|
||||
do {
|
||||
unsigned int w = *(unsigned int *) buff;
|
||||
buff += 4;
|
||||
result += carry;
|
||||
result += w;
|
||||
carry = (w > result);
|
||||
} while (buff < end);
|
||||
result += carry;
|
||||
result = (result & 0xffff) + (result >> 16);
|
||||
}
|
||||
if (len & 2) {
|
||||
result += *(unsigned short *) buff;
|
||||
buff += 2;
|
||||
}
|
||||
}
|
||||
if (len & 1)
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
result += *buff;
|
||||
#else
|
||||
result += (*buff << 8);
|
||||
#endif
|
||||
result = from32to16(result);
|
||||
if (odd)
|
||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
uint16_t ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
return (uint16_t)~do_csum(iph, ihl*4);
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
uint32_t csum_partial(const void *buff, int len, uint32_t wsum)
|
||||
{
|
||||
unsigned int sum = (unsigned int)wsum;
|
||||
unsigned int result = do_csum(buff, len);
|
||||
|
||||
/* add in old sum, and carry.. */
|
||||
result += sum;
|
||||
if (sum > result)
|
||||
result += 1;
|
||||
return (uint32_t)result;
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||
* in icmp.c
|
||||
*/
|
||||
uint16_t ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return (uint16_t)~do_csum(buff, len);
|
||||
}
|
||||
|
||||
uint16_t csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
uint32_t len, uint8_t proto, uint32_t csum)
|
||||
{
|
||||
int carry;
|
||||
uint32_t ulen;
|
||||
uint32_t uproto;
|
||||
uint32_t sum = (uint32_t)csum;
|
||||
|
||||
sum += (uint32_t)saddr->s6_addr32[0];
|
||||
carry = (sum < (uint32_t)saddr->s6_addr32[0]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)saddr->s6_addr32[1];
|
||||
carry = (sum < (uint32_t)saddr->s6_addr32[1]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)saddr->s6_addr32[2];
|
||||
carry = (sum < (uint32_t)saddr->s6_addr32[2]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)saddr->s6_addr32[3];
|
||||
carry = (sum < (uint32_t)saddr->s6_addr32[3]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)daddr->s6_addr32[0];
|
||||
carry = (sum < (uint32_t)daddr->s6_addr32[0]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)daddr->s6_addr32[1];
|
||||
carry = (sum < (uint32_t)daddr->s6_addr32[1]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)daddr->s6_addr32[2];
|
||||
carry = (sum < (uint32_t)daddr->s6_addr32[2]);
|
||||
sum += carry;
|
||||
|
||||
sum += (uint32_t)daddr->s6_addr32[3];
|
||||
carry = (sum < (uint32_t)daddr->s6_addr32[3]);
|
||||
sum += carry;
|
||||
|
||||
ulen = (uint32_t)htonl((uint32_t) len);
|
||||
sum += ulen;
|
||||
carry = (sum < ulen);
|
||||
sum += carry;
|
||||
|
||||
uproto = (uint32_t)htonl(proto);
|
||||
sum += uproto;
|
||||
carry = (sum < uproto);
|
||||
sum += carry;
|
||||
|
||||
return csum_fold((uint32_t)sum);
|
||||
}
|
||||
|
||||
/* fold a partial checksum */
|
||||
uint16_t csum_fold(uint32_t csum)
|
||||
{
|
||||
uint32_t sum = (uint32_t)csum;
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
return (uint16_t)~sum;
|
||||
}
|
||||
13
src/osmo-pfcp-tool/checksum.h
Normal file
13
src/osmo-pfcp-tool/checksum.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
uint16_t ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
uint32_t csum_partial(const void *buff, int len, uint32_t wsum);
|
||||
uint16_t ip_compute_csum(const void *buff, int len);
|
||||
|
||||
uint16_t csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
uint32_t len, uint8_t proto, uint32_t csum);
|
||||
|
||||
uint16_t csum_fold(uint32_t csum);
|
||||
285
src/osmo-pfcp-tool/gtp_probe.c
Normal file
285
src/osmo-pfcp-tool/gtp_probe.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* (C) 2024 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 <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#include <osmocom/pfcptool/gtp_probe.h>
|
||||
#include <osmocom/pfcptool/pfcp_tool.h>
|
||||
#include "checksum.h"
|
||||
|
||||
void gtp_probe_target_close(struct gtp_probe_target *t)
|
||||
{
|
||||
if (t->ofd.fd > 0) {
|
||||
osmo_fd_unregister(&t->ofd);
|
||||
close(t->ofd.fd);
|
||||
}
|
||||
t->ofd.fd = -1;
|
||||
t->addr = (struct osmo_sockaddr){};
|
||||
}
|
||||
|
||||
LLIST_HEAD(g_expect_probes);
|
||||
unsigned int g_gtp_probes_submitted = 0;
|
||||
unsigned int g_gtp_probes_pending = 0;
|
||||
unsigned int g_gtp_probes_successful = 0;
|
||||
|
||||
struct expect_probe {
|
||||
struct llist_head entry;
|
||||
|
||||
struct osmo_sockaddr from;
|
||||
uint8_t payload[8];
|
||||
size_t payload_len;
|
||||
};
|
||||
|
||||
static int gtp_probe_cb(struct osmo_fd *ofd, unsigned int what)
|
||||
{
|
||||
int rc;
|
||||
struct gtp_probe_state *s = ofd->data;
|
||||
struct osmo_sockaddr remote;
|
||||
socklen_t remote_len = sizeof(remote);
|
||||
struct osmo_sockaddr_str remote_str;
|
||||
char strbuf[64];
|
||||
|
||||
uint8_t rxbuf[2048];
|
||||
size_t rxlen = 0;
|
||||
|
||||
if (!(what & OSMO_FD_READ))
|
||||
return 0;
|
||||
|
||||
rc = recvfrom(ofd->fd, rxbuf, sizeof(rxbuf), 0, (struct sockaddr *)&remote, &remote_len);
|
||||
if (rc <= 0 || rc > sizeof(rxbuf)) {
|
||||
fprintf(stderr, "problem receiving on UDP probe: rc %d > sizeof(rxbuf) %zu\n", rc, sizeof(rxbuf));
|
||||
return -EIO;
|
||||
}
|
||||
rxlen = rc;
|
||||
|
||||
osmo_sockaddr_str_from_sockaddr(&remote_str, &remote.u.sas);
|
||||
|
||||
if (ofd->priv_nr)
|
||||
osmo_escape_cstr_buf(strbuf, sizeof(strbuf), (char *)rxbuf, rxlen);
|
||||
else
|
||||
osmo_hexdump_buf(strbuf, sizeof(strbuf), rxbuf, rc, NULL, false);
|
||||
|
||||
struct expect_probe *p;
|
||||
bool expected = false;
|
||||
llist_for_each_entry (p, &g_expect_probes, entry) {
|
||||
if (rxlen != p->payload_len)
|
||||
continue;
|
||||
if (memcmp(rxbuf, p->payload, p->payload_len))
|
||||
continue;
|
||||
if (osmo_sockaddr_cmp(&remote, &p->from))
|
||||
continue;
|
||||
|
||||
expected = true;
|
||||
llist_del(&p->entry);
|
||||
g_gtp_probes_pending--;
|
||||
g_gtp_probes_successful++;
|
||||
talloc_free(p);
|
||||
break;
|
||||
}
|
||||
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||
"RX %s probe: " OSMO_SOCKADDR_STR_FMT " -> " OSMO_SOCKADDR_STR_FMT
|
||||
" '%s' (%u submitted, %u successful, %u pending)\n",
|
||||
expected ? "expected" : "UNEXPECTED",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&remote_str),
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&s->ip_target.cfg),
|
||||
strbuf,
|
||||
g_gtp_probes_submitted,
|
||||
g_gtp_probes_successful,
|
||||
g_gtp_probes_pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gtp_probe_target_bind(struct gtp_probe_state *s, struct gtp_probe_target *t)
|
||||
{
|
||||
int rc;
|
||||
/* close the existing socket, if any */
|
||||
gtp_probe_target_close(t);
|
||||
|
||||
/* create the new socket, binding to configured local address */
|
||||
t->ofd.data = s;
|
||||
t->ofd.cb = gtp_probe_cb;
|
||||
osmo_sockaddr_str_to_sockaddr(&t->cfg, &t->addr.u.sas);
|
||||
rc = osmo_sock_init_osa_ofd(&t->ofd, SOCK_DGRAM, IPPROTO_UDP, &t->addr, NULL, OSMO_SOCK_F_BIND);
|
||||
if (rc < 0) {
|
||||
t->addr = (struct osmo_sockaddr){};
|
||||
return rc;
|
||||
}
|
||||
LOGP(DLGLOBAL, LOGL_NOTICE, "Bound probe port: " OSMO_SOCKADDR_STR_FMT "\n",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&t->cfg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* According to 3GPP TS 29.060. */
|
||||
struct gtp1u_hdr {
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
uint8_t pn:1, s:1, e:1, spare:1, pt:1, version:3;
|
||||
#else
|
||||
uint8_t version:3, pt:1, spare:1, e:1, s:1, pn:1;
|
||||
#endif
|
||||
uint8_t type;
|
||||
uint16_t length;
|
||||
uint32_t tei;
|
||||
};
|
||||
|
||||
struct gtp_pdu {
|
||||
struct gtp1u_hdr gtp;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
char data[1024];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int gtp_probe_run_tunend(void *ctx,
|
||||
struct gtp_probe_state *s, struct pfcp_tool_gtp_tun *inject_gtp,
|
||||
struct osmo_sockaddr_str *ue_ip,
|
||||
struct gtp_probe_target *expect_rx_on_ip)
|
||||
{
|
||||
int rc;
|
||||
/* remote-GTP this session's ACCESS side gtp_probe UDP
|
||||
* |--------UDP/GTP---->|--------------------------->[...]--->|
|
||||
* | |
|
||||
* inject | expect UDP
|
||||
* from | at the ip_target
|
||||
* remote-GTP-IP:2152 to UPF's F-TEID
|
||||
*/
|
||||
//struct osmo_sockaddr_str *remote_gtp = &inject_gtp->remote.addr;
|
||||
struct osmo_sockaddr_str upf_gtp = inject_gtp->local.addr;
|
||||
upf_gtp.port = 2152;
|
||||
struct osmo_sockaddr sendto_addr;
|
||||
uint32_t upf_rx_teid = inject_gtp->local.teid;
|
||||
struct osmo_sockaddr_str *payload_dst = &expect_rx_on_ip->cfg;
|
||||
struct osmo_sockaddr_str payload_src = *ue_ip;
|
||||
payload_src.port = payload_dst->port;
|
||||
static uint16_t ip_id = 1;
|
||||
|
||||
struct gtp_pdu pdu = {
|
||||
.gtp = {
|
||||
.pn = 0,
|
||||
.s = 0,
|
||||
.e = 0,
|
||||
.spare = 0,
|
||||
.pt = 1,
|
||||
.version = 1,
|
||||
.type = 0xff, /* G-PDU */
|
||||
.length = 0, /* filled in later */
|
||||
.tei = htonl(upf_rx_teid),
|
||||
},
|
||||
.ip = {
|
||||
.ihl = 5,
|
||||
.version = 4,
|
||||
.id = htons(ip_id++),
|
||||
.frag_off = htons(0x4000),
|
||||
.ttl = 64,
|
||||
.protocol = IPPROTO_UDP,
|
||||
},
|
||||
.udp = {
|
||||
.source = htons(payload_src.port),
|
||||
.dest = htons(payload_dst->port),
|
||||
.check = 0, // TODO
|
||||
},
|
||||
.data = "hello!",
|
||||
};
|
||||
size_t data_len = strlen(pdu.data) + 1;
|
||||
|
||||
uint16_t *id = (void *)pdu.data;
|
||||
static uint16_t next_id = 0;
|
||||
*id = next_id++;
|
||||
data_len = 2;
|
||||
|
||||
size_t udp_len = sizeof(pdu.udp) + data_len;
|
||||
size_t ip_len = sizeof(pdu.ip) + udp_len;
|
||||
size_t gtp_len = sizeof(pdu.gtp) + ip_len;
|
||||
uint32_t i32;
|
||||
pdu.gtp.length = htons(gtp_len);
|
||||
pdu.ip.tot_len = htons(ip_len);
|
||||
pdu.udp.len = htons(udp_len);
|
||||
|
||||
g_gtp_probes_submitted++;
|
||||
|
||||
rc = osmo_sockaddr_str_to_32(&payload_src, &i32);
|
||||
if (rc) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "invalid payload source address: " OSMO_SOCKADDR_STR_FMT "\n",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&payload_src));
|
||||
return rc;
|
||||
}
|
||||
pdu.ip.saddr = i32;
|
||||
|
||||
rc = osmo_sockaddr_str_to_32(payload_dst, &i32);
|
||||
if (rc) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "invalid payload destination address: " OSMO_SOCKADDR_STR_FMT "\n",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(payload_dst));
|
||||
return rc;
|
||||
}
|
||||
pdu.ip.daddr = i32;
|
||||
|
||||
#if 0
|
||||
/* Skip GTP tunnel for debugging */
|
||||
upf_gtp = *payload_dst;
|
||||
#endif
|
||||
|
||||
rc = osmo_sockaddr_str_to_sockaddr(&upf_gtp, &sendto_addr.u.sas);
|
||||
if (rc) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "invalid UPF GTP address: " OSMO_SOCKADDR_STR_FMT "\n",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&upf_gtp));
|
||||
return rc;
|
||||
}
|
||||
|
||||
pdu.ip.check = ip_fast_csum(&pdu.ip, pdu.ip.ihl);
|
||||
|
||||
LOGP(DLGLOBAL, LOGL_INFO, "GTP-probe sending: " OSMO_SOCKADDR_STR_FMT " -> " OSMO_SOCKADDR_STR_FMT ":TEID-0x%x:"
|
||||
" payload: UDP " OSMO_SOCKADDR_STR_FMT " -> " OSMO_SOCKADDR_STR_FMT " (now %u probes pending)\n",
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&s->gtp_target.cfg),
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&upf_gtp),
|
||||
upf_rx_teid,
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&payload_src),
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(payload_dst),
|
||||
g_gtp_probes_pending + 1);
|
||||
|
||||
/* add g_expect_probes entry */
|
||||
struct expect_probe *p = talloc_zero(ctx, struct expect_probe);
|
||||
osmo_sockaddr_str_to_osa(&payload_src, &p->from);
|
||||
p->payload_len = data_len;
|
||||
memcpy(p->payload, pdu.data, data_len);
|
||||
llist_add_tail(&p->entry, &g_expect_probes);
|
||||
g_gtp_probes_pending++;
|
||||
|
||||
// FIXME: allow more than just one gtp_target, and figure out here which one to use from remote_gtp above.
|
||||
rc = sendto(s->gtp_target.ofd.fd, (void *)&pdu, gtp_len, 0,
|
||||
&sendto_addr.u.sa, sizeof(sendto_addr));
|
||||
if (rc != gtp_len) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "%s.sendto(%s) failed: rc = %d != length %zu; errno = %d %s\n",
|
||||
osmo_sock_get_name(OTC_SELECT, s->gtp_target.ofd.fd),
|
||||
osmo_sockaddr_to_str_c(OTC_SELECT, &sendto_addr), rc, gtp_len,
|
||||
errno, strerror(errno));
|
||||
llist_del(&p->entry);
|
||||
g_gtp_probes_pending--;
|
||||
talloc_free(p);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include <osmocom/pfcp/pfcp_endpoint.h>
|
||||
|
||||
#include "pfcp_tool.h"
|
||||
#include <osmocom/pfcptool/pfcp_tool.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
@@ -226,14 +226,15 @@ const struct log_info log_info = {
|
||||
.num_cat = ARRAY_SIZE(pfcp_tool_default_categories),
|
||||
};
|
||||
|
||||
int pfcp_tool_mainloop()
|
||||
int pfcp_tool_mainloop(int poll)
|
||||
{
|
||||
int rc;
|
||||
log_reset_context();
|
||||
osmo_select_main_ctx(0);
|
||||
rc = osmo_select_main_ctx(poll);
|
||||
|
||||
/* If the user hits Ctrl-C the third time, just terminate immediately. */
|
||||
if (quit >= 3)
|
||||
return 1;
|
||||
return -1;
|
||||
|
||||
/* Has SIGTERM been received (and not yet been handled)? */
|
||||
if (quit && !osmo_select_shutdown_requested()) {
|
||||
@@ -243,7 +244,7 @@ int pfcp_tool_mainloop()
|
||||
osmo_select_shutdown_request();
|
||||
/* continue the main select loop until all write queues are serviced. */
|
||||
}
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -326,7 +327,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
pfcp_tool_mainloop();
|
||||
pfcp_tool_mainloop(1);
|
||||
|
||||
pfcp_tool_vty_init_cmds();
|
||||
|
||||
@@ -341,14 +342,14 @@ int main(int argc, char **argv)
|
||||
printf("Done reading '%s', waiting for retransmission queue...\n",
|
||||
pfcp_tool_cmdline_config.command_file);
|
||||
do {
|
||||
if (pfcp_tool_mainloop())
|
||||
if (pfcp_tool_mainloop(0) == -1)
|
||||
break;
|
||||
} while (osmo_pfcp_endpoint_retrans_queue_is_busy(g_pfcp_tool->ep));
|
||||
printf("Done\n");
|
||||
} else {
|
||||
printf("Listening for commands on VTY...\n");
|
||||
do {
|
||||
if (pfcp_tool_mainloop())
|
||||
if (pfcp_tool_mainloop(0) == -1)
|
||||
break;
|
||||
} while (!osmo_select_shutdown_done());
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <osmocom/pfcp/pfcp_endpoint.h>
|
||||
|
||||
#include "pfcp_tool.h"
|
||||
#include <osmocom/pfcptool/pfcp_tool.h>
|
||||
|
||||
struct g_pfcp_tool *g_pfcp_tool = NULL;
|
||||
|
||||
@@ -48,6 +48,9 @@ void g_pfcp_tool_alloc(void *ctx)
|
||||
};
|
||||
|
||||
INIT_LLIST_HEAD(&g_pfcp_tool->peers);
|
||||
|
||||
osmo_sockaddr_str_from_str(&g_pfcp_tool->gtp_state.access.remote.addr, "10.99.0.2", 2152);
|
||||
g_pfcp_tool->next_ue_addr_state = 0xc0a90001;
|
||||
}
|
||||
|
||||
struct pfcp_tool_peer *pfcp_tool_peer_find(const struct osmo_sockaddr *remote_addr)
|
||||
@@ -70,7 +73,7 @@ struct pfcp_tool_peer *pfcp_tool_peer_find_or_create(const struct osmo_sockaddr
|
||||
peer->remote_addr = *remote_addr;
|
||||
peer->next_seid_state = 0x1234567;
|
||||
INIT_LLIST_HEAD(&peer->sessions);
|
||||
llist_add(&peer->entry, &g_pfcp_tool->peers);
|
||||
llist_add_tail(&peer->entry, &g_pfcp_tool->peers);
|
||||
return peer;
|
||||
}
|
||||
|
||||
@@ -97,7 +100,7 @@ struct pfcp_tool_session *pfcp_tool_session_find_or_create(struct pfcp_tool_peer
|
||||
.cp_seid = cp_seid,
|
||||
.kind = kind,
|
||||
};
|
||||
llist_add(&session->entry, &peer->sessions);
|
||||
llist_add_tail(&session->entry, &peer->sessions);
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -144,6 +147,32 @@ static void rx_session_est_resp(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_
|
||||
if (!session)
|
||||
return;
|
||||
session->up_f_seid = m->ies.session_est_resp.up_f_seid;
|
||||
|
||||
/* Retrieve the local-F-TEIDs that the UPF has created */
|
||||
for (int i = 0; i < m->ies.session_est_resp.created_pdr_count; i++) {
|
||||
struct osmo_pfcp_ie_created_pdr *cpdr = &m->ies.session_est_resp.created_pdr[i];
|
||||
struct pfcp_tool_gtp_tun_ep *target = NULL;
|
||||
|
||||
if (!cpdr->local_f_teid_present)
|
||||
continue;
|
||||
if (cpdr->local_f_teid.choose_flag)
|
||||
continue;
|
||||
|
||||
switch (session->kind) {
|
||||
case UP_GTP_U_TUNEND:
|
||||
if (session->tunend.access.local_pdr_id == cpdr->pdr_id)
|
||||
target = &session->tunend.access.local;
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (target) {
|
||||
osmo_pfcp_ip_addrs_get_str(&target->addr, NULL, &cpdr->local_f_teid.fixed.ip_addr);
|
||||
target->teid = cpdr->local_f_teid.fixed.teid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pfcp_tool_rx_msg(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m, struct osmo_pfcp_msg *req)
|
||||
@@ -183,3 +212,17 @@ uint64_t peer_new_seid(struct pfcp_tool_peer *peer)
|
||||
{
|
||||
return peer->next_seid_state++;
|
||||
}
|
||||
|
||||
uint32_t pfcp_tool_new_teid(void)
|
||||
{
|
||||
return g_pfcp_tool->gtp_state.access.remote.teid++;
|
||||
}
|
||||
|
||||
int pfcp_tool_next_ue_addr(struct osmo_sockaddr_str *dst)
|
||||
{
|
||||
uint32_t addr = g_pfcp_tool->next_ue_addr_state++;
|
||||
osmo_sockaddr_str_from_32h(dst, addr, 0);
|
||||
printf("XXXXX addr=%u 0x%x htonl=%x %s\n", addr, addr, htonl(addr), dst->ip);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
#include "pfcp_tool.h"
|
||||
#include <osmocom/pfcptool/pfcp_tool.h>
|
||||
|
||||
enum pfcp_tool_vty_node {
|
||||
PEER_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
@@ -97,7 +97,7 @@ DEFUN(c_listen, c_listen_cmd,
|
||||
|
||||
rc = osmo_pfcp_endpoint_bind(g_pfcp_tool->ep);
|
||||
if (rc) {
|
||||
vty_out(vty, "Failed to bind PFCP endpoint on %s: %s%s\n",
|
||||
vty_out(vty, "Failed to bind PFCP endpoint on %s: %s%s",
|
||||
osmo_sockaddr_to_str_c(OTC_SELECT, osmo_pfcp_endpoint_get_local_addr(g_pfcp_tool->ep)),
|
||||
strerror(-rc), VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@@ -108,7 +108,7 @@ DEFUN(c_listen, c_listen_cmd,
|
||||
DEFUN(c_sleep, c_sleep_cmd,
|
||||
"sleep <0-999999> [<0-999>]",
|
||||
"Let some time pass\n"
|
||||
"Seconds to wait\n")
|
||||
"Seconds to wait\n" "Additional milliseconds to wait\n")
|
||||
{
|
||||
int secs = atoi(argv[0]);
|
||||
int msecs = 0;
|
||||
@@ -124,7 +124,7 @@ DEFUN(c_sleep, c_sleep_cmd,
|
||||
|
||||
/* Still operate the message pump while waiting for time to pass */
|
||||
while (t.active && !osmo_select_shutdown_done()) {
|
||||
if (pfcp_tool_mainloop())
|
||||
if (pfcp_tool_mainloop(0) == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,74 @@ DEFUN(c_sleep, c_sleep_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(c_date, c_date_cmd,
|
||||
"date",
|
||||
"print a timestamp\n")
|
||||
{
|
||||
struct timeval tv = {};
|
||||
struct tm tm = {};
|
||||
|
||||
osmo_gettimeofday(&tv, NULL);
|
||||
localtime_r(&tv.tv_sec, &tm);
|
||||
|
||||
vty_out(vty,"%04d-%02d-%02d,%02d:%02d:%02d.%03d%s",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
(int)(tv.tv_usec / 1000), VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define GTP_PROBE_STR "Configure GTP probing parameters\n"
|
||||
|
||||
int gtp_probe_set_target(struct vty *vty, int argc, const char **argv, struct gtp_probe_target *t)
|
||||
{
|
||||
int rc;
|
||||
|
||||
const char *local_ip_str = argv[0];
|
||||
const char *local_port_str = "2152";
|
||||
if (argc > 1) {
|
||||
local_port_str = argv[1];
|
||||
t->ofd.priv_nr = 1;
|
||||
} else {
|
||||
t->ofd.priv_nr = 0;
|
||||
}
|
||||
|
||||
osmo_sockaddr_str_from_str(&t->cfg, local_ip_str, atoi(local_port_str));
|
||||
|
||||
rc = gtp_probe_target_bind(&g_pfcp_tool->gtp_probe, t);
|
||||
if (rc) {
|
||||
vty_out(vty, "Failed to bind for GTP probe on UDP %s %s%s", local_ip_str, local_port_str, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(c_gtp_probe_ip_target, c_gtp_probe_ip_target_cmd,
|
||||
"gtp-probe ip-target ADDR <1-65535>",
|
||||
GTP_PROBE_STR
|
||||
"Set the target address in IP space. osmo-pfcp-tool must be able to bind on this IP address locally. This can"
|
||||
" be used for GTP tunnel endpoints: when injecting some GTP, expect to receive it in IP space by listening on"
|
||||
" this UDP address.\n"
|
||||
"IP address to bind on, to send/receive on for probing.\n"
|
||||
"UDP port to receive on for probing.\n")
|
||||
{
|
||||
OSMO_ASSERT(g_pfcp_tool);
|
||||
return gtp_probe_set_target(vty, argc, argv, &g_pfcp_tool->gtp_probe.ip_target);
|
||||
}
|
||||
|
||||
DEFUN(c_gtp_probe_gtp_target, c_gtp_probe_gtp_target_cmd,
|
||||
"gtp-probe gtp-target ADDR [2152]",
|
||||
GTP_PROBE_STR
|
||||
"For GTP tunnel injection: when injecting GTP-U PDUs into a tunnel, use this GTP endpoint for it."
|
||||
" osmo-pfcp-tool must be able to bind on this IP address locally.\n"
|
||||
"IP address to bind on, to send/receive on for probing.\n"
|
||||
"UDP port to receive on for probing.\n")
|
||||
{
|
||||
OSMO_ASSERT(g_pfcp_tool);
|
||||
return gtp_probe_set_target(vty, argc, argv, &g_pfcp_tool->gtp_probe.gtp_target);
|
||||
}
|
||||
|
||||
static struct cmd_node peer_node = {
|
||||
PEER_NODE,
|
||||
"%s(peer)# ",
|
||||
@@ -397,9 +465,45 @@ DEFUN(s_f_teid_choose, s_f_teid_choose_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
DEFUN(s_gtp_probe_run, s_gtp_probe_run_cmd,
|
||||
"gtp-probe run",
|
||||
"Probe a GTP tunnel: send one payload in each direction and verify reception\n"
|
||||
"Run a GTP probe on this session's GTP tunnel\n")
|
||||
{
|
||||
struct pfcp_tool_session *session = vty->index;
|
||||
int rc;
|
||||
|
||||
switch (session->kind) {
|
||||
case UP_GTP_U_TUNEND:
|
||||
rc = gtp_probe_run_tunend(g_pfcp_tool,
|
||||
&g_pfcp_tool->gtp_probe,
|
||||
&session->tunend.access,
|
||||
&session->tunend.core.ue_local_addr,
|
||||
&g_pfcp_tool->gtp_probe.ip_target);
|
||||
if (rc)
|
||||
return CMD_WARNING;
|
||||
return CMD_SUCCESS;
|
||||
|
||||
case UP_GTP_U_TUNMAP:
|
||||
vty_out(vty, "%% Error: GTP probing for tunmap not implemented%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
enum pdr_id_fixed {
|
||||
PDR_ID_CORE = 1,
|
||||
PDR_ID_ACCESS = 2,
|
||||
};
|
||||
|
||||
const char * const gtp_ip_core = "10.99.0.1";
|
||||
const char * const gtp_ip_access = "10.99.0.2";
|
||||
|
||||
int session_tunend_tx_est_req(struct pfcp_tool_session *session, bool forw, osmo_pfcp_resp_cb resp_cb)
|
||||
{
|
||||
struct pfcp_tool_peer *peer = session->peer;
|
||||
int rc;
|
||||
struct osmo_pfcp_msg *m;
|
||||
@@ -411,27 +515,25 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
|
||||
OSMO_ASSERT(session->kind == UP_GTP_U_TUNEND);
|
||||
|
||||
if (!g_pfcp_tool->ep) {
|
||||
vty_out(vty, "Endpoint not configured%s", VTY_NEWLINE);
|
||||
if (!g_pfcp_tool->ep)
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (argc > 0 && !strcmp("drop", argv[0]))
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
else
|
||||
if (forw)
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_FORW, true);
|
||||
else
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
|
||||
#define STR_TO_ADDR(DST, SRC) do { \
|
||||
if (osmo_sockaddr_str_to_sockaddr(&SRC, &DST.u.sas)) { \
|
||||
vty_out(vty, "Error in " #SRC ": " OSMO_SOCKADDR_STR_FMT "%s", \
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&SRC), VTY_NEWLINE); \
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Error in " #SRC ": " OSMO_SOCKADDR_STR_FMT "\n", \
|
||||
OSMO_SOCKADDR_STR_FMT_ARGS(&SRC)); \
|
||||
return CMD_WARNING; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
STR_TO_ADDR(ue_addr, session->tunend.core.ue_local_addr);
|
||||
|
||||
if (session->tunend.access.local.teid == 0) {
|
||||
if (!*session->tunend.access.local.addr.ip) {
|
||||
f_teid_access_local = (struct osmo_pfcp_ie_f_teid){
|
||||
.choose_flag = true,
|
||||
.choose = {
|
||||
@@ -449,6 +551,7 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
};
|
||||
STR_TO_ADDR(f_teid_access_local.fixed.ip_addr.v4, session->tunend.access.local.addr);
|
||||
}
|
||||
session->tunend.access.local_pdr_id = PDR_ID_ACCESS;
|
||||
|
||||
ohc_access = (struct osmo_pfcp_ie_outer_header_creation){
|
||||
.teid_present = true,
|
||||
@@ -464,6 +567,10 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
osmo_pfcp_ip_addrs_set(&cp_f_seid.ip_addr, osmo_pfcp_endpoint_get_local_addr(g_pfcp_tool->ep));
|
||||
|
||||
m = osmo_pfcp_msg_alloc_tx_req(OTC_SELECT, &peer->remote_addr, OSMO_PFCP_MSGT_SESSION_EST_REQ);
|
||||
|
||||
m->ctx.resp_cb = resp_cb;
|
||||
m->ctx.priv = session;
|
||||
|
||||
m->h.seid_present = true;
|
||||
/* the UPF has yet to assign a SEID for itself, no matter what SEID we (the CPF) use for this session */
|
||||
m->h.seid = 0;
|
||||
@@ -475,7 +582,7 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
.create_pdr_count = 2,
|
||||
.create_pdr = {
|
||||
{
|
||||
.pdr_id = 1,
|
||||
.pdr_id = PDR_ID_CORE,
|
||||
.precedence = 255,
|
||||
.pdi = {
|
||||
.source_iface = OSMO_PFCP_SOURCE_IFACE_CORE,
|
||||
@@ -492,7 +599,7 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
.far_id = 1,
|
||||
},
|
||||
{
|
||||
.pdr_id = 2,
|
||||
.pdr_id = PDR_ID_ACCESS,
|
||||
.precedence = 255,
|
||||
.pdi = {
|
||||
.source_iface = OSMO_PFCP_SOURCE_IFACE_ACCESS,
|
||||
@@ -532,15 +639,14 @@ int session_tunend_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
|
||||
rc = peer_tx(peer, m);
|
||||
if (rc) {
|
||||
vty_out(vty, "Failed to transmit: %s%s", strerror(-rc), VTY_NEWLINE);
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Failed to transmit: %s\n", strerror(-rc));
|
||||
return CMD_WARNING;
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
int session_tunmap_tx_est_req(struct pfcp_tool_session *session, bool forw, osmo_pfcp_resp_cb resp_cb)
|
||||
{
|
||||
struct pfcp_tool_session *session = vty->index;
|
||||
struct pfcp_tool_peer *peer = session->peer;
|
||||
int rc;
|
||||
struct osmo_pfcp_msg *m;
|
||||
@@ -555,15 +661,13 @@ int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
|
||||
struct osmo_pfcp_ie_apply_action aa = {};
|
||||
|
||||
if (!g_pfcp_tool->ep) {
|
||||
vty_out(vty, "Endpoint not configured%s", VTY_NEWLINE);
|
||||
if (!g_pfcp_tool->ep)
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (argc > 0 && !strcmp("drop", argv[0]))
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
else
|
||||
if (forw)
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_FORW, true);
|
||||
else
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
|
||||
if (session->tunmap.access.local.teid == 0) {
|
||||
f_teid_access_local = (struct osmo_pfcp_ie_f_teid){
|
||||
@@ -625,6 +729,10 @@ int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
osmo_pfcp_ip_addrs_set(&cp_f_seid.ip_addr, osmo_pfcp_endpoint_get_local_addr(g_pfcp_tool->ep));
|
||||
|
||||
m = osmo_pfcp_msg_alloc_tx_req(OTC_SELECT, &peer->remote_addr, OSMO_PFCP_MSGT_SESSION_EST_REQ);
|
||||
|
||||
m->ctx.resp_cb = resp_cb;
|
||||
m->ctx.priv = session;
|
||||
|
||||
m->h.seid_present = true;
|
||||
m->h.seid = 0;
|
||||
/* GTP tunmap: remove header from both directions, and add header in both directions */
|
||||
@@ -635,7 +743,7 @@ int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
.create_pdr_count = 2,
|
||||
.create_pdr = {
|
||||
{
|
||||
.pdr_id = 1,
|
||||
.pdr_id = PDR_ID_CORE,
|
||||
.precedence = 255,
|
||||
.pdi = {
|
||||
.source_iface = OSMO_PFCP_SOURCE_IFACE_CORE,
|
||||
@@ -650,7 +758,7 @@ int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
.far_id = 1,
|
||||
},
|
||||
{
|
||||
.pdr_id = 2,
|
||||
.pdr_id = PDR_ID_ACCESS,
|
||||
.precedence = 255,
|
||||
.pdi = {
|
||||
.source_iface = OSMO_PFCP_SOURCE_IFACE_ACCESS,
|
||||
@@ -692,7 +800,7 @@ int session_tunmap_tx_est_req(struct vty *vty, const char **argv, int argc)
|
||||
|
||||
rc = peer_tx(peer, m);
|
||||
if (rc) {
|
||||
vty_out(vty, "Failed to transmit: %s%s", strerror(-rc), VTY_NEWLINE);
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Failed to transmit PFCP: %s\n", strerror(-rc));
|
||||
return CMD_WARNING;
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
@@ -705,39 +813,33 @@ DEFUN(session_tx_est_req, session_tx_est_req_cmd,
|
||||
"Set FAR to DROP = 1\n")
|
||||
{
|
||||
struct pfcp_tool_session *session = vty->index;
|
||||
bool forw = (argc == 0 || !strcmp("forw", argv[0]));
|
||||
switch (session->kind) {
|
||||
case UP_GTP_U_TUNEND:
|
||||
return session_tunend_tx_est_req(vty, argv, argc);
|
||||
return session_tunend_tx_est_req(session, forw, NULL);
|
||||
case UP_GTP_U_TUNMAP:
|
||||
return session_tunmap_tx_est_req(vty, argv, argc);
|
||||
return session_tunmap_tx_est_req(session, forw, NULL);
|
||||
default:
|
||||
vty_out(vty, "unknown gtp action%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN(session_tx_mod_req, session_tx_mod_req_cmd,
|
||||
"tx session-mod-req far [(forw|drop)]",
|
||||
TX_STR "Send a Session Modification Request\n"
|
||||
"Set FAR to FORW = 1\n"
|
||||
"Set FAR to DROP = 1\n")
|
||||
int session_tunmap_tx_mod_req(struct pfcp_tool_session *session, bool forw, osmo_pfcp_resp_cb resp_cb)
|
||||
{
|
||||
struct pfcp_tool_session *session = vty->index;
|
||||
struct pfcp_tool_peer *peer = session->peer;
|
||||
int rc;
|
||||
struct osmo_pfcp_msg *m;
|
||||
struct osmo_pfcp_ie_apply_action aa = {};
|
||||
struct osmo_pfcp_ie_f_seid cp_f_seid;
|
||||
|
||||
if (!g_pfcp_tool->ep) {
|
||||
vty_out(vty, "Endpoint not configured%s", VTY_NEWLINE);
|
||||
if (!g_pfcp_tool->ep)
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (argc > 0 && !strcmp("drop", argv[0]))
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
else
|
||||
if (forw)
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_FORW, true);
|
||||
else
|
||||
osmo_pfcp_bits_set(aa.bits, OSMO_PFCP_APPLY_ACTION_DROP, true);
|
||||
|
||||
cp_f_seid = (struct osmo_pfcp_ie_f_seid){
|
||||
.seid = session->cp_seid,
|
||||
@@ -745,6 +847,10 @@ DEFUN(session_tx_mod_req, session_tx_mod_req_cmd,
|
||||
osmo_pfcp_ip_addrs_set(&cp_f_seid.ip_addr, osmo_pfcp_endpoint_get_local_addr(g_pfcp_tool->ep));
|
||||
|
||||
m = osmo_pfcp_msg_alloc_tx_req(OTC_SELECT, &peer->remote_addr, OSMO_PFCP_MSGT_SESSION_MOD_REQ);
|
||||
|
||||
m->ctx.resp_cb = resp_cb;
|
||||
m->ctx.priv = session;
|
||||
|
||||
m->h.seid_present = true;
|
||||
m->h.seid = session->up_f_seid.seid;
|
||||
m->ies.session_mod_req = (struct osmo_pfcp_msg_session_mod_req){
|
||||
@@ -766,13 +872,25 @@ DEFUN(session_tx_mod_req, session_tx_mod_req_cmd,
|
||||
};
|
||||
|
||||
rc = peer_tx(peer, m);
|
||||
if (rc) {
|
||||
vty_out(vty, "Failed to transmit: %s%s", strerror(-rc), VTY_NEWLINE);
|
||||
if (rc)
|
||||
return CMD_WARNING;
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(session_tx_mod_req, session_tx_mod_req_cmd,
|
||||
"tx session-mod-req far [(forw|drop)]",
|
||||
TX_STR "Send a Session Modification Request\n"
|
||||
"Set FAR to FORW = 1\n"
|
||||
"Set FAR to DROP = 1\n")
|
||||
{
|
||||
struct pfcp_tool_session *session = vty->index;
|
||||
bool forw = (argc == 0 || !strcmp("forw", argv[0]));
|
||||
int rc = session_tunmap_tx_mod_req(session, forw, NULL);
|
||||
if (rc != CMD_SUCCESS)
|
||||
vty_out(vty, "Failed to send Session Modification Request%s", VTY_NEWLINE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
DEFUN(session_tx_del_req, session_tx_del_req_cmd,
|
||||
"tx session-del-req",
|
||||
TX_STR "Send a Session Deletion Request\n")
|
||||
@@ -799,6 +917,378 @@ DEFUN(session_tx_del_req, session_tx_del_req_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* N SESSIONS */
|
||||
|
||||
static int g_pfcp_responses_pending = 0;
|
||||
|
||||
DEFUN(wait_responses, wait_responses_cmd,
|
||||
"wait responses",
|
||||
"Let some time pass until events have occured\n"
|
||||
"Wait for all PFCP responses for pending PFCP requests\n")
|
||||
{
|
||||
if (!g_pfcp_responses_pending) {
|
||||
vty_out(vty, "no responses pending, not waiting.%s", VTY_NEWLINE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
vty_out(vty, "waiting for %d PFCP responses, %u GTP probes...%s", g_pfcp_responses_pending,
|
||||
g_gtp_probes_pending, VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
|
||||
/* Still operate the message pump while waiting for time to pass */
|
||||
while (!osmo_select_shutdown_done()) {
|
||||
if (pfcp_tool_mainloop(0) == -1) {
|
||||
vty_out(vty, "waiting for responses interrupted.%s", VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
break;
|
||||
}
|
||||
if (g_pfcp_responses_pending == 0 && g_gtp_probes_pending == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_pfcp_responses_pending || g_gtp_probes_pending)
|
||||
vty_out(vty, "...still pending: %d PFCP resposes, %u GTP probes.%s", g_pfcp_responses_pending,
|
||||
g_gtp_probes_pending, VTY_NEWLINE);
|
||||
vty_out(vty, "...done waiting for responses%s", VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* N SESSIONS TUNEND */
|
||||
|
||||
int one_session_mod_tunend_resp_cb(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg)
|
||||
{
|
||||
g_pfcp_responses_pending--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int one_session_mod_tunend(struct pfcp_tool_session *session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = session_tunmap_tx_mod_req(session, true, one_session_mod_tunend_resp_cb);
|
||||
if (rc == CMD_SUCCESS)
|
||||
g_pfcp_responses_pending++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void est_resp_get_created_f_teid(struct pfcp_tool_gtp_tun_ep *dst, const struct osmo_pfcp_msg *rx_resp, uint16_t pdr_id)
|
||||
{
|
||||
int i;
|
||||
const struct osmo_pfcp_msg_session_est_resp *r;
|
||||
if (rx_resp->h.message_type != OSMO_PFCP_MSGT_SESSION_EST_RESP)
|
||||
return;
|
||||
|
||||
r = &rx_resp->ies.session_est_resp;
|
||||
|
||||
for (i = 0; i < r->created_pdr_count; i++) {
|
||||
const struct osmo_pfcp_ie_created_pdr *p = &r->created_pdr[i];
|
||||
if (p->pdr_id != pdr_id)
|
||||
continue;
|
||||
if (!p->local_f_teid_present)
|
||||
continue;
|
||||
osmo_sockaddr_str_from_sockaddr(&dst->addr,
|
||||
&p->local_f_teid.fixed.ip_addr.v4.u.sas);
|
||||
dst->teid = p->local_f_teid.fixed.teid;
|
||||
}
|
||||
}
|
||||
|
||||
int one_session_create_tunend_resp_cb(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg)
|
||||
{
|
||||
struct pfcp_tool_session *session = req->ctx.priv;
|
||||
enum osmo_pfcp_cause *cause;
|
||||
const struct osmo_pfcp_msg_session_est_resp *r = NULL;
|
||||
if (rx_resp)
|
||||
r = &rx_resp->ies.session_est_resp;
|
||||
|
||||
g_pfcp_responses_pending--;
|
||||
|
||||
if (errmsg)
|
||||
LOGP(DLPFCP, LOGL_ERROR, "%s\n", errmsg);
|
||||
|
||||
cause = rx_resp ? osmo_pfcp_msg_cause(rx_resp) : NULL;
|
||||
if (!cause || *cause != OSMO_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
return 0;
|
||||
|
||||
/* store SEID */
|
||||
if (r && r->up_f_seid_present)
|
||||
session->up_f_seid = r->up_f_seid;
|
||||
/* store access local F-TEID */
|
||||
est_resp_get_created_f_teid(&session->tunend.access.local, rx_resp, PDR_ID_ACCESS);
|
||||
|
||||
/* Success response, now continue with second step: Session Mod to set the CORE's remote side GTP */
|
||||
one_session_mod_tunend(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int one_session_create_tunend(struct pfcp_tool_peer *peer)
|
||||
{
|
||||
struct pfcp_tool_session *session;
|
||||
struct pfcp_tool_tunend *te;
|
||||
int rc;
|
||||
|
||||
session = pfcp_tool_session_find_or_create(peer, peer_new_seid(peer), UP_GTP_U_TUNEND);
|
||||
te = &session->tunend;
|
||||
|
||||
/* Access: set remote GTP address */
|
||||
te->access.remote = g_pfcp_tool->gtp_state.access.remote;
|
||||
te->access.remote.teid = pfcp_tool_new_teid();
|
||||
|
||||
/* Set local F-TEIDs == CHOOSE */
|
||||
te->access.local = (struct pfcp_tool_gtp_tun_ep){};
|
||||
pfcp_tool_next_ue_addr(&te->core.ue_local_addr);
|
||||
|
||||
/* Send initial Session Establishment Request */
|
||||
rc = session_tunend_tx_est_req(session, false, one_session_create_tunend_resp_cb);
|
||||
if (rc == CMD_SUCCESS)
|
||||
g_pfcp_responses_pending++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* N SESSIONS TUNMAP */
|
||||
|
||||
int one_session_mod_tunmap_resp_cb(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg)
|
||||
{
|
||||
g_pfcp_responses_pending--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int one_session_mod_tunmap(struct pfcp_tool_session *session)
|
||||
{
|
||||
struct pfcp_tool_gtp_tun_ep *dst;
|
||||
int rc;
|
||||
|
||||
dst = &session->tunmap.core.remote;
|
||||
if (osmo_sockaddr_str_from_str2(&dst->addr, gtp_ip_core)) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Error setting GTP IP address from %s\n",
|
||||
osmo_quote_cstr_c(OTC_SELECT, gtp_ip_core, -1));
|
||||
return CMD_WARNING;
|
||||
}
|
||||
dst->teid = pfcp_tool_new_teid();
|
||||
|
||||
rc = session_tunmap_tx_mod_req(session, true, one_session_mod_tunmap_resp_cb);
|
||||
if (rc == CMD_SUCCESS)
|
||||
g_pfcp_responses_pending++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int one_session_create_tunmap_resp_cb(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg)
|
||||
{
|
||||
struct pfcp_tool_session *session = req->ctx.priv;
|
||||
enum osmo_pfcp_cause *cause;
|
||||
|
||||
g_pfcp_responses_pending--;
|
||||
|
||||
if (errmsg)
|
||||
LOGP(DLPFCP, LOGL_ERROR, "%s\n", errmsg);
|
||||
|
||||
cause = rx_resp ? osmo_pfcp_msg_cause(rx_resp) : NULL;
|
||||
if (!cause || *cause != OSMO_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
return 0;
|
||||
|
||||
/* store SEID */
|
||||
if (rx_resp->ies.session_est_resp.up_f_seid_present)
|
||||
session->up_f_seid = rx_resp->ies.session_est_resp.up_f_seid;
|
||||
|
||||
/* store local F-TEIDs */
|
||||
est_resp_get_created_f_teid(&session->tunmap.access.local, rx_resp, PDR_ID_ACCESS);
|
||||
est_resp_get_created_f_teid(&session->tunmap.core.local, rx_resp, PDR_ID_CORE);
|
||||
|
||||
/* Success response, now continue with second step: Session Mod to set the CORE's remote side GTP */
|
||||
one_session_mod_tunmap(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int one_session_create_tunmap(struct pfcp_tool_peer *peer)
|
||||
{
|
||||
struct pfcp_tool_session *session;
|
||||
struct pfcp_tool_tunmap *tm;
|
||||
struct pfcp_tool_gtp_tun_ep *dst;
|
||||
int rc;
|
||||
|
||||
session = pfcp_tool_session_find_or_create(peer, peer_new_seid(peer), UP_GTP_U_TUNMAP);
|
||||
tm = &session->tunmap;
|
||||
|
||||
/* Access: set remote GTP address */
|
||||
dst = &tm->access.remote;
|
||||
if (osmo_sockaddr_str_from_str2(&dst->addr, gtp_ip_access)) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Error setting GTP IP address from %s\n",
|
||||
osmo_quote_cstr_c(OTC_SELECT, gtp_ip_access, -1));
|
||||
return CMD_WARNING;
|
||||
}
|
||||
dst->teid = pfcp_tool_new_teid();
|
||||
|
||||
/* Core: set remote GTP address */
|
||||
dst = &tm->core.remote;
|
||||
if (osmo_sockaddr_str_from_str2(&dst->addr, gtp_ip_core)) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Error setting GTP IP address from %s\n",
|
||||
osmo_quote_cstr_c(OTC_SELECT, gtp_ip_core, -1));
|
||||
return CMD_WARNING;
|
||||
}
|
||||
dst->teid = pfcp_tool_new_teid();
|
||||
|
||||
/* Set local F-TEIDs == CHOOSE */
|
||||
tm->access.local = (struct pfcp_tool_gtp_tun_ep){};
|
||||
tm->core.local = (struct pfcp_tool_gtp_tun_ep){};
|
||||
|
||||
/* Send initial Session Establishment Request */
|
||||
rc = session_tunmap_tx_est_req(session, false, one_session_create_tunmap_resp_cb);
|
||||
if (rc == CMD_SUCCESS)
|
||||
g_pfcp_responses_pending++;
|
||||
return rc;
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
static void n_sessions_create(struct vty *vty, struct pfcp_tool_peer *peer, int n, enum up_gtp_action_kind kind)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
int rc;
|
||||
if (kind == UP_GTP_U_TUNMAP)
|
||||
rc = one_session_create_tunmap(peer);
|
||||
else
|
||||
rc = one_session_create_tunend(peer);
|
||||
if (rc != CMD_SUCCESS)
|
||||
goto aborted;
|
||||
|
||||
/* handle any pending select work */
|
||||
while (!osmo_select_shutdown_done()) {
|
||||
rc = pfcp_tool_mainloop(1);
|
||||
/* quit requested */
|
||||
if (rc < 0)
|
||||
goto aborted;
|
||||
/* no fd needed service */
|
||||
if (rc == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Every N created sessions, wait for pending responses */
|
||||
if (!(i & 0x3f) && g_pfcp_responses_pending) {
|
||||
vty_out(vty, "waiting for %d responses...%s", g_pfcp_responses_pending, VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
while (!osmo_select_shutdown_done()) {
|
||||
if (pfcp_tool_mainloop(0) == -1)
|
||||
break;
|
||||
if (g_pfcp_responses_pending == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
aborted:
|
||||
vty_out(vty, "Aborted at session nr %d%s", i, VTY_NEWLINE);
|
||||
vty_flush(vty);
|
||||
}
|
||||
|
||||
static void n_sessions_delete(struct pfcp_tool_peer *peer, int n, enum up_gtp_action_kind kind)
|
||||
{
|
||||
}
|
||||
|
||||
DEFUN(n_cfg_session_gtp_access, n_cfg_session_gtp_access_cmd,
|
||||
"n cfg session access remote f-teid start ADDR <0-65535>",
|
||||
"Batch run\n"
|
||||
"Configure batch run parameters\n"
|
||||
"Batch run on PFCP sessions\n"
|
||||
"Configure GTP Access side\n"
|
||||
"Configure remote GTP tunnel endpoint, as seem from UPF\n"
|
||||
"Configure F-TEID, the GTP address and the tunnel's TEID at that address\n"
|
||||
"Set the first addr+TEID to use, increment the TEID for each 'n session'\n"
|
||||
"IP address (GTP)\n" "TEID\n")
|
||||
{
|
||||
osmo_sockaddr_str_from_str(&g_pfcp_tool->gtp_state.access.remote.addr, argv[0], 0);
|
||||
g_pfcp_tool->gtp_state.access.remote.teid = atoi(argv[1]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(n_cfg_session_ue_addr, n_cfg_session_ue_addr_cmd,
|
||||
"n cfg session ue-addr start ADDR",
|
||||
"Batch run\n"
|
||||
"Configure batch run parameters\n"
|
||||
"Batch run on PFCP sessions\n"
|
||||
"Configure first UE address\n"
|
||||
"Set the first addr to use, increment for each 'n session'\n"
|
||||
"UE IP address\n")
|
||||
{
|
||||
struct osmo_sockaddr_str addr;
|
||||
osmo_sockaddr_str_from_str(&addr, argv[0], 0);
|
||||
osmo_sockaddr_str_to_32h(&addr, &g_pfcp_tool->next_ue_addr_state);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(n_sessions, n_sessions_cmd,
|
||||
"n (<0-2147483647>|all) session (create|delete) (tunend|tunmap)",
|
||||
"Batch run\n"
|
||||
"Perform the action N times\n" "Perform the action on all available entries\n"
|
||||
"Batch run on PFCP sessions\n"
|
||||
"Create N new sessions\n"
|
||||
"Delete N sessions created earlier\n"
|
||||
TUNEND_STR TUNMAP_STR)
|
||||
{
|
||||
struct pfcp_tool_peer *peer = vty->index;
|
||||
int n = (strcmp("all", argv[0]) == 0? -1 : atoi(argv[0]));
|
||||
bool create = (strcmp("create", argv[1]) == 0);
|
||||
enum up_gtp_action_kind kind;
|
||||
if (!strcmp(argv[2], "tunmap"))
|
||||
kind = UP_GTP_U_TUNMAP;
|
||||
else
|
||||
kind = UP_GTP_U_TUNEND;
|
||||
|
||||
if (create)
|
||||
n_sessions_create(vty, peer, n, kind);
|
||||
else
|
||||
n_sessions_delete(peer, n, kind);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void n_sessions_gtp_probe_run(struct vty *vty, struct pfcp_tool_peer *peer, enum up_gtp_action_kind kind)
|
||||
{
|
||||
struct pfcp_tool_session *s;
|
||||
int batch;
|
||||
batch = 0;
|
||||
llist_for_each_entry (s, &peer->sessions, entry) {
|
||||
if (s->kind != kind)
|
||||
continue;
|
||||
|
||||
/* operate the select loop while dispatching probes */
|
||||
if (batch >= 10) {
|
||||
if (osmo_select_shutdown_done())
|
||||
break;
|
||||
while (!osmo_select_shutdown_done() && g_gtp_probes_pending) {
|
||||
if (pfcp_tool_mainloop(0) < 0)
|
||||
break;
|
||||
}
|
||||
batch = 0;
|
||||
}
|
||||
batch++;
|
||||
|
||||
switch (s->kind) {
|
||||
case UP_GTP_U_TUNEND:
|
||||
gtp_probe_run_tunend(g_pfcp_tool,
|
||||
&g_pfcp_tool->gtp_probe,
|
||||
&s->tunend.access,
|
||||
&s->tunend.core.ue_local_addr,
|
||||
&g_pfcp_tool->gtp_probe.ip_target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN(n_sessions_gtp_probe, n_sessions_gtp_probe_cmd,
|
||||
"n all session gtp-probe run tunend",
|
||||
"Batch run\n"
|
||||
"Perform the action on all available entries\n"
|
||||
"Batch run on PFCP sessions\n"
|
||||
"Run a GTP probe on the GTP tunnel created by this session\n"
|
||||
"Run only on tunend sessions\n")
|
||||
{
|
||||
struct pfcp_tool_peer *peer = vty->index;
|
||||
n_sessions_gtp_probe_run(vty, peer, UP_GTP_U_TUNEND);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void install_ve_and_config(struct cmd_element *cmd)
|
||||
{
|
||||
install_element_ve(cmd);
|
||||
@@ -818,23 +1308,35 @@ void pfcp_tool_vty_init_cmds()
|
||||
OSMO_ASSERT(g_pfcp_tool != NULL);
|
||||
|
||||
install_ve_and_config(&c_sleep_cmd);
|
||||
install_ve_and_config(&c_date_cmd);
|
||||
install_ve_and_config(&wait_responses_cmd);
|
||||
install_ve_and_config(&c_gtp_probe_ip_target_cmd);
|
||||
install_ve_and_config(&c_gtp_probe_gtp_target_cmd);
|
||||
|
||||
install_ve_and_config(&peer_cmd);
|
||||
install_node(&peer_node, NULL);
|
||||
|
||||
install_element(PEER_NODE, &c_sleep_cmd);
|
||||
install_element(PEER_NODE, &c_date_cmd);
|
||||
install_element(PEER_NODE, &peer_tx_heartbeat_cmd);
|
||||
install_element(PEER_NODE, &peer_tx_assoc_setup_req_cmd);
|
||||
install_element(PEER_NODE, &peer_retrans_req_cmd);
|
||||
install_element(PEER_NODE, &n_cfg_session_gtp_access_cmd);
|
||||
install_element(PEER_NODE, &n_cfg_session_ue_addr_cmd);
|
||||
install_element(PEER_NODE, &n_sessions_cmd);
|
||||
install_element(PEER_NODE, &n_sessions_gtp_probe_cmd);
|
||||
install_element(PEER_NODE, &wait_responses_cmd);
|
||||
|
||||
install_element(PEER_NODE, &session_cmd);
|
||||
install_element(PEER_NODE, &session_endecaps_cmd);
|
||||
install_node(&session_node, NULL);
|
||||
install_element(SESSION_NODE, &c_sleep_cmd);
|
||||
install_element(SESSION_NODE, &c_date_cmd);
|
||||
install_element(SESSION_NODE, &session_tx_est_req_cmd);
|
||||
install_element(SESSION_NODE, &session_tx_mod_req_cmd);
|
||||
install_element(SESSION_NODE, &session_tx_del_req_cmd);
|
||||
install_element(SESSION_NODE, &s_ue_cmd);
|
||||
install_element(SESSION_NODE, &s_f_teid_cmd);
|
||||
install_element(SESSION_NODE, &s_f_teid_choose_cmd);
|
||||
install_element(SESSION_NODE, &s_gtp_probe_run_cmd);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,20 @@
|
||||
|
||||
struct g_upf *g_upf = NULL;
|
||||
|
||||
struct osmo_tdef g_upf_nft_tdefs[] = {
|
||||
{ .T = -32, .default_val = 1000, .unit = OSMO_TDEF_MS,
|
||||
.desc = "How long to wait for more nft rulesets before flushing in batch",
|
||||
},
|
||||
{ .T = -33, .default_val = 64, .unit = OSMO_TDEF_CUSTOM,
|
||||
.desc = "When reaching this nr of queued nft rulesets, flush the queue",
|
||||
.max_val = 128,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
struct osmo_tdef_group g_upf_tdef_groups[] = {
|
||||
{ "pfcp", "PFCP endpoint timers", osmo_pfcp_tdefs, },
|
||||
{ "nft", "netfilter timers", g_upf_nft_tdefs, },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <osmocom/upf/upf.h>
|
||||
#include <osmocom/upf/upf_nft.h>
|
||||
@@ -39,18 +40,18 @@ static char *upf_nft_ruleset_vmap_init(void *ctx, const char *table_name, int pr
|
||||
{
|
||||
/* 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 map inet osmo-upf mpre { typeof ip daddr . @ih,32,32 : verdict; }
|
||||
* add map inet osmo-upf mpost { typeof meta mark : verdict; }
|
||||
* add rule inet osmo-upf pre udp dport 2152 ip daddr . @ih,32,32 vmap @mpre
|
||||
* add rule inet osmo-upf post meta mark vmap @mpost
|
||||
*/
|
||||
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",
|
||||
"add map inet %s mpre { typeof ip daddr . @ih,32,32 : verdict; };\n"
|
||||
"add map inet %s mpost { typeof meta mark : verdict; };\n"
|
||||
"add rule inet %s pre udp dport %u ip daddr . @ih,32,32 vmap @mpre;\n"
|
||||
"add rule inet %s post meta mark vmap @mpost;\n",
|
||||
table_name, priority_pre,
|
||||
table_name, priority_post,
|
||||
table_name,
|
||||
@@ -59,9 +60,10 @@ static char *upf_nft_ruleset_vmap_init(void *ctx, const char *table_name, int pr
|
||||
table_name);
|
||||
}
|
||||
|
||||
static int upf_nft_run(const char *ruleset)
|
||||
static int upf_nft_run_now(const char *ruleset)
|
||||
{
|
||||
int rc;
|
||||
const int logmax = 256;
|
||||
|
||||
if (g_upf->tunmap.mockup) {
|
||||
LOGP(DNFT, LOGL_NOTICE, "tunmap/mockup active: not running nft ruleset: '%s'\n", ruleset);
|
||||
@@ -81,14 +83,135 @@ static int upf_nft_run(const char *ruleset)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
LOGP(DNFT, LOGL_DEBUG, "run nft ruleset: %s\n", osmo_quote_str_c(OTC_SELECT, ruleset, -1));
|
||||
if (log_check_level(DNFT, LOGL_DEBUG)) {
|
||||
size_t l = strlen(ruleset);
|
||||
LOGP(DNFT, LOGL_DEBUG, "ran nft ruleset, %zu chars: \"%s%s\"\n",
|
||||
l,
|
||||
osmo_escape_cstr_c(OTC_SELECT, ruleset, OSMO_MIN(logmax, l)),
|
||||
l > logmax ? "..." : "");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nft_queue {
|
||||
struct osmo_tdef *flush_time_tdef;
|
||||
struct osmo_tdef *ruleset_max_tdef;
|
||||
struct osmo_strbuf sb;
|
||||
/* 128 NFT rulesets amount to about 110 kb of char */
|
||||
char buf[1<<17];
|
||||
unsigned int ruleset_count;
|
||||
struct osmo_timer_list timer;
|
||||
};
|
||||
|
||||
static void nft_queue_clear_buf(struct nft_queue *q)
|
||||
{
|
||||
q->sb = (struct osmo_strbuf){ .buf = q->buf, .len = sizeof(q->buf) };
|
||||
q->buf[0] = '\0';
|
||||
}
|
||||
|
||||
static void nft_queue_init(void *ctx, struct nft_queue *q,
|
||||
struct osmo_tdef *flush_time_tdef,
|
||||
struct osmo_tdef *ruleset_max_tdef)
|
||||
{
|
||||
*q = (struct nft_queue){
|
||||
.flush_time_tdef = flush_time_tdef,
|
||||
.ruleset_max_tdef = ruleset_max_tdef,
|
||||
};
|
||||
nft_queue_clear_buf(q);
|
||||
}
|
||||
|
||||
static void nft_queue_flush(struct nft_queue *q, const char *reason)
|
||||
{
|
||||
static unsigned int flush_count = 0;
|
||||
static unsigned int ruleset_count = 0;
|
||||
|
||||
/* We will now flush the queue empty. A timer needs to run only when the next pending entry is added. */
|
||||
osmo_timer_del(&q->timer);
|
||||
|
||||
/* Nothing to send? */
|
||||
if (!q->sb.chars_needed)
|
||||
return;
|
||||
|
||||
flush_count++;
|
||||
ruleset_count += q->ruleset_count;
|
||||
LOGP(DNFT, LOGL_INFO, "Flushing NFT ruleset queue: %s: n:%u strlen:%zu (flush count: %u avg rules per flush: %s)\n",
|
||||
reason,
|
||||
q->ruleset_count, q->sb.chars_needed,
|
||||
flush_count, osmo_int_to_float_str_c(OTC_SELECT, 10 * ruleset_count / flush_count, 1));
|
||||
|
||||
q->ruleset_count = 0;
|
||||
|
||||
upf_nft_run_now(q->sb.buf);
|
||||
|
||||
nft_queue_clear_buf(q);
|
||||
}
|
||||
|
||||
static void nft_queue_flush_cb(void *q)
|
||||
{
|
||||
nft_queue_flush(q, "timeout");
|
||||
}
|
||||
|
||||
static int nft_enqueue(struct nft_queue *q,
|
||||
int (*tunmap_to_str_buf)(char *buf, size_t len, struct upf_tunmap *tunmap),
|
||||
struct upf_tunmap *tunmap)
|
||||
{
|
||||
int ruleset_max;
|
||||
struct osmo_strbuf q_sb_was = q->sb;
|
||||
|
||||
OSMO_STRBUF_APPEND(q->sb, tunmap_to_str_buf, tunmap);
|
||||
|
||||
/* is that being cut off? then revert the addition. This should never happen in practice. */
|
||||
if (q->sb.chars_needed >= q->sb.len) {
|
||||
q->sb = q_sb_was;
|
||||
if (q->sb.pos)
|
||||
*q->sb.pos = '\0';
|
||||
nft_queue_flush(q, "reached max nr of chars");
|
||||
OSMO_STRBUF_APPEND(q->sb, tunmap_to_str_buf, tunmap);
|
||||
}
|
||||
|
||||
/* Append separator -- no problem if that gets cut off. */
|
||||
OSMO_STRBUF_PRINTF(q->sb, "\n");
|
||||
|
||||
q->ruleset_count++;
|
||||
|
||||
LOGP(DNFT, LOGL_INFO, "Added NFT ruleset to queue: n:%u strlen:%zu\n",
|
||||
q->ruleset_count, q->sb.chars_needed);
|
||||
|
||||
/* Added a rule, see if it has reached ruleset_max. */
|
||||
ruleset_max = osmo_tdef_get(q->ruleset_max_tdef, q->ruleset_max_tdef->T, OSMO_TDEF_CUSTOM, 128);
|
||||
if (q->ruleset_count >= ruleset_max) {
|
||||
nft_queue_flush(q, "reached max nr of rules");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Item added. If the timer is not running yet, schedule a flush in given timeout */
|
||||
if (!osmo_timer_pending(&q->timer)) {
|
||||
struct osmo_tdef *t;
|
||||
unsigned long us;
|
||||
osmo_timer_setup(&q->timer, nft_queue_flush_cb, q);
|
||||
t = q->flush_time_tdef;
|
||||
us = osmo_tdef_get(t, t->T, OSMO_TDEF_US, 100000);
|
||||
osmo_timer_schedule(&q->timer, us / 1000000, us % 1000000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_queue_free(struct nft_queue *q)
|
||||
{
|
||||
osmo_timer_del(&q->timer);
|
||||
}
|
||||
|
||||
static struct nft_queue g_nft_queue = {};
|
||||
|
||||
int upf_nft_init()
|
||||
{
|
||||
int rc;
|
||||
|
||||
nft_queue_init(g_upf, &g_nft_queue,
|
||||
osmo_tdef_get_entry(g_upf_nft_tdefs, -32),
|
||||
osmo_tdef_get_entry(g_upf_nft_tdefs, -33));
|
||||
|
||||
/* Always set up the default settings, also in mockup mode, so that the VTY reflects sane values */
|
||||
if (!g_upf->tunmap.table_name)
|
||||
g_upf->tunmap.table_name = talloc_strdup(g_upf, "osmo-upf");
|
||||
@@ -106,7 +229,7 @@ int upf_nft_init()
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = upf_nft_run(upf_nft_tunmap_get_table_init_str(OTC_SELECT));
|
||||
rc = upf_nft_run_now(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->tunmap.table_name, -1));
|
||||
@@ -114,7 +237,7 @@ int upf_nft_init()
|
||||
}
|
||||
LOGP(DNFT, LOGL_NOTICE, "Created nft table %s\n", osmo_quote_str_c(OTC_SELECT, g_upf->tunmap.table_name, -1));
|
||||
|
||||
rc = upf_nft_run(upf_nft_tunmap_get_vmap_init_str(OTC_SELECT));
|
||||
rc = upf_nft_run_now(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->tunmap.table_name);
|
||||
return rc;
|
||||
@@ -124,6 +247,7 @@ int upf_nft_init()
|
||||
|
||||
int upf_nft_free()
|
||||
{
|
||||
nft_queue_free(&g_nft_queue);
|
||||
if (!g_upf->tunmap.nft_ctx)
|
||||
return 0;
|
||||
nft_ctx_free(g_upf->tunmap.nft_ctx);
|
||||
@@ -170,46 +294,46 @@ static int tunmap_add_single_direction(char *buf, size_t buflen,
|
||||
}
|
||||
|
||||
/* # add chain for verdict map in prerouting
|
||||
* add chain inet osmo-upf tunmap-pre-123
|
||||
* add chain inet osmo-upf mpre123
|
||||
* # 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 rule inet osmo-upf mpre123 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
|
||||
* add chain inet osmo-upf mpost123
|
||||
* # 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 rule inet osmo-upf mpost123 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 }
|
||||
* add element inet osmo-upf mpre { 2.2.2.3 . 0x00000203 : jump mpre123 }
|
||||
* add element inet osmo-upf mpost { 123 : jump mpost123 }
|
||||
*/
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add chain inet %s tunmap-pre-%u;\n",
|
||||
OSMO_STRBUF_PRINTF(sb, "add chain inet %s mpre%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s tunmap-pre-%u",
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s mpre%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);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add chain inet %s tunmap-post-%u;\n",
|
||||
OSMO_STRBUF_PRINTF(sb, "add chain inet %s mpost%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s tunmap-post-%u",
|
||||
OSMO_STRBUF_PRINTF(sb, "add rule inet %s mpost%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, "add element inet %s tunmap-pre { ",
|
||||
OSMO_STRBUF_PRINTF(sb, "add element inet %s mpre { ",
|
||||
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",
|
||||
OSMO_STRBUF_PRINTF(sb, " . 0x%x : jump mpre%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",
|
||||
OSMO_STRBUF_PRINTF(sb, "add element inet %s mpost { %u : jump mpost%u };\n",
|
||||
args->table_name, from_peer->chain_id, from_peer->chain_id);
|
||||
|
||||
return sb.chars_needed;
|
||||
@@ -227,24 +351,24 @@ static int tunmap_del_single_direction(char *buf, size_t buflen,
|
||||
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
|
||||
/* delete element inet osmo-upf mpre { 2.2.2.3 . 0x203 }
|
||||
* delete element inet osmo-upf mpost { 123 }
|
||||
* delete chain inet osmo-upf mpre123
|
||||
* delete chain inet osmo-upf mpost123
|
||||
*/
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete element inet %s tunmap-pre { ",
|
||||
OSMO_STRBUF_PRINTF(sb, "delete element inet %s mpre { ",
|
||||
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",
|
||||
OSMO_STRBUF_PRINTF(sb, "delete element inet %s mpost { %u };\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s tunmap-pre-%u;\n",
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s mpre%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s tunmap-post-%u;\n",
|
||||
OSMO_STRBUF_PRINTF(sb, "delete chain inet %s mpost%u;\n",
|
||||
args->table_name, from_peer->chain_id);
|
||||
|
||||
return sb.chars_needed;
|
||||
@@ -262,11 +386,6 @@ static int upf_nft_ruleset_tunmap_create_buf(char *buf, size_t buflen, const str
|
||||
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, 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 };
|
||||
@@ -279,11 +398,6 @@ static int upf_nft_ruleset_tunmap_delete_buf(char *buf, size_t buflen, const str
|
||||
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, 512, "ERROR", upf_nft_ruleset_tunmap_delete_buf, args)
|
||||
}
|
||||
|
||||
int upf_nft_tunmap_to_str_buf(char *buf, size_t buflen, const struct upf_tunmap *tunmap)
|
||||
{
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||
@@ -343,18 +457,28 @@ char *upf_nft_tunmap_get_vmap_init_str(void *ctx)
|
||||
g_upf->tunmap.priority_post);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_tunmap *tunmap)
|
||||
int upf_nft_tunmap_get_ruleset_str_buf(char *buf, size_t len, struct upf_tunmap *tunmap)
|
||||
{
|
||||
struct upf_nft_args args;
|
||||
upf_nft_args_from_tunmap(&args, tunmap);
|
||||
return upf_nft_ruleset_tunmap_create_c(ctx, &args);
|
||||
return upf_nft_ruleset_tunmap_create_buf(buf, len, &args);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_str(void *ctx, struct upf_tunmap *tunmap)
|
||||
{
|
||||
OSMO_NAME_C_IMPL(ctx, 1024, "ERROR", upf_nft_tunmap_get_ruleset_str_buf, tunmap)
|
||||
}
|
||||
|
||||
int upf_nft_tunmap_get_ruleset_del_str_buf(char *buf, size_t len, struct upf_tunmap *tunmap)
|
||||
{
|
||||
struct upf_nft_args args;
|
||||
upf_nft_args_from_tunmap(&args, tunmap);
|
||||
return upf_nft_ruleset_tunmap_delete_buf(buf, len, &args);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_del_str(void *ctx, struct upf_tunmap *tunmap)
|
||||
{
|
||||
struct upf_nft_args args;
|
||||
upf_nft_args_from_tunmap(&args, tunmap);
|
||||
return upf_nft_ruleset_tunmap_delete_c(ctx, &args);
|
||||
OSMO_NAME_C_IMPL(ctx, 1024, "ERROR", upf_nft_tunmap_get_ruleset_del_str_buf, tunmap)
|
||||
}
|
||||
|
||||
static int upf_nft_tunmap_ensure_chain_id(struct upf_nft_tun *tun)
|
||||
@@ -372,10 +496,101 @@ int upf_nft_tunmap_create(struct upf_tunmap *tunmap)
|
||||
if (upf_nft_tunmap_ensure_chain_id(&tunmap->access)
|
||||
|| upf_nft_tunmap_ensure_chain_id(&tunmap->core))
|
||||
return -ENOSPC;
|
||||
return upf_nft_run(upf_nft_tunmap_get_ruleset_str(OTC_SELECT, tunmap));
|
||||
return nft_enqueue(&g_nft_queue, upf_nft_tunmap_get_ruleset_str_buf, tunmap);
|
||||
}
|
||||
|
||||
int upf_nft_tunmap_delete(struct upf_tunmap *tunmap)
|
||||
{
|
||||
return upf_nft_run(upf_nft_tunmap_get_ruleset_del_str(OTC_SELECT, tunmap));
|
||||
return nft_enqueue(&g_nft_queue, upf_nft_tunmap_get_ruleset_del_str_buf, tunmap);
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_dump_all(void *ctx)
|
||||
{
|
||||
int rc;
|
||||
const int logmax = 256;
|
||||
struct nft_ctx *nft = g_upf->tunmap.nft_ctx;
|
||||
char *output = NULL;
|
||||
char *cmd;
|
||||
|
||||
if (g_upf->tunmap.mockup) {
|
||||
LOGP(DNFT, LOGL_NOTICE, "tunmap/mockup active: not retrieving ruleset\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!nft)
|
||||
return NULL;
|
||||
|
||||
cmd = talloc_asprintf(g_upf, "list table inet %s", g_upf->tunmap.table_name);
|
||||
|
||||
rc = nft_ctx_buffer_output(nft);
|
||||
if (rc) {
|
||||
LOGP(DNFT, LOGL_ERROR, "error: nft_ctx_buffer_output() returned failure: rc=%d cmd=%s\n",
|
||||
rc, osmo_quote_str_c(OTC_SELECT, cmd, -1));
|
||||
goto unbuffer_and_exit;
|
||||
}
|
||||
rc = nft_run_cmd_from_buffer(nft, cmd);
|
||||
if (rc < 0) {
|
||||
LOGP(DNFT, LOGL_ERROR, "error running nft cmd: rc=%d cmd=%s\n",
|
||||
rc, osmo_quote_str_c(OTC_SELECT, cmd, -1));
|
||||
goto unbuffer_and_exit;
|
||||
}
|
||||
if (log_check_level(DNFT, LOGL_DEBUG)) {
|
||||
size_t l = strlen(cmd);
|
||||
LOGP(DNFT, LOGL_DEBUG, "ran nft cmd, %zu chars: \"%s%s\"\n",
|
||||
l,
|
||||
osmo_escape_cstr_c(OTC_SELECT, cmd, OSMO_MIN(logmax, l)),
|
||||
l > logmax ? "..." : "");
|
||||
}
|
||||
output = talloc_strdup(ctx, nft_ctx_get_output_buffer(nft));
|
||||
|
||||
unbuffer_and_exit:
|
||||
talloc_free(cmd);
|
||||
nft_ctx_unbuffer_output(nft);
|
||||
return output;
|
||||
}
|
||||
|
||||
char *upf_nft_tunmap_get_ruleset_dump(void *ctx, const char *countername, uint32_t chain_id)
|
||||
{
|
||||
int rc;
|
||||
const int logmax = 256;
|
||||
struct nft_ctx *nft = g_upf->tunmap.nft_ctx;
|
||||
char *output = NULL;
|
||||
char *cmd;
|
||||
|
||||
if (g_upf->tunmap.mockup) {
|
||||
LOGP(DNFT, LOGL_NOTICE, "tunmap/mockup active: not retrieving ruleset\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!nft)
|
||||
return NULL;
|
||||
|
||||
cmd = talloc_asprintf(g_upf, "list chain inet %s %s%u", g_upf->tunmap.table_name,
|
||||
countername, chain_id);
|
||||
|
||||
rc = nft_ctx_buffer_output(nft);
|
||||
if (rc) {
|
||||
LOGP(DNFT, LOGL_ERROR, "error: nft_ctx_buffer_output() returned failure: rc=%d cmd=%s\n",
|
||||
rc, osmo_quote_str_c(OTC_SELECT, cmd, -1));
|
||||
goto unbuffer_and_exit;
|
||||
}
|
||||
rc = nft_run_cmd_from_buffer(nft, cmd);
|
||||
if (rc < 0) {
|
||||
LOGP(DNFT, LOGL_ERROR, "error running nft cmd: rc=%d cmd=%s\n",
|
||||
rc, osmo_quote_str_c(OTC_SELECT, cmd, -1));
|
||||
goto unbuffer_and_exit;
|
||||
}
|
||||
if (log_check_level(DNFT, LOGL_DEBUG)) {
|
||||
size_t l = strlen(cmd);
|
||||
LOGP(DNFT, LOGL_DEBUG, "ran nft cmd, %zu chars: \"%s%s\"\n",
|
||||
l,
|
||||
osmo_escape_cstr_c(OTC_SELECT, cmd, OSMO_MIN(logmax, l)),
|
||||
l > logmax ? "..." : "");
|
||||
}
|
||||
output = talloc_strdup(ctx, nft_ctx_get_output_buffer(nft));
|
||||
|
||||
unbuffer_and_exit:
|
||||
talloc_free(cmd);
|
||||
nft_ctx_unbuffer_output(nft);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -336,6 +336,112 @@ DEFUN(show_nft_rule_tunmap_example, show_nft_rule_tunmap_example_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(show_nft_ruleset2, show_nft_ruleset2_cmd,
|
||||
"show nft-ruleset2",
|
||||
SHOW_STR "Retrieve and dump the complete nft ruleset (may be huge)\n")
|
||||
{
|
||||
char *ruleset;
|
||||
char *pos;
|
||||
char buf1[64];
|
||||
char buf2[64];
|
||||
|
||||
vty_out(vty, "Retrieving ruleset...%s", VTY_NEWLINE);
|
||||
ruleset = upf_nft_tunmap_get_ruleset_dump_all(g_upf);
|
||||
|
||||
pos = ruleset;
|
||||
while (*pos) {
|
||||
char *chain, *chain_end;
|
||||
char *counter, *counter_end;
|
||||
|
||||
chain = strstr(pos, "chain mp");
|
||||
if (!chain)
|
||||
break;
|
||||
chain += 6;
|
||||
chain_end = strstr(chain, " {");
|
||||
if (!chain_end)
|
||||
break;
|
||||
|
||||
counter = strstr(chain_end, "counter packets ");
|
||||
if (!counter)
|
||||
break;
|
||||
counter += 8;
|
||||
counter_end = strstr(counter, " accept");
|
||||
if (!counter_end)
|
||||
break;
|
||||
|
||||
osmo_escape_cstr_buf(buf1, sizeof(buf1), chain, chain_end - chain);
|
||||
osmo_escape_cstr_buf(buf2, sizeof(buf2), counter, counter_end - counter);
|
||||
vty_out(vty, "%s %s%s", buf1, buf2, VTY_NEWLINE);
|
||||
|
||||
pos = counter_end;
|
||||
}
|
||||
|
||||
talloc_free(ruleset);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(show_nft_ruleset, show_nft_ruleset_cmd,
|
||||
"show nft-ruleset",
|
||||
SHOW_STR "Retrieve and dump the complete nft ruleset (may be huge)\n")
|
||||
{
|
||||
char *ruleset;
|
||||
char *pos;
|
||||
char buf1[64];
|
||||
char buf2[64];
|
||||
vty_out(vty, "Retrieving ruleset...%s", VTY_NEWLINE);
|
||||
|
||||
struct up_peer *peer;
|
||||
llist_for_each_entry(peer, &g_upf->pfcp.ep->peers, entry) {
|
||||
struct up_session *session;
|
||||
int bkt;
|
||||
hash_for_each(peer->sessions_by_up_seid, bkt, session, node_by_up_seid) {
|
||||
struct up_gtp_action *a;
|
||||
llist_for_each_entry(a, &session->active_gtp_actions, entry) {
|
||||
if (a->kind != UP_GTP_U_TUNMAP)
|
||||
continue;
|
||||
|
||||
const char *ctrs[] = { "mpre", "mpost" };
|
||||
const uint32_t chain_ids[] = { a->tunmap.access.chain_id, a->tunmap.core.chain_id };
|
||||
for (int j = 0; j < 2; j++)
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ruleset = upf_nft_tunmap_get_ruleset_dump(g_upf, ctrs[i], chain_ids[j]);
|
||||
pos = ruleset;
|
||||
while (*pos) {
|
||||
char *chain, *chain_end;
|
||||
char *counter, *counter_end;
|
||||
|
||||
chain = strstr(pos, "chain mp");
|
||||
if (!chain)
|
||||
break;
|
||||
chain += 6;
|
||||
chain_end = strstr(chain, " {");
|
||||
if (!chain_end)
|
||||
break;
|
||||
|
||||
counter = strstr(chain_end, "counter packets ");
|
||||
if (!counter)
|
||||
break;
|
||||
counter += 8;
|
||||
counter_end = strstr(counter, " accept");
|
||||
if (!counter_end)
|
||||
break;
|
||||
|
||||
osmo_escape_cstr_buf(buf1, sizeof(buf1), chain, chain_end - chain);
|
||||
osmo_escape_cstr_buf(buf2, sizeof(buf2), counter, counter_end - counter);
|
||||
vty_out(vty, "%s %s%s", buf1, buf2, VTY_NEWLINE);
|
||||
|
||||
pos = counter_end;
|
||||
}
|
||||
|
||||
talloc_free(ruleset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_node cfg_netinst_node = {
|
||||
NETINST_NODE,
|
||||
"%s(config-netinst)# ",
|
||||
@@ -495,6 +601,8 @@ void upf_vty_init()
|
||||
install_element_ve(&show_session_cmd);
|
||||
install_element_ve(&show_netinst_cmd);
|
||||
install_element_ve(&show_nft_rule_append_cmd);
|
||||
install_element_ve(&show_nft_ruleset_cmd);
|
||||
install_element_ve(&show_nft_ruleset2_cmd);
|
||||
|
||||
install_node(&cfg_pfcp_node, config_write_pfcp);
|
||||
install_element(CONFIG_NODE, &cfg_pfcp_cmd);
|
||||
|
||||
@@ -4,7 +4,7 @@ OsmoUPF(config)# tunmap
|
||||
|
||||
OsmoUPF(config-tunmap)# show nft-rule tunmap example
|
||||
% init verdict map:
|
||||
add table inet osmo-upf { flags owner; };
|
||||
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; };
|
||||
|
||||
@@ -8,18 +8,18 @@ DLPFCP NOTICE PFCP endpoint: recovery timestamp = 0x83aa7e80 (0 seconds since UN
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
add table inet osmo-upf { flags owner; };
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add table inet osmo-upf { flags owner; };\n"
|
||||
DNFT DEBUG ran nft ruleset, 42 chars: "add table inet osmo-upf { flags owner; };\n"
|
||||
DNFT NOTICE Created nft table "osmo-upf"
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
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 map inet osmo-upf mpre { typeof ip daddr . @ih,32,32 : verdict; };
|
||||
add map inet osmo-upf mpost { typeof meta mark : verdict; };
|
||||
add rule inet osmo-upf pre udp dport 2152 ip daddr . @ih,32,32 vmap @mpre;
|
||||
add rule inet osmo-upf post meta mark vmap @mpost;
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add chain inet osmo-upf pre { type filter hook prerouting priority -300; policy accept; };\nadd chain inet osmo-upf post { type filter hook postrouting priority 400; policy accept; };\nadd map inet osmo-upf tunmap-pre { typeof ip daddr . @ih,32,32 : verdict; };\nadd map inet osmo-upf tunmap-post { typeof meta mark : verdict; };\nadd rule inet osmo-upf pre udp dport 2152 ip daddr . @ih,32,32 vmap @tunmap-pre;\nadd rule inet osmo-upf post meta mark vmap @tunmap-post;\n"
|
||||
DNFT DEBUG ran nft ruleset, 441 chars: "add chain inet osmo-upf pre { type filter hook prerouting priority -300; policy accept; };\nadd chain inet osmo-upf post { type filter hook postrouting priority 400; policy accept; };\nadd map inet osmo-upf mpre { typeof ip daddr . @ih,32,32 : verdict; };\nad..."
|
||||
|
||||
PFCP Associate peer
|
||||
DPEER DEBUG up_peer{NOT_ASSOCIATED}: Allocated
|
||||
@@ -58,22 +58,25 @@ DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: Active PDR set: + PDR-1{src:Core T
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: GTP actions: 0 previously active; want active: 1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: want: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x100 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x101 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: enabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x100 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x101 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:701
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:701 (flush count: 1 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
add chain inet osmo-upf tunmap-pre-1;
|
||||
add rule inet osmo-upf tunmap-pre-1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-1;
|
||||
add rule inet osmo-upf tunmap-post-1 ip saddr set 1.1.1.1 @ih,32,32 set 0x101 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 : jump tunmap-pre-1 };
|
||||
add element inet osmo-upf tunmap-post { 1 : jump tunmap-post-1 };
|
||||
add chain inet osmo-upf tunmap-pre-2;
|
||||
add rule inet osmo-upf tunmap-pre-2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-2;
|
||||
add rule inet osmo-upf tunmap-post-2 ip saddr set 1.1.1.1 @ih,32,32 set 0x100 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 : jump tunmap-pre-2 };
|
||||
add element inet osmo-upf tunmap-post { 2 : jump tunmap-post-2 };
|
||||
add chain inet osmo-upf mpre1;
|
||||
add rule inet osmo-upf mpre1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;
|
||||
add chain inet osmo-upf mpost1;
|
||||
add rule inet osmo-upf mpost1 ip saddr set 1.1.1.1 @ih,32,32 set 0x101 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x2 : jump mpre1 };
|
||||
add element inet osmo-upf mpost { 1 : jump mpost1 };
|
||||
add chain inet osmo-upf mpre2;
|
||||
add rule inet osmo-upf mpre2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;
|
||||
add chain inet osmo-upf mpost2;
|
||||
add rule inet osmo-upf mpost2 ip saddr set 1.1.1.1 @ih,32,32 set 0x100 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x1 : jump mpre2 };
|
||||
add element inet osmo-upf mpost { 2 : jump mpost2 };
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add chain inet osmo-upf tunmap-pre-1;\nadd rule inet osmo-upf tunmap-pre-1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;\nadd chain inet osmo-upf tunmap-post-1;\nadd rule inet osmo-upf tunmap-post-1 ip saddr set 1.1.1.1 @ih,32,32 set 0x101 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 : jump tunmap-pre-1 };\nadd element inet osmo-upf tunmap-post { 1 : jump tunmap-post-1 };\nadd chain inet osmo-upf tunmap-pre-2;\nadd rule inet osmo-upf tunmap-pre-2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;\nadd chain inet osmo-upf tunmap-post-2;\nadd rule inet osmo-upf tunmap-post-2 ip saddr set 1.1.1.1 @ih,32,32 set 0x100 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 : jump tunmap-pre-2 };\nadd element inet osmo-upf tunmap-post { 2 : jump tunmap-post-2 };\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 701 chars: "add chain inet osmo-upf mpre1;\nadd rule inet osmo-upf mpre1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;\nadd chain inet osmo-upf mpost1;\nadd rule inet osmo-upf mpost1 ip saddr set 1.1.1.1 @ih,32,32 set 0x101 counter accept;\nadd element inet osm..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x100 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x101 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1: Enabled tunmap, nft chain IDs: access--1-> <-2--core
|
||||
|
||||
[test override] PFCP tx:
|
||||
@@ -123,22 +126,25 @@ DSESSION DEBUG up_session(1-2-3-4-0x2){INIT}: Active PDR set: + PDR-1{src:Core T
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){INIT}: GTP actions: 0 previously active; want active: 1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){INIT}: want: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){INIT}: enabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:701
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:701 (flush count: 2 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
add chain inet osmo-upf tunmap-pre-3;
|
||||
add rule inet osmo-upf tunmap-pre-3 ip daddr set 13.14.15.16 meta mark set 3 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-3;
|
||||
add rule inet osmo-upf tunmap-post-3 ip saddr set 1.1.1.1 @ih,32,32 set 0x103 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x4 : jump tunmap-pre-3 };
|
||||
add element inet osmo-upf tunmap-post { 3 : jump tunmap-post-3 };
|
||||
add chain inet osmo-upf tunmap-pre-4;
|
||||
add rule inet osmo-upf tunmap-pre-4 ip daddr set 5.6.7.8 meta mark set 4 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-4;
|
||||
add rule inet osmo-upf tunmap-post-4 ip saddr set 1.1.1.1 @ih,32,32 set 0x102 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x3 : jump tunmap-pre-4 };
|
||||
add element inet osmo-upf tunmap-post { 4 : jump tunmap-post-4 };
|
||||
add chain inet osmo-upf mpre3;
|
||||
add rule inet osmo-upf mpre3 ip daddr set 13.14.15.16 meta mark set 3 counter accept;
|
||||
add chain inet osmo-upf mpost3;
|
||||
add rule inet osmo-upf mpost3 ip saddr set 1.1.1.1 @ih,32,32 set 0x103 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x4 : jump mpre3 };
|
||||
add element inet osmo-upf mpost { 3 : jump mpost3 };
|
||||
add chain inet osmo-upf mpre4;
|
||||
add rule inet osmo-upf mpre4 ip daddr set 5.6.7.8 meta mark set 4 counter accept;
|
||||
add chain inet osmo-upf mpost4;
|
||||
add rule inet osmo-upf mpost4 ip saddr set 1.1.1.1 @ih,32,32 set 0x102 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x3 : jump mpre4 };
|
||||
add element inet osmo-upf mpost { 4 : jump mpost4 };
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add chain inet osmo-upf tunmap-pre-3;\nadd rule inet osmo-upf tunmap-pre-3 ip daddr set 13.14.15.16 meta mark set 3 counter accept;\nadd chain inet osmo-upf tunmap-post-3;\nadd rule inet osmo-upf tunmap-post-3 ip saddr set 1.1.1.1 @ih,32,32 set 0x103 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x4 : jump tunmap-pre-3 };\nadd element inet osmo-upf tunmap-post { 3 : jump tunmap-post-3 };\nadd chain inet osmo-upf tunmap-pre-4;\nadd rule inet osmo-upf tunmap-pre-4 ip daddr set 5.6.7.8 meta mark set 4 counter accept;\nadd chain inet osmo-upf tunmap-post-4;\nadd rule inet osmo-upf tunmap-post-4 ip saddr set 1.1.1.1 @ih,32,32 set 0x102 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x3 : jump tunmap-pre-4 };\nadd element inet osmo-upf tunmap-post { 4 : jump tunmap-post-4 };\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 701 chars: "add chain inet osmo-upf mpre3;\nadd rule inet osmo-upf mpre3 ip daddr set 13.14.15.16 meta mark set 3 counter accept;\nadd chain inet osmo-upf mpost3;\nadd rule inet osmo-upf mpost3 ip saddr set 1.1.1.1 @ih,32,32 set 0x103 counter accept;\nadd element inet osm..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1: Enabled tunmap, nft chain IDs: access--3-> <-4--core
|
||||
|
||||
[test override] PFCP tx:
|
||||
@@ -182,18 +188,21 @@ DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: Received Event UP_SESSION_E
|
||||
DREF INFO up_peer(1-2-3-4){ASSOCIATED}: - msg-tx: now used by 0 (-)
|
||||
DPEER DEBUG up_peer(1-2-3-4){ASSOCIATED}: Received Event UP_PEER_EV_USE_COUNT_ZERO
|
||||
DSESSION NOTICE up_session(1-2-3-4-0x1){ESTABLISHED}: Session releasing: peer:1.2.3.4 SEID-r:0x100 SEID-l:0x1 state:ESTABLISHED PDR-active:2/2 FAR-active:2/2 GTP-active:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:329
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:329 (flush count: 3 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 };
|
||||
delete element inet osmo-upf tunmap-post { 1 };
|
||||
delete chain inet osmo-upf tunmap-pre-1;
|
||||
delete chain inet osmo-upf tunmap-post-1;
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 };
|
||||
delete element inet osmo-upf tunmap-post { 2 };
|
||||
delete chain inet osmo-upf tunmap-pre-2;
|
||||
delete chain inet osmo-upf tunmap-post-2;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x2 };
|
||||
delete element inet osmo-upf mpost { 1 };
|
||||
delete chain inet osmo-upf mpre1;
|
||||
delete chain inet osmo-upf mpost1;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x1 };
|
||||
delete element inet osmo-upf mpost { 2 };
|
||||
delete chain inet osmo-upf mpre2;
|
||||
delete chain inet osmo-upf mpost2;
|
||||
|
||||
DNFT DEBUG run nft ruleset: "delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 };\ndelete element inet osmo-upf tunmap-post { 1 };\ndelete chain inet osmo-upf tunmap-pre-1;\ndelete chain inet osmo-upf tunmap-post-1;\ndelete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 };\ndelete element inet osmo-upf tunmap-post { 2 };\ndelete chain inet osmo-upf tunmap-pre-2;\ndelete chain inet osmo-upf tunmap-post-2;\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 329 chars: "delete element inet osmo-upf mpre { 1.1.1.1 . 0x2 };\ndelete element inet osmo-upf mpost { 1 };\ndelete chain inet osmo-upf mpre1;\ndelete chain inet osmo-upf mpost1;\ndelete element inet osmo-upf mpre { 1.1.1.1 . 0x1 };\ndelete element inet osmo-upf mpost { 2 ..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x100 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x101 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1: Disabled tunmap, nft chain IDs: access--1-> <-2--core
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: State change to WAIT_USE_COUNT (no timeout)
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){WAIT_USE_COUNT}: GTP actions: 0 previously active; want active: 0
|
||||
@@ -231,22 +240,25 @@ DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: Active PDR set: + PDR-1{src:Core T
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: GTP actions: 0 previously active; want active: 1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: want: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){INIT}: enabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:701
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:701 (flush count: 4 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
add chain inet osmo-upf tunmap-pre-1;
|
||||
add rule inet osmo-upf tunmap-pre-1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-1;
|
||||
add rule inet osmo-upf tunmap-post-1 ip saddr set 1.1.1.1 @ih,32,32 set 0x105 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 : jump tunmap-pre-1 };
|
||||
add element inet osmo-upf tunmap-post { 1 : jump tunmap-post-1 };
|
||||
add chain inet osmo-upf tunmap-pre-2;
|
||||
add rule inet osmo-upf tunmap-pre-2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-2;
|
||||
add rule inet osmo-upf tunmap-post-2 ip saddr set 1.1.1.1 @ih,32,32 set 0x104 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 : jump tunmap-pre-2 };
|
||||
add element inet osmo-upf tunmap-post { 2 : jump tunmap-post-2 };
|
||||
add chain inet osmo-upf mpre1;
|
||||
add rule inet osmo-upf mpre1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;
|
||||
add chain inet osmo-upf mpost1;
|
||||
add rule inet osmo-upf mpost1 ip saddr set 1.1.1.1 @ih,32,32 set 0x105 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x2 : jump mpre1 };
|
||||
add element inet osmo-upf mpost { 1 : jump mpost1 };
|
||||
add chain inet osmo-upf mpre2;
|
||||
add rule inet osmo-upf mpre2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;
|
||||
add chain inet osmo-upf mpost2;
|
||||
add rule inet osmo-upf mpost2 ip saddr set 1.1.1.1 @ih,32,32 set 0x104 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x1 : jump mpre2 };
|
||||
add element inet osmo-upf mpost { 2 : jump mpost2 };
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add chain inet osmo-upf tunmap-pre-1;\nadd rule inet osmo-upf tunmap-pre-1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;\nadd chain inet osmo-upf tunmap-post-1;\nadd rule inet osmo-upf tunmap-post-1 ip saddr set 1.1.1.1 @ih,32,32 set 0x105 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 : jump tunmap-pre-1 };\nadd element inet osmo-upf tunmap-post { 1 : jump tunmap-post-1 };\nadd chain inet osmo-upf tunmap-pre-2;\nadd rule inet osmo-upf tunmap-pre-2 ip daddr set 5.6.7.8 meta mark set 2 counter accept;\nadd chain inet osmo-upf tunmap-post-2;\nadd rule inet osmo-upf tunmap-post-2 ip saddr set 1.1.1.1 @ih,32,32 set 0x104 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 : jump tunmap-pre-2 };\nadd element inet osmo-upf tunmap-post { 2 : jump tunmap-post-2 };\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 701 chars: "add chain inet osmo-upf mpre1;\nadd rule inet osmo-upf mpre1 ip daddr set 13.14.15.16 meta mark set 1 counter accept;\nadd chain inet osmo-upf mpost1;\nadd rule inet osmo-upf mpost1 ip saddr set 1.1.1.1 @ih,32,32 set 0x105 counter accept;\nadd element inet osm..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1: Enabled tunmap, nft chain IDs: access--1-> <-2--core
|
||||
|
||||
[test override] PFCP tx:
|
||||
@@ -296,22 +308,25 @@ DSESSION DEBUG up_session(1-2-3-4-0x3){INIT}: Active PDR set: + PDR-1{src:Core T
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){INIT}: GTP actions: 0 previously active; want active: 1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){INIT}: want: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){INIT}: enabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:701
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:701 (flush count: 5 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
add chain inet osmo-upf tunmap-pre-5;
|
||||
add rule inet osmo-upf tunmap-pre-5 ip daddr set 13.14.15.16 meta mark set 5 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-5;
|
||||
add rule inet osmo-upf tunmap-post-5 ip saddr set 1.1.1.1 @ih,32,32 set 0x107 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x6 : jump tunmap-pre-5 };
|
||||
add element inet osmo-upf tunmap-post { 5 : jump tunmap-post-5 };
|
||||
add chain inet osmo-upf tunmap-pre-6;
|
||||
add rule inet osmo-upf tunmap-pre-6 ip daddr set 5.6.7.8 meta mark set 6 counter accept;
|
||||
add chain inet osmo-upf tunmap-post-6;
|
||||
add rule inet osmo-upf tunmap-post-6 ip saddr set 1.1.1.1 @ih,32,32 set 0x106 counter accept;
|
||||
add element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x5 : jump tunmap-pre-6 };
|
||||
add element inet osmo-upf tunmap-post { 6 : jump tunmap-post-6 };
|
||||
add chain inet osmo-upf mpre5;
|
||||
add rule inet osmo-upf mpre5 ip daddr set 13.14.15.16 meta mark set 5 counter accept;
|
||||
add chain inet osmo-upf mpost5;
|
||||
add rule inet osmo-upf mpost5 ip saddr set 1.1.1.1 @ih,32,32 set 0x107 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x6 : jump mpre5 };
|
||||
add element inet osmo-upf mpost { 5 : jump mpost5 };
|
||||
add chain inet osmo-upf mpre6;
|
||||
add rule inet osmo-upf mpre6 ip daddr set 5.6.7.8 meta mark set 6 counter accept;
|
||||
add chain inet osmo-upf mpost6;
|
||||
add rule inet osmo-upf mpost6 ip saddr set 1.1.1.1 @ih,32,32 set 0x106 counter accept;
|
||||
add element inet osmo-upf mpre { 1.1.1.1 . 0x5 : jump mpre6 };
|
||||
add element inet osmo-upf mpost { 6 : jump mpost6 };
|
||||
|
||||
DNFT DEBUG run nft ruleset: "add chain inet osmo-upf tunmap-pre-5;\nadd rule inet osmo-upf tunmap-pre-5 ip daddr set 13.14.15.16 meta mark set 5 counter accept;\nadd chain inet osmo-upf tunmap-post-5;\nadd rule inet osmo-upf tunmap-post-5 ip saddr set 1.1.1.1 @ih,32,32 set 0x107 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x6 : jump tunmap-pre-5 };\nadd element inet osmo-upf tunmap-post { 5 : jump tunmap-post-5 };\nadd chain inet osmo-upf tunmap-pre-6;\nadd rule inet osmo-upf tunmap-pre-6 ip daddr set 5.6.7.8 meta mark set 6 counter accept;\nadd chain inet osmo-upf tunmap-post-6;\nadd rule inet osmo-upf tunmap-post-6 ip saddr set 1.1.1.1 @ih,32,32 set 0x106 counter accept;\nadd element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x5 : jump tunmap-pre-6 };\nadd element inet osmo-upf tunmap-post { 6 : jump tunmap-post-6 };\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 701 chars: "add chain inet osmo-upf mpre5;\nadd rule inet osmo-upf mpre5 ip daddr set 13.14.15.16 meta mark set 5 counter accept;\nadd chain inet osmo-upf mpost5;\nadd rule inet osmo-upf mpost5 ip saddr set 1.1.1.1 @ih,32,32 set 0x107 counter accept;\nadd element inet osm..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1: Enabled tunmap, nft chain IDs: access--5-> <-6--core
|
||||
|
||||
[test override] PFCP tx:
|
||||
@@ -348,18 +363,21 @@ DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: Removing from parent up_pee
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: GTP actions: 1 previously active; want active: 0
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: active: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: disabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:329
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:329 (flush count: 6 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x6 };
|
||||
delete element inet osmo-upf tunmap-post { 5 };
|
||||
delete chain inet osmo-upf tunmap-pre-5;
|
||||
delete chain inet osmo-upf tunmap-post-5;
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x5 };
|
||||
delete element inet osmo-upf tunmap-post { 6 };
|
||||
delete chain inet osmo-upf tunmap-pre-6;
|
||||
delete chain inet osmo-upf tunmap-post-6;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x6 };
|
||||
delete element inet osmo-upf mpost { 5 };
|
||||
delete chain inet osmo-upf mpre5;
|
||||
delete chain inet osmo-upf mpost5;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x5 };
|
||||
delete element inet osmo-upf mpost { 6 };
|
||||
delete chain inet osmo-upf mpre6;
|
||||
delete chain inet osmo-upf mpost6;
|
||||
|
||||
DNFT DEBUG run nft ruleset: "delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x6 };\ndelete element inet osmo-upf tunmap-post { 5 };\ndelete chain inet osmo-upf tunmap-pre-5;\ndelete chain inet osmo-upf tunmap-post-5;\ndelete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x5 };\ndelete element inet osmo-upf tunmap-post { 6 };\ndelete chain inet osmo-upf tunmap-pre-6;\ndelete chain inet osmo-upf tunmap-post-6;\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 329 chars: "delete element inet osmo-upf mpre { 1.1.1.1 . 0x6 };\ndelete element inet osmo-upf mpost { 5 };\ndelete chain inet osmo-upf mpre5;\ndelete chain inet osmo-upf mpost5;\ndelete element inet osmo-upf mpre { 1.1.1.1 . 0x5 };\ndelete element inet osmo-upf mpost { 6 ..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x106 GTP-access-l:1.1.1.1 TEID-access-l:0x6 GTP-core-r:13.14.15.16 TEID-core-r:0x107 GTP-core-l:1.1.1.1 TEID-core-l:0x5 PFCP-peer:1.2.3.4 SEID-l:0x3 PDR-access:2 PDR-core:1: Disabled tunmap, nft chain IDs: access--5-> <-6--core
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: Freeing instance
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x3){ESTABLISHED}: Deallocated
|
||||
@@ -368,18 +386,21 @@ DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: Removing from parent up_pee
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: GTP actions: 1 previously active; want active: 0
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: active: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: disabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:329
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:329 (flush count: 7 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 };
|
||||
delete element inet osmo-upf tunmap-post { 1 };
|
||||
delete chain inet osmo-upf tunmap-pre-1;
|
||||
delete chain inet osmo-upf tunmap-post-1;
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 };
|
||||
delete element inet osmo-upf tunmap-post { 2 };
|
||||
delete chain inet osmo-upf tunmap-pre-2;
|
||||
delete chain inet osmo-upf tunmap-post-2;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x2 };
|
||||
delete element inet osmo-upf mpost { 1 };
|
||||
delete chain inet osmo-upf mpre1;
|
||||
delete chain inet osmo-upf mpost1;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x1 };
|
||||
delete element inet osmo-upf mpost { 2 };
|
||||
delete chain inet osmo-upf mpre2;
|
||||
delete chain inet osmo-upf mpost2;
|
||||
|
||||
DNFT DEBUG run nft ruleset: "delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x2 };\ndelete element inet osmo-upf tunmap-post { 1 };\ndelete chain inet osmo-upf tunmap-pre-1;\ndelete chain inet osmo-upf tunmap-post-1;\ndelete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x1 };\ndelete element inet osmo-upf tunmap-post { 2 };\ndelete chain inet osmo-upf tunmap-pre-2;\ndelete chain inet osmo-upf tunmap-post-2;\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 329 chars: "delete element inet osmo-upf mpre { 1.1.1.1 . 0x2 };\ndelete element inet osmo-upf mpost { 1 };\ndelete chain inet osmo-upf mpre1;\ndelete chain inet osmo-upf mpost1;\ndelete element inet osmo-upf mpre { 1.1.1.1 . 0x1 };\ndelete element inet osmo-upf mpost { 2 ..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x104 GTP-access-l:1.1.1.1 TEID-access-l:0x2 GTP-core-r:13.14.15.16 TEID-core-r:0x105 GTP-core-l:1.1.1.1 TEID-core-l:0x1 PFCP-peer:1.2.3.4 SEID-l:0x1 PDR-access:2 PDR-core:1: Disabled tunmap, nft chain IDs: access--1-> <-2--core
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: Freeing instance
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x1){ESTABLISHED}: Deallocated
|
||||
@@ -388,18 +409,21 @@ DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: Removing from parent up_pee
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: GTP actions: 1 previously active; want active: 0
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: active: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: disabling: GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1
|
||||
DNFT INFO Added NFT ruleset to queue: n:1 strlen:329
|
||||
DNFT INFO Flushing NFT ruleset queue: reached max nr of rules: n:1 strlen:329 (flush count: 8 avg rules per flush: 1)
|
||||
|
||||
[test override] nft_run_cmd_from_buffer():
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x4 };
|
||||
delete element inet osmo-upf tunmap-post { 3 };
|
||||
delete chain inet osmo-upf tunmap-pre-3;
|
||||
delete chain inet osmo-upf tunmap-post-3;
|
||||
delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x3 };
|
||||
delete element inet osmo-upf tunmap-post { 4 };
|
||||
delete chain inet osmo-upf tunmap-pre-4;
|
||||
delete chain inet osmo-upf tunmap-post-4;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x4 };
|
||||
delete element inet osmo-upf mpost { 3 };
|
||||
delete chain inet osmo-upf mpre3;
|
||||
delete chain inet osmo-upf mpost3;
|
||||
delete element inet osmo-upf mpre { 1.1.1.1 . 0x3 };
|
||||
delete element inet osmo-upf mpost { 4 };
|
||||
delete chain inet osmo-upf mpre4;
|
||||
delete chain inet osmo-upf mpost4;
|
||||
|
||||
DNFT DEBUG run nft ruleset: "delete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x4 };\ndelete element inet osmo-upf tunmap-post { 3 };\ndelete chain inet osmo-upf tunmap-pre-3;\ndelete chain inet osmo-upf tunmap-post-3;\ndelete element inet osmo-upf tunmap-pre { 1.1.1.1 . 0x3 };\ndelete element inet osmo-upf tunmap-post { 4 };\ndelete chain inet osmo-upf tunmap-pre-4;\ndelete chain inet osmo-upf tunmap-post-4;\n"
|
||||
|
||||
DNFT DEBUG ran nft ruleset, 329 chars: "delete element inet osmo-upf mpre { 1.1.1.1 . 0x4 };\ndelete element inet osmo-upf mpost { 3 };\ndelete chain inet osmo-upf mpre3;\ndelete chain inet osmo-upf mpost3;\ndelete element inet osmo-upf mpre { 1.1.1.1 . 0x3 };\ndelete element inet osmo-upf mpost { 4 ..."
|
||||
DGTP NOTICE GTP:tunmap GTP-access-r:5.6.7.8 TEID-access-r:0x102 GTP-access-l:1.1.1.1 TEID-access-l:0x4 GTP-core-r:13.14.15.16 TEID-core-r:0x103 GTP-core-l:1.1.1.1 TEID-core-l:0x3 PFCP-peer:1.2.3.4 SEID-l:0x2 PDR-access:2 PDR-core:1: Disabled tunmap, nft chain IDs: access--3-> <-4--core
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: Freeing instance
|
||||
DSESSION DEBUG up_session(1-2-3-4-0x2){ESTABLISHED}: Deallocated
|
||||
|
||||
Reference in New Issue
Block a user