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(&gtp_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 <[email protected]>

Reply via email to