diff options
author | Harald Welte <laforge@osmocom.org> | 2021-04-28 13:27:12 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2021-04-28 14:39:19 +0200 |
commit | 903e670c54d165ea5005a1117689e6344387c6f9 (patch) | |
tree | 29ff46971bce34e245eca3b84ab41bdf8b7e9ced | |
parent | c545ff6f3eec08730a87cf0e469c904180a16ff6 (diff) |
socket: IPv6 support for osmo_sock_set_dscp()
IPv6 has the analogous to DSCP: The "traffic class" field.
See https://tools.ietf.org/html/draft-itojun-ipv6-tclass-api-03
Change-Id: Ib31b977f67d60aa7f30ca4ab6eceba3d1d5eeee1
Related: SYS#5427
-rw-r--r-- | src/socket.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/src/socket.c b/src/socket.c index 6afe9865..59d0876f 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1800,25 +1800,54 @@ char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len, * \returns 0 on success; negative on error. */ int osmo_sock_set_dscp(int fd, uint8_t dscp) { + struct sockaddr_storage local_addr; + socklen_t local_addr_len = sizeof(local_addr); uint8_t tos; socklen_t tos_len = sizeof(tos); + int tclass; + socklen_t tclass_len = sizeof(tclass); int rc; /* DSCP is a 6-bit value stored in the upper 6 bits of the 8-bit TOS */ if (dscp > 63) return -EINVAL; - /* read the original value */ - rc = getsockopt(fd, IPPROTO_IP, IP_TOS, &tos, &tos_len); + rc = getsockname(fd, (struct sockaddr *)&local_addr, &local_addr_len); if (rc < 0) return rc; - /* mask-in the DSCP into the upper 6 bits */ - tos &= 0x03; - tos |= dscp << 2; + switch (local_addr.ss_family) { + case AF_INET: + /* read the original value */ + rc = getsockopt(fd, IPPROTO_IP, IP_TOS, &tos, &tos_len); + if (rc < 0) + return rc; + /* mask-in the DSCP into the upper 6 bits */ + tos &= 0x03; + tos |= dscp << 2; + /* and write it back to the kernel */ + rc = setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); + break; + case AF_INET6: + /* read the original value */ + rc = getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tclass, &tclass_len); + if (rc < 0) + return rc; + /* mask-in the DSCP into the upper 6 bits */ + tclass &= 0x03; + tclass |= dscp << 2; + /* and write it back to the kernel */ + rc = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof(tclass)); + break; + case AF_UNSPEC: + default: + LOGP(DLGLOBAL, LOGL_ERROR, "No DSCP support for socket family %u\n", + local_addr.ss_family); + rc = -1; + break; + } - /* and write it back to the kernel */ - return setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); + return rc; } /*! Set the priority value of a socket. |