pespin has submitted this change. (
https://gerrit.osmocom.org/c/upf-benchmark/+/39573?usp=email )
Change subject: osmo-upf-load-gen: Support setting UE IP ranges per local GTP endpoint
......................................................................
osmo-upf-load-gen: Support setting UE IP ranges per local GTP endpoint
Before this commit, a single UE IP address pool was used by all local
GTP endpoints (eg. eNodeBs). This means UE IP addresses are allocated
with jumps on each GTP endpoint, which creates some limitations for TRex
to generate traffic on those tunnels using tunnels_topo.
Add a VTY command to alow setting a pool of concurrent UE IP addresses
per tunnel endpoint to overcome this problem.
Change-Id: I51fec879bccc9e0c3debcef091fce0814d74400c
---
M include/osmocom/upfloadgen/pfcp_tool.h
M src/osmo-upf-load-gen/pfcp_tool.c
M src/osmo-upf-load-gen/pfcp_tool_vty.c
3 files changed, 90 insertions(+), 23 deletions(-)
Approvals:
osmith: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/include/osmocom/upfloadgen/pfcp_tool.h
b/include/osmocom/upfloadgen/pfcp_tool.h
index e13c1aa..28be674 100644
--- a/include/osmocom/upfloadgen/pfcp_tool.h
+++ b/include/osmocom/upfloadgen/pfcp_tool.h
@@ -111,6 +111,14 @@
/* IP address and UDP port from user input */
struct osmo_sockaddr osa;
+ struct {
+ /* Whether it has its own specific range or global one
+ * (g_pfcp_tool->ue.ip_range) should be used. */
+ bool ip_range_present;
+ /* Specific UE IP range to use for this GTPU endpoint */
+ struct range ip_range;
+ } ue;
+
/* In case this is a locally bound port, this is the fd for the socket. */
struct osmo_fd ofd;
};
@@ -183,7 +191,7 @@
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 *dst);
+int pfcp_tool_next_ue_addr(struct range *r, struct osmo_sockaddr *dst);
struct udp_port *pfcp_tool_have_local_udp_port_by_str(const struct osmo_sockaddr_str
*addr, uint16_t fallback_port, bool do_bind);
struct udp_port *pfcp_tool_have_core_udp_port_by_str(const struct osmo_sockaddr_str
*addr, uint16_t fallback_port);
diff --git a/src/osmo-upf-load-gen/pfcp_tool.c b/src/osmo-upf-load-gen/pfcp_tool.c
index b634822..f07acf0 100644
--- a/src/osmo-upf-load-gen/pfcp_tool.c
+++ b/src/osmo-upf-load-gen/pfcp_tool.c
@@ -212,14 +212,14 @@
return g_pfcp_tool->next_teid_state++;
}
-int pfcp_tool_next_ue_addr(struct osmo_sockaddr *dst)
+int pfcp_tool_next_ue_addr(struct range *r, struct osmo_sockaddr *dst)
{
- range_next(&g_pfcp_tool->ue.ip_range);
- if (g_pfcp_tool->ue.ip_range.wrapped) {
+ range_next(r);
+ if (r->wrapped) {
LOGP(DLGLOBAL, LOGL_ERROR, "insufficient UE IP addresses, wrapped back to
first\n");
- g_pfcp_tool->ue.ip_range.wrapped = false;
+ r->wrapped = false;
}
- range_val_get_addr(dst, &g_pfcp_tool->ue.ip_range.next);
+ range_val_get_addr(dst, &r->next);
return 0;
}
@@ -361,7 +361,7 @@
if (ue_local_addr) {
osmo_sockaddr_str_to_osa(ue_local_addr, &cfg.payload_src);
- } else if (pfcp_tool_next_ue_addr(&cfg.payload_src)) {
+ } else if (pfcp_tool_next_ue_addr(&g_pfcp_tool->ue.ip_range,
&cfg.payload_src)) {
LOGP(DLGLOBAL, LOGL_ERROR, "Cannot set up GTP flow for session, failed to identify
UE's IP address\n");
return false;
}
diff --git a/src/osmo-upf-load-gen/pfcp_tool_vty.c
b/src/osmo-upf-load-gen/pfcp_tool_vty.c
index 5af9dfe..86e4104 100644
--- a/src/osmo-upf-load-gen/pfcp_tool_vty.c
+++ b/src/osmo-upf-load-gen/pfcp_tool_vty.c
@@ -219,6 +219,42 @@
p = pfcp_tool_have_local_udp_port_by_str(&addr_str, port_nr,
g_pfcp_tool->gtp.do_local_gtpu_bind);
if (!p)
goto invalid_ip;
+ p->ue.ip_range_present = false;
+ return CMD_SUCCESS;
+
+invalid_ip:
+ vty_out(vty, "%% Error: invalid IP address: '%s'%s", ip_str,
VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+DEFUN(c_gtp_local_with_ue_ip_range, c_gtp_local_with_ue_ip_range_cmd,
+ "gtp local IP_ADDR <1-65535> ue-ip-range IP_ADDR_FIRST IP_ADDR_LAST",
+ GTP_STR
+ "Add a local GTP port, to emit GTP1U traffic from\n"
+ IP_ADDR_STR
+ "Specific UDP port to use, GTPU1 port is 2152\n"
+ IP_RANGE_STR)
+{
+ const char *ip_str = argv[0];
+ uint16_t port_nr;
+ struct osmo_sockaddr_str addr_str;
+ struct udp_port *p;
+
+ port_nr = atoi(argv[1]);
+
+ if (osmo_sockaddr_str_from_str(&addr_str, ip_str, port_nr))
+ goto invalid_ip;
+ vty_out(vty, "local GTP port: " OSMO_SOCKADDR_STR_FMT "%s",
OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL(&addr_str), VTY_NEWLINE);
+ p = pfcp_tool_have_local_udp_port_by_str(&addr_str, port_nr,
g_pfcp_tool->gtp.do_local_gtpu_bind);
+ if (!p)
+ goto invalid_ip;
+
+ if (!parse_ip_range(vty, &p->ue.ip_range, &argv[2])) {
+ ip_str = argv[2];
+ goto invalid_ip;
+ }
+
+ p->ue.ip_range_present = true;
return CMD_SUCCESS;
invalid_ip:
@@ -1187,20 +1223,11 @@
return 0;
}
-static int set_access_ran_tunend(struct pfcp_tool_gtp_tun_ep *dst)
+/* next local GTP address to emit from */
+static struct udp_port *pick_next_gtp_local_addr(void)
{
- if (llist_empty(&g_pfcp_tool->gtp.gtp_local_addrs)) {
- /* No local GTP ports configured, just set an arbitrary address. */
- if (osmo_sockaddr_str_from_str2(&dst->addr, fallback_gtp_ip_access)) {
- LOGP(DLGLOBAL, LOGL_ERROR, "Error setting Access side GTP IP address from
%s\n",
- osmo_quote_cstr_c(OTC_SELECT, fallback_gtp_ip_access, -1));
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
- }
-
- /* next local GTP address to emit from */
struct udp_port *next;
+
next = g_pfcp_tool->gtp.gtp_local_addrs_next;
if (next) {
/* Move on by one gtp_local_addr. If past the end of the list, wrap back to the start
below. */
@@ -1214,12 +1241,38 @@
entry);
OSMO_ASSERT(next);
g_pfcp_tool->gtp.gtp_local_addrs_next = next;
+ return next;
+}
+
+/* ip_range is an out param, optionally set if the selected gtp local addr has
+ * specific UE IP address ranges assigned. */
+static int set_access_ran_tunend(struct pfcp_tool_gtp_tun_ep *dst, struct range
**ip_range)
+{
+ struct udp_port *next;
+
+ if (ip_range)
+ *ip_range = NULL;
+
+ if (llist_empty(&g_pfcp_tool->gtp.gtp_local_addrs)) {
+ /* No local GTP ports configured, just set an arbitrary address. */
+ if (osmo_sockaddr_str_from_str2(&dst->addr, fallback_gtp_ip_access)) {
+ LOGP(DLGLOBAL, LOGL_ERROR, "Error setting Access side GTP IP address from
%s\n",
+ osmo_quote_cstr_c(OTC_SELECT, fallback_gtp_ip_access, -1));
+ return CMD_WARNING;
+ }
+ return CMD_SUCCESS;
+ }
+
+ /* next local GTP address to emit from */
+ next = pick_next_gtp_local_addr();
if (osmo_sockaddr_str_from_osa(&dst->addr, &next->osa)) {
LOGP(DLGLOBAL, LOGL_ERROR, "Error setting Access side GTP IP address from
%s\n",
osmo_sockaddr_to_str_c(OTC_SELECT, &next->osa));
return CMD_WARNING;
}
+ if (ip_range && next->ue.ip_range_present)
+ *ip_range = &next->ue.ip_range;
dst->teid = pfcp_tool_new_teid();
LOGP(DLGLOBAL, LOGL_DEBUG, "session picked gtp local " OSMO_SOCKADDR_STR_FMT
" TEID 0x%x\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&dst->addr), dst->teid);
@@ -1261,21 +1314,26 @@
struct pfcp_tool_tunend *te;
struct pfcp_tool_gtp_tun_ep *dst;
struct osmo_sockaddr osa;
+ struct range *ip_range = NULL;
int rc;
session = pfcp_tool_session_find_or_create(peer, peer_new_seid(peer), UP_GTP_U_TUNEND);
te = &session->tunend;
+ te->access.local = (struct pfcp_tool_gtp_tun_ep){};
/* Access: set remote GTP address from UPF's point of view.
* A local GTP port from osmo-upf-load-gen's point of view. */
dst = &te->access.remote;
- rc = set_access_ran_tunend(dst);
+ rc = set_access_ran_tunend(dst, &ip_range);
if (rc != CMD_SUCCESS)
return rc;
+ /* If selected RAN doesn't have specific UE IP addr range, pick global one: */
+ if (!ip_range)
+ ip_range = &g_pfcp_tool->ue.ip_range;
+
/* Set UE address */
- te->access.local = (struct pfcp_tool_gtp_tun_ep){};
- pfcp_tool_next_ue_addr(&osa);
+ pfcp_tool_next_ue_addr(ip_range, &osa);
if (osmo_sockaddr_str_from_osa(&te->core.ue_local_addr, &osa)) {
LOGP(DLGLOBAL, LOGL_ERROR, "Error setting UE address from %s\n",
osmo_sockaddr_to_str_c(OTC_SELECT, &osa));
@@ -1356,7 +1414,7 @@
/* Access: set remote GTP address from UPF's point of view.
* A local GTP port from osmo-upf-load-gen's point of view. */
dst = &tm->access.remote;
- rc = set_access_ran_tunend(dst);
+ rc = set_access_ran_tunend(dst, NULL);
if (rc != CMD_SUCCESS)
return rc;
@@ -1493,6 +1551,7 @@
install_ve_and_config(&no_gtp_local_bind_cmd);
install_ve_and_config(&c_gtp_local_cmd);
+ install_ve_and_config(&c_gtp_local_with_ue_ip_range_cmd);
install_ve_and_config(&c_gtp_core_cmd);
install_ve_and_config(&c_ue_ip_range_cmd);
--
To view, visit
https://gerrit.osmocom.org/c/upf-benchmark/+/39573?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: upf-benchmark
Gerrit-Branch: master
Gerrit-Change-Id: I51fec879bccc9e0c3debcef091fce0814d74400c
Gerrit-Change-Number: 39573
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>