diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 698aa69a4b..2e0ee684ff 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -1873,3 +1874,29 @@ void cmsg_close_all(struct msghdr *mh) { } } } + +int tos_to_priority(uint8_t tos) { + /* Map the IP Precedence (top 3 bits of the TOS field) to Linux internal packet priorities + * (TC_PRIO_*). This exactly mirrors the standard Linux kernel IP precedence-to-priority mapping + * (rt_tos2priority) to ensure consistent behavior when explicitly setting SO_PRIORITY. */ + switch (IPTOS_PREC(tos)) { + case IPTOS_PREC_NETCONTROL: /* 0xc0 (CS7) - Network Control. Used for infrastructure control (e.g., STP, keepalives). */ + case IPTOS_PREC_INTERNETCONTROL: /* 0xe0 (CS6) - Internetwork Control. Used for routing protocols (e.g., OSPF, BGP) and DHCP. */ + return TC_PRIO_CONTROL; + + case IPTOS_PREC_CRITIC_ECP: /* 0xa0 (CS5) - Critical. Used for delay-sensitive traffic like Voice over IP (VoIP). */ + case IPTOS_PREC_FLASHOVERRIDE: /* 0x80 (CS4) - Flash Override. Used for interactive video and multimedia. */ + return TC_PRIO_INTERACTIVE; + + case IPTOS_PREC_FLASH: /* 0x60 (CS3) - Flash. Used for broadcast video and call signaling (e.g., SIP). */ + case IPTOS_PREC_IMMEDIATE: /* 0x40 (CS2) - Immediate. Used for OAM (Operations, Administration, and Management) and transactional data. */ + return TC_PRIO_INTERACTIVE_BULK; + + case IPTOS_PREC_PRIORITY: /* 0x20 (CS1) - Priority. Used for background traffic and bulk data transfers. */ + return TC_PRIO_BULK; + + case IPTOS_PREC_ROUTINE: /* 0x00 (CS0) - Routine. Best effort traffic. */ + default: + return TC_PRIO_BESTEFFORT; + } +} diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 78b948ad46..208eb7ac07 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -270,3 +270,5 @@ int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_ int socket_get_cookie(int fd, uint64_t *ret); void cmsg_close_all(struct msghdr *mh); + +int tos_to_priority(uint8_t tos); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 090839ac06..713844b09b 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include "alloc-util.h" @@ -530,4 +532,22 @@ TEST(getpeerpidref) { ASSERT_TRUE(!pidref_equal(&pidref0, &pidref_pid1)); } +TEST(tos_to_priority) { + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS7), TC_PRIO_CONTROL); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS6), TC_PRIO_CONTROL); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS5), TC_PRIO_INTERACTIVE); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS4), TC_PRIO_INTERACTIVE); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS3), TC_PRIO_INTERACTIVE_BULK); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS2), TC_PRIO_INTERACTIVE_BULK); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS1), TC_PRIO_BULK); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS0), TC_PRIO_BESTEFFORT); + + /* check if lower bits are correctly filtered. */ + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS7 | IPTOS_LOWDELAY), TC_PRIO_CONTROL); + ASSERT_EQ(tos_to_priority(IPTOS_CLASS_CS1 | IPTOS_LOWCOST), TC_PRIO_BULK); + + ASSERT_EQ(tos_to_priority(0x00), TC_PRIO_BESTEFFORT); + ASSERT_EQ(tos_to_priority(0xff), TC_PRIO_CONTROL); +} + DEFINE_TEST_MAIN(LOG_DEBUG);