neels has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-upf/+/37830?usp=email )
Change subject: add VTY 'gtp-echo' command
......................................................................
add VTY 'gtp-echo' command
Allow sending GTPv1-U Echo Requests to GTP peers via new VTY command
gtp-echo tx to 1.2.3.4 [from (dev|ip) (apn0|5.6.7.8)]
(pseudocode)
Related: OS#6541
Change-Id: I970dccd7a27b098eea9e660822e24e2c4b059fc6
---
M include/osmocom/upf/upf.h
M include/osmocom/upf/upf_gtpu_echo.h
M src/osmo-upf/upf_gtpu_echo.c
M src/osmo-upf/upf_vty.c
A tests/gtp-echo.vty
5 files changed, 295 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-upf refs/changes/30/37830/1
diff --git a/include/osmocom/upf/upf.h b/include/osmocom/upf/upf.h
index db73c1f..abd881e 100644
--- a/include/osmocom/upf/upf.h
+++ b/include/osmocom/upf/upf.h
@@ -117,6 +117,7 @@
struct {
uint32_t next_local_teid_state;
+ uint16_t next_echo_seq_nr;
} gtp;
struct llist_head netinst;
diff --git a/include/osmocom/upf/upf_gtpu_echo.h b/include/osmocom/upf/upf_gtpu_echo.h
index 2575424..2bb7c31 100644
--- a/include/osmocom/upf/upf_gtpu_echo.h
+++ b/include/osmocom/upf/upf_gtpu_echo.h
@@ -2,3 +2,4 @@
#pragma once
int upf_gtpu_echo_setup(struct upf_gtp_dev *dev);
+int upf_gtpu_echo_req_tx(struct upf_gtp_dev *dev, const struct osmo_sockaddr *remote,
uint16_t seq_nr);
diff --git a/src/osmo-upf/upf_gtpu_echo.c b/src/osmo-upf/upf_gtpu_echo.c
index b234065..8d8db0c 100644
--- a/src/osmo-upf/upf_gtpu_echo.c
+++ b/src/osmo-upf/upf_gtpu_echo.c
@@ -122,6 +122,45 @@
return rc;
}
+int upf_gtpu_echo_req_tx(struct upf_gtp_dev *dev, const struct osmo_sockaddr *remote,
uint16_t seq_nr)
+{
+ struct gtp1u_hdr *tx_h;
+ int rc;
+
+#define GTP_ECHO_REQ_SIZE ((size_t)(sizeof(struct gtp1u_hdr) + 2))
+ uint8_t msgbuf[GTP_ECHO_REQ_SIZE];
+
+ tx_h = (void *)msgbuf;
+ *tx_h = (struct gtp1u_hdr){
+ /* 3GPP TS 29.281 5.1 defines that the ECHO REQ & RESP shall contain a sequence nr
*/
+ .s = 1,
+ .pt = 1,
+ .version = 1,
+ .msg_type = GTP1U_MSGTYPE_ECHO_REQ,
+ .ext = {
+ .seq_nr = seq_nr,
+ },
+ };
+
+ /* ECHO REQUEST shall contain a recovery counter */
+ tx_h->data2[0] = GTP1U_IEI_RECOVERY;
+ tx_h->data2[1] = g_upf->tunend.recovery_count;
+
+ osmo_store16be(GTP_ECHO_REQ_SIZE - offsetof(struct gtp1u_hdr, data1),
&tx_h->length);
+
+ rc = sendto(dev->gtpv1.ofd.fd, msgbuf, GTP_ECHO_REQ_SIZE, 0, &remote->u.sa,
sizeof(*remote));
+ if (rc < 0) {
+ rc = -errno;
+ LOG_GTP_DEV(dev, LOGL_ERROR, "GTP1-U sendto(len=%zu, to=%s): %s\n",
GTP_ECHO_REQ_SIZE,
+ osmo_sockaddr_to_str(remote), strerror(-rc));
+ } else {
+ rc = 0;
+ }
+ LOG_GTP_DEV(dev, LOGL_INFO, "<- %s: tx GTP1-U Echo Request: seq_nr=%u
recovery_count=%u\n",
+ osmo_sockaddr_to_str(remote), seq_nr, g_upf->tunend.recovery_count);
+ return rc;
+}
+
int upf_gtpu_echo_read_cb(struct osmo_fd *ofd, unsigned int what)
{
struct upf_gtp_dev *dev = ofd->data;
diff --git a/src/osmo-upf/upf_vty.c b/src/osmo-upf/upf_vty.c
index 44d14db..76d18ea 100644
--- a/src/osmo-upf/upf_vty.c
+++ b/src/osmo-upf/upf_vty.c
@@ -38,6 +38,7 @@
#include <osmocom/upf/up_session.h>
#include <osmocom/upf/up_gtp_action.h>
#include <osmocom/upf/netinst.h>
+#include <osmocom/upf/upf_gtpu_echo.h>
enum upf_vty_node {
PFCP_NODE = _LAST_OSMOVTY_NODE + 1,
@@ -486,6 +487,80 @@
return CMD_SUCCESS;
}
+DEFUN(gtp_echo_tx, gtp_echo_tx_cmd,
+ "gtp-echo tx to IP_ADDR [from] [(ip|dev)] [LOCAL_ADDR_OR_DEV_NAME]",
+ "GTP1-U Echo probing\n"
+ "Send a GTP1-U Echo Request to a remote peer\n"
+ "Send to remote peer's GTP address\n" "IP address like 1.2.3.4
or 1:2:3::4\n"
+ "Choose local GTP device to send from; when omitted, choose first GTP
device.\n"
+ "Choose local GTP device by IP address\n"
+ "Choose local GTP device by configured name\n"
+ "A local IP address bound by a GTP device | a GTP device name as in
cfg\n")
+{
+ struct osmo_sockaddr_str addr;
+ struct osmo_sockaddr osa_remote;
+ struct osmo_sockaddr osa_local;
+ struct upf_gtp_dev *gtp_dev = NULL;
+ const char *remote_str = argv[0];
+ const char *local_type = NULL;
+ const char *local_str = NULL;
+ if (argc > 1 && argc <= 3) {
+ vty_out(vty, "%% Error: missing argument after '%s'%s", argv[argc -
1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (argc > 2)
+ local_type = argv[2];
+ if (argc > 3)
+ local_str = argv[3];
+
+ /* GTP can be received on port 2152 only, i.e. the remote port must be 2152. (The
sending port is allowed to
+ * differ). */
+ if (osmo_sockaddr_str_from_str(&addr, remote_str, 2152)
+ || osmo_sockaddr_str_to_osa(&addr, &osa_remote)) {
+ vty_out(vty, "%% Error: invalid IP address: %s%s", osmo_quote_str(remote_str,
-1), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (local_type) {
+ if (!strcmp(local_type, "ip")) {
+ if (osmo_sockaddr_str_from_str(&addr, local_str, 2152)
+ || osmo_sockaddr_str_to_osa(&addr, &osa_local)) {
+ vty_out(vty, "%% Error: invalid IP address: %s%s",
osmo_quote_str(local_str, -1), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ gtp_dev = upf_gtp_dev_find_by_local_addr(&osa_local);
+ if (!gtp_dev) {
+ vty_out(vty, "%% Error: this does not seem to be a locally bound GTP address:
%s%s",
+ osmo_sockaddr_to_str_c(OTC_SELECT, &osa_local), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ } else {
+ gtp_dev = upf_gtp_dev_find_by_name(local_str);
+ if (!gtp_dev) {
+ vty_out(vty, "%% Error: there is no GTP device by the name of
'%s'%s",
+ local_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ } else {
+ gtp_dev = llist_first_entry_or_null(&g_upf->tunend.devs, struct upf_gtp_dev,
entry);
+ if (!gtp_dev) {
+ vty_out(vty, "%% Error: there is no GTP device to send Echo from%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ OSMO_ASSERT(gtp_dev);
+
+ if (upf_gtpu_echo_req_tx(gtp_dev, &osa_remote, g_upf->gtp.next_echo_seq_nr++)) {
+ vty_out(vty, "%%Error: Failed to transmit Echo Request (see DGTP logging)%s",
VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ vty_out(vty, "%s -> %s tx Echo Request; for responses, see DGTP logging level
INFO%s",
+ gtp_dev->name, osmo_sockaddr_to_str_c(OTC_SELECT, &osa_remote), VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
void upf_vty_init()
{
OSMO_ASSERT(g_upf != NULL);
@@ -495,6 +570,7 @@
install_element_ve(&show_session_cmd);
install_element_ve(&show_netinst_cmd);
install_element_ve(&show_nft_rule_append_cmd);
+ install_element_ve(>p_echo_tx_cmd);
install_node(&cfg_pfcp_node, config_write_pfcp);
install_element(CONFIG_NODE, &cfg_pfcp_cmd);
diff --git a/tests/gtp-echo.vty b/tests/gtp-echo.vty
new file mode 100644
index 0000000..620d36c
--- /dev/null
+++ b/tests/gtp-echo.vty
@@ -0,0 +1,178 @@
+OsmoUPF> list
+ show pid
+ show uptime
+ show version
+ show online-help
+ list [with-flags]
+ exit
+ help
+ show vty-attributes
+ show vty-attributes (application|library|global)
+ enable [expert-mode]
+ terminal length <0-512>
+ terminal no length
+ who
+ show history
+ logging enable
+ logging disable
+ logging filter all (0|1)
+ logging color (0|1)
+ logging timestamp (0|1)
+ logging print extended-timestamp (0|1)
+ logging print thread-id (0|1)
+ logging print category (0|1)
+ logging print category-hex (0|1)
+ logging print level (0|1)
+ logging print file (0|1|basename) [last]
+ logging set-log-mask MASK
+ logging level
(ref|peer|session|gtp|nft|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1|lio)
(debug|info|notice|error|fatal)
+ logging level set-all (debug|info|notice|error|fatal)
+ logging level force-all (debug|info|notice|error|fatal)
+ no logging level force-all
+ logp
(ref|peer|session|gtp|nft|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1|lio)
(debug|info|notice|error|fatal) .LOGMESSAGE
+ show logging vty
+ show alarms
+ show talloc-context (application|global|all) (full|brief|DEPTH)
+ show talloc-context (application|global|all) (full|brief|DEPTH) tree ADDRESS
+ show talloc-context (application|global|all) (full|brief|DEPTH) filter REGEXP
+ show cpu-sched threads
+ show pdr
+ show gtp
+ show session
+ show netinst [NAME]
+ gtp-echo tx to IP_ADDR [from] [(ip|dev)] [LOCAL_ADDR_OR_DEV_NAME]
+ show timer [(pfcp)] [TNNNN]
+OsmoUPF> enable
+OsmoUPF# list
+ help
+ list [with-flags]
+ show vty-attributes
+ show vty-attributes (application|library|global)
+ write terminal
+ write file [PATH]
+ write memory
+ write
+ show running-config
+ exit
+ disable
+ configure [terminal]
+ copy running-config startup-config
+ shutdown
+ show startup-config
+ show version
+ show online-help
+ terminal length <0-512>
+ terminal no length
+ who
+ show history
+ terminal monitor
+ terminal no monitor
+ logging enable
+ logging disable
+ logging filter all (0|1)
+ logging color (0|1)
+ logging timestamp (0|1)
+ logging print extended-timestamp (0|1)
+ logging print thread-id (0|1)
+ logging print category (0|1)
+ logging print category-hex (0|1)
+ logging print level (0|1)
+ logging print file (0|1|basename) [last]
+ logging set-log-mask MASK
+ logging level
(ref|peer|session|gtp|nft|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1|lio)
(debug|info|notice|error|fatal)
+ logging level set-all (debug|info|notice|error|fatal)
+ logging level force-all (debug|info|notice|error|fatal)
+ no logging level force-all
+ logp
(ref|peer|session|gtp|nft|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1|lio)
(debug|info|notice|error|fatal) .LOGMESSAGE
+ show logging vty
+ show alarms
+ show talloc-context (application|global|all) (full|brief|DEPTH)
+ show talloc-context (application|global|all) (full|brief|DEPTH) tree ADDRESS
+ show talloc-context (application|global|all) (full|brief|DEPTH) filter REGEXP
+ show cpu-sched threads
+ show pdr
+ show gtp
+ show session
+ show netinst [NAME]
+ gtp-echo tx to IP_ADDR [from] [(ip|dev)] [LOCAL_ADDR_OR_DEV_NAME]
+ show timer [(pfcp)] [TNNNN]
+OsmoUPF# configure terminal
+OsmoUPF(config)# list
+ help
+ list [with-flags]
+ show vty-attributes
+ show vty-attributes (application|library|global)
+ write terminal
+ write file [PATH]
+ write memory
+ write
+ show running-config
+ exit
+ end
+ hostname WORD
+ no hostname [HOSTNAME]
+ password (8|) WORD
+ password LINE
+ enable password (8|) WORD
+ enable password LINE
+ no enable password
+ banner motd default
+ banner motd file [FILE]
+ no banner motd
+ service terminal-length <0-512>
+ no service terminal-length [<0-512>]
+ line vty
+ service advanced-vty
+ no service advanced-vty
+ show history
+ ctrl
+ log stderr [blocking-io]
+ no log stderr
+ log file FILENAME [blocking-io]
+ no log file FILENAME
+ log alarms <2-32700>
+ no log alarms
+ log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)
+ log syslog local <0-7>
+ no log syslog
+ log systemd-journal [raw]
+ no log systemd-journal
+ log gsmtap [HOSTNAME]
+ no log gsmtap [HOSTNAME]
+ cpu-sched
+ pfcp
+ tunend
+ tunmap
+ netinst
+ timer [(pfcp)] [TNNNN] [(<0-2147483647>|default)]
+OsmoUPF(config)# end
+
+OsmoUPF# gtp-echo?
+ gtp-echo GTP1-U Echo probing
+OsmoUPF# gtp-echo ?
+ tx Send a GTP1-U Echo Request to a remote peer
+OsmoUPF# gtp-echo tx ?
+ to Send to remote peer's GTP address
+OsmoUPF# gtp-echo tx to ?
+ IP_ADDR IP address like 1.2.3.4 or 1:2:3::4
+OsmoUPF# gtp-echo tx to 1.2.3.4 ?
+ [from] Choose local GTP device to send from; when omitted, choose first GTP device.
+OsmoUPF# gtp-echo tx to 1.2.3.4 from ?
+ [ip] Choose local GTP device by IP address
+ [dev] Choose local GTP device by configured name
+OsmoUPF# gtp-echo tx to 1.2.3.4 from ip ?
+ [LOCAL_ADDR_OR_DEV_NAME] A local IP address bound by a GTP device | a GTP device name
as in cfg
+OsmoUPF# gtp-echo tx to 1.2.3.4 from dev ?
+ [LOCAL_ADDR_OR_DEV_NAME] A local IP address bound by a GTP device | a GTP device name
as in cfg
+OsmoUPF# gtp-echo tx to 1.2.3.4
+% Error: there is no GTP device to send Echo from
+OsmoUPF# gtp-echo tx to 1.2.3.4 from
+% Error: missing argument after 'from'
+OsmoUPF# gtp-echo tx to 1.2.3.4 from ip
+% Error: missing argument after 'ip'
+OsmoUPF# gtp-echo tx to 1.2.3.4 from dev
+% Error: missing argument after 'dev'
+OsmoUPF# gtp-echo tx to 1.2.3.4 from ip 1.2.3.4
+% Error: this does not seem to be a locally bound GTP address: 1.2.3.4:2152
+OsmoUPF# gtp-echo tx to 1.2.3.4 from dev apn0
+% Error: there is no GTP device by the name of 'apn0'
--
To view, visit
https://gerrit.osmocom.org/c/osmo-upf/+/37830?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: I970dccd7a27b098eea9e660822e24e2c4b059fc6
Gerrit-Change-Number: 37830
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>