jolly has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-sigtran/+/42809?usp=email )


Change subject: Add test case to verify proper DSCP settings
......................................................................

Add test case to verify proper DSCP settings

Related: SYS#8071
Change-Id: I6ac965998433b4d8213cce30fc3fcf8fe485a092
---
M .gitignore
M configure.ac
M tests/Makefile.am
A tests/dscp/Makefile.am
A tests/dscp/dscp_test.ok
A tests/dscp/dscp_test.py
A tests/dscp/get_tos_diag.c
A tests/dscp/osmo-stp-dscp.cfg
M tests/testsuite.at
9 files changed, 248 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran 
refs/changes/09/42809/1

diff --git a/.gitignore b/.gitignore
index 99cb052..8988066 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@
 tests/db/db_test
 tests/debug/debug_test
 tests/*/*_test
+tests/dscp/get_tos_diag

 tests/atconfig
 tests/package.m4
diff --git a/configure.ac b/configure.ac
index f1e1888..0bbc233 100644
--- a/configure.ac
+++ b/configure.ac
@@ -209,6 +209,7 @@
     tests/ss7/Makefile
     tests/tcap/Makefile
     tests/vty/Makefile
+    tests/dscp/Makefile
     examples/Makefile
     stp/Makefile
     doc/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7927bbd..5e056d4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = xua m2ua ss7 vty
+SUBDIRS = xua m2ua ss7 vty dscp

 if BUILD_WITH_TCAP_LOADSHARING
 SUBDIRS += tcap
diff --git a/tests/dscp/Makefile.am b/tests/dscp/Makefile.am
new file mode 100644
index 0000000..43b1fcd
--- /dev/null
+++ b/tests/dscp/Makefile.am
@@ -0,0 +1,18 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall $(LIBOSMONETIF_CFLAGS) $(LIBOSMOCORE_CFLAGS) 
$(LIBOSMOVTY_CFLAGS)
+
+AM_LDFLAGS = -no-install
+LDADD = $(top_builddir)/src/.libs/libosmo-sigtran.a \
+       $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) 
$(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS)
+
+if BUILD_WITH_TCAP_LOADSHARING
+LDADD += $(LIBOSMOASN1TCAP_LIBS)
+endif
+
+EXTRA_DIST = dscp_test.ok dscp_test.py
+
+check_PROGRAMS = get_tos_diag
+
+get_tos_diag_SOURCES = get_tos_diag.c
+
+
diff --git a/tests/dscp/dscp_test.ok b/tests/dscp/dscp_test.ok
new file mode 100644
index 0000000..66c7bc4
--- /dev/null
+++ b/tests/dscp/dscp_test.ok
@@ -0,0 +1,9 @@
+starting osmo-stp
+started osmo-stp
+LISTEN 127.0.0.1:2905 0.0.0.0:0 23
+ESTAB 127.0.0.1:2905 127.0.0.2:2906 23
+OTHER 127.0.0.1:2905 127.0.0.2:2906 23
+ESTAB 127.0.0.2:2906 127.0.0.1:2905 42
+OTHER 127.0.0.2:2906 127.0.0.1:2905 42
+stopping osmo-stp
+stopped osmo-stp
diff --git a/tests/dscp/dscp_test.py b/tests/dscp/dscp_test.py
new file mode 100755
index 0000000..0122257
--- /dev/null
+++ b/tests/dscp/dscp_test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+
+# (C) 2026 by sysmocom s.f.m.c. GmbH
+# 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 3 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/>.
+
+import subprocess
+import time
+import os
+import sys
+from pathlib import Path
+
+# Pfade definieren
+SCRIPT_DIR = Path(__file__).parent.resolve()
+STP_BINARY = SCRIPT_DIR / ".." / ".." / "stp" / "osmo-stp"
+CONFIG_FILE = SCRIPT_DIR / "osmo-stp-dscp.cfg"
+DIAG_BINARY = SCRIPT_DIR / "get_tos_diag"
+
+
+def main():
+    print(f"starting osmo-stp")
+
+    # 1. osmo-stp im Hintergrund starten
+    try:
+        proc = subprocess.Popen(
+            [STP_BINARY, "-c", CONFIG_FILE],
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            text=True
+        )
+    except FileNotFoundError:
+        print("File not found")
+        sys.exit(1)
+
+    # wait to establish socket connection
+    time.sleep(1.0)
+
+    # check process
+    if proc.poll() is not None:
+        print("Process failed")
+        stdout, stderr = proc.communicate()
+        print(f"STDOUT:\n{stdout}\nSTDERR:\n{stderr}", file=sys.stderr)
+        sys.exit(1)
+
+    print("started osmo-stp")
+
+    subprocess.run([DIAG_BINARY], check=True)
+
+    print("stopping osmo-stp")
+    proc.terminate()
+
+    try:
+        proc.wait(timeout=5)
+        print("stopped osmo-stp")
+    except subprocess.TimeoutExpired:
+        print("failed to stop, killing...")
+        proc.kill()
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/dscp/get_tos_diag.c b/tests/dscp/get_tos_diag.c
new file mode 100644
index 0000000..d7bb2d8
--- /dev/null
+++ b/tests/dscp/get_tos_diag.c
@@ -0,0 +1,120 @@
+/*
+ * (C) 2026 by sysmocom s.f.m.c. GmbH
+ * 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 3 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/sock_diag.h>
+#include <linux/inet_diag.h>
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+
+#define BUFFER_SIZE 8192
+
+int main()
+{
+       int nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG);
+       if (nl_fd < 0) {
+               perror("Failed to open netlink socket.");
+               return 1;
+       }
+
+       struct {
+               struct nlmsghdr nlh;
+               struct inet_diag_req_v2 req;
+       } req;
+
+       memset(&req, 0, sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct inet_diag_req_v2));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+       req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
+
+       req.req.sdiag_family = AF_INET;
+       req.req.sdiag_protocol = IPPROTO_SCTP;
+       req.req.idiag_states = 0xFFFFFFFF;
+
+       req.req.idiag_ext = (1 << (INET_DIAG_TOS - 1));
+
+       if (send(nl_fd, &req, req.nlh.nlmsg_len, 0) < 0) {
+               perror("Failed to sent netlink request.");
+               close(nl_fd);
+               return 1;
+       }
+
+       char buffer[BUFFER_SIZE];
+
+       while (1) {
+               ssize_t num_bytes = recv(nl_fd, buffer, sizeof(buffer), 0);
+               if (num_bytes < 0) {
+                       perror("Failed to receive netlink response.");
+                       break;
+               }
+
+               struct nlmsghdr *nlh = (struct nlmsghdr *)buffer;
+               while (NLMSG_OK(nlh, num_bytes)) {
+                       if (nlh->nlmsg_type == NLMSG_DONE) {
+                               close(nl_fd);
+                               return 0;
+                       }
+                       if (nlh->nlmsg_type == NLMSG_ERROR) {
+                               perror("Netlink error received.");
+                               close(nl_fd);
+                               return 1;
+                       }
+
+                       struct inet_diag_msg *diag_msg = NLMSG_DATA(nlh);
+
+                       char src_ip[INET_ADDRSTRLEN], dst_ip[INET_ADDRSTRLEN];
+                       inet_ntop(AF_INET, &diag_msg->id.idiag_src, src_ip, 
sizeof(src_ip));
+                       inet_ntop(AF_INET, &diag_msg->id.idiag_dst, dst_ip, 
sizeof(dst_ip));
+
+                       uint16_t src_port = ntohs(diag_msg->id.idiag_sport);
+                       uint16_t dst_port = ntohs(diag_msg->id.idiag_dport);
+
+                       char src_addr[32], dst_addr[32];
+                       snprintf(src_addr, sizeof(src_addr), "%s:%d", src_ip, 
src_port);
+                       snprintf(dst_addr, sizeof(dst_addr), "%s:%d", dst_ip, 
dst_port);
+
+                       const char *state_str = (diag_msg->idiag_state == 
TCP_ESTABLISHED) ? "ESTAB" :
+                                               (diag_msg->idiag_state == 
TCP_LISTEN) ? "LISTEN" : "OTHER";
+
+                       uint8_t tos = 0;
+
+                       int rta_len = nlh->nlmsg_len - 
NLMSG_LENGTH(sizeof(struct inet_diag_msg));
+                       struct rtattr *attr = (struct rtattr *)(diag_msg + 1);
+
+                       while (RTA_OK(attr, rta_len)) {
+                               if (attr->rta_type == INET_DIAG_TOS) {
+                                       tos = *(uint8_t *)RTA_DATA(attr);
+                                       break;
+                               }
+                               attr = RTA_NEXT(attr, rta_len);
+                       }
+
+                       /* state local remote dscp */
+                       printf("%s %s %s %d\n", state_str, src_addr, dst_addr, 
tos>>2);
+                       nlh = NLMSG_NEXT(nlh, num_bytes);
+               }
+       }
+
+       close(nl_fd);
+       return 0;
+}
diff --git a/tests/dscp/osmo-stp-dscp.cfg b/tests/dscp/osmo-stp-dscp.cfg
new file mode 100644
index 0000000..74f85ef
--- /dev/null
+++ b/tests/dscp/osmo-stp-dscp.cfg
@@ -0,0 +1,22 @@
+log stderr
+ logging filter all 1
+ logging color 1
+ logging print category 1
+ logging timestamp 0
+ logging level set-all notice
+line vty
+ no login
+!
+cs7 instance 0
+ xua rkm routing-key-allocation dynamic-permitted
+ listen m3ua 2905
+  accept-asp-connections dynamic-permitted
+  local-ip 127.0.0.1
+  ip-dscp 23
+ asp asp-clnt-m3ua 2905 2906 m3ua
+  local-ip 127.0.0.2
+  remote-ip 127.0.0.1
+  ip-dscp 42
+  role asp
+  sctp-role client
+  no shutdown
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 910fc0b..7812c93 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -26,3 +26,9 @@
 cat $abs_srcdir/tcap/tcap_transaction_tracking_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/tcap/tcap_transaction_tracking_test], [], 
[expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([dscp])
+AT_KEYWORDS([dscp])
+cat $abs_srcdir/dscp/dscp_test.ok > expout
+AT_CHECK([python3 -u $abs_top_builddir/tests/dscp/dscp_test.py], [], [expout], 
[ignore])
+AT_CLEANUP

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/42809?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I6ac965998433b4d8213cce30fc3fcf8fe485a092
Gerrit-Change-Number: 42809
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <[email protected]>

Reply via email to