mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-upf.git
synced 2025-11-02 21:13:46 +00:00
Compare commits
1 Commits
pespin/mas
...
neels/gtp-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6c96707d3 |
@@ -117,6 +117,7 @@ struct g_upf {
|
||||
|
||||
struct {
|
||||
uint32_t next_local_teid_state;
|
||||
uint16_t next_echo_seq_nr;
|
||||
} gtp;
|
||||
|
||||
struct llist_head netinst;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -122,6 +122,45 @@ static int tx_echo_resp(struct upf_gtp_dev *dev, const struct osmo_sockaddr *rem
|
||||
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;
|
||||
|
||||
@@ -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,105 @@ DEFUN(show_session, show_session_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* variant:
|
||||
* 0 "gtp-echo send to (A.B.C.D|X:X::X:X)"
|
||||
* 1 "gtp-echo send to (A.B.C.D|X:X::X:X) local-ip (A.B.C.D|X:X::X:X)"
|
||||
* 2 "gtp-echo send to (A.B.C.D|X:X::X:X) local-dev DEV_NAME"
|
||||
*/
|
||||
int _gtp_echo_tx(struct vty *vty, int variant, int argc, const char **argv)
|
||||
{
|
||||
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_str = NULL;
|
||||
if (argc > 1)
|
||||
local_str = argv[1];
|
||||
|
||||
/* 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: cannot send Echo: invalid IP address: %s%s",
|
||||
osmo_quote_str(remote_str, -1), VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
switch (variant) {
|
||||
case 0:
|
||||
gtp_dev = llist_first_entry_or_null(&g_upf->tunend.devs, struct upf_gtp_dev, entry);
|
||||
if (!gtp_dev) {
|
||||
vty_out(vty, "%% Error: cannot send Echo: there is no GTP device%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (osmo_sockaddr_str_from_str(&addr, local_str, 2152)
|
||||
|| osmo_sockaddr_str_to_osa(&addr, &osa_local)) {
|
||||
vty_out(vty, "%% Error: cannot send Echo: 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: cannot send Echo: 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;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
gtp_dev = upf_gtp_dev_find_by_name(local_str);
|
||||
if (!gtp_dev) {
|
||||
vty_out(vty, "%% Error: cannot send Echo: there is no GTP device by the name of '%s'%s",
|
||||
local_str, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
#define IP46_STR "IPv4 address\nIPv6 address\n"
|
||||
#define GTP_ECHO_TX_STR \
|
||||
"GTP1-U Echo probing\n" \
|
||||
"Send a GTP1-U Echo Request to a remote peer\n" \
|
||||
"Send to remote peer's GTP address\n" IP46_STR
|
||||
|
||||
DEFUN(gtp_echo_tx, gtp_echo_tx_cmd,
|
||||
"gtp-echo send to (A.B.C.D|X:X::X:X)",
|
||||
GTP_ECHO_TX_STR)
|
||||
{
|
||||
return _gtp_echo_tx(vty, 0, argc, argv);
|
||||
}
|
||||
|
||||
DEFUN(gtp_echo_tx_local_ip, gtp_echo_tx_local_ip_cmd,
|
||||
"gtp-echo send to (A.B.C.D|X:X::X:X) local-ip (A.B.C.D|X:X::X:X)",
|
||||
GTP_ECHO_TX_STR
|
||||
"Send from local GTP device, chosen by IP address\n"
|
||||
IP46_STR)
|
||||
{
|
||||
return _gtp_echo_tx(vty, 1, argc, argv);
|
||||
}
|
||||
|
||||
DEFUN(gtp_echo_tx_local_dev, gtp_echo_tx_local_dev_cmd,
|
||||
"gtp-echo send to (A.B.C.D|X:X::X:X) local-dev DEV_NAME",
|
||||
GTP_ECHO_TX_STR
|
||||
"Send from local GTP device, chosen by name as configured in 'dev create' or 'dev use'.\n"
|
||||
"A GTP device name as it appears in the cfg\n")
|
||||
{
|
||||
return _gtp_echo_tx(vty, 2, argc, argv);
|
||||
}
|
||||
|
||||
void upf_vty_init()
|
||||
{
|
||||
OSMO_ASSERT(g_upf != NULL);
|
||||
@@ -495,6 +595,9 @@ 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(>p_echo_tx_cmd);
|
||||
install_element_ve(>p_echo_tx_local_ip_cmd);
|
||||
install_element_ve(>p_echo_tx_local_dev_cmd);
|
||||
|
||||
install_node(&cfg_pfcp_node, config_write_pfcp);
|
||||
install_element(CONFIG_NODE, &cfg_pfcp_cmd);
|
||||
|
||||
42
tests/gtp-echo.vty
Normal file
42
tests/gtp-echo.vty
Normal file
@@ -0,0 +1,42 @@
|
||||
OsmoUPF> list
|
||||
...
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X)
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X) local-ip (A.B.C.D|X:X::X:X)
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X) local-dev DEV_NAME
|
||||
...
|
||||
OsmoUPF> enable
|
||||
OsmoUPF# list
|
||||
...
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X)
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X) local-ip (A.B.C.D|X:X::X:X)
|
||||
gtp-echo send to (A.B.C.D|X:X::X:X) local-dev DEV_NAME
|
||||
...
|
||||
OsmoUPF# configure terminal
|
||||
OsmoUPF(config)# list
|
||||
... !gtp-echo
|
||||
OsmoUPF(config)# end
|
||||
|
||||
OsmoUPF# gtp-echo?
|
||||
gtp-echo GTP1-U Echo probing
|
||||
OsmoUPF# gtp-echo ?
|
||||
send Send a GTP1-U Echo Request to a remote peer
|
||||
OsmoUPF# gtp-echo send ?
|
||||
to Send to remote peer's GTP address
|
||||
OsmoUPF# gtp-echo send to ?
|
||||
A.B.C.D IPv4 address
|
||||
X:X::X:X IPv6 address
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4 ?
|
||||
local-ip Send from local GTP device, chosen by IP address
|
||||
local-dev Send from local GTP device, chosen by name as configured in 'dev create' or 'dev use'.
|
||||
<cr>
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4 local-ip ?
|
||||
A.B.C.D IPv4 address
|
||||
X:X::X:X IPv6 address
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4 local-dev ?
|
||||
DEV_NAME A GTP device name as it appears in the cfg
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4
|
||||
% Error: cannot send Echo: there is no GTP device
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4 local-ip 1.2.3.4
|
||||
% Error: cannot send Echo: this does not seem to be a locally bound GTP address: 1.2.3.4:2152
|
||||
OsmoUPF# gtp-echo send to 1.2.3.4 local-dev apn0
|
||||
% Error: cannot send Echo: there is no GTP device by the name of 'apn0'
|
||||
Reference in New Issue
Block a user