aboutsummaryrefslogtreecommitdiffstats
path: root/src/socket.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2021-04-28 13:27:12 +0200
committerHarald Welte <laforge@osmocom.org>2021-04-28 14:39:19 +0200
commit903e670c54d165ea5005a1117689e6344387c6f9 (patch)
tree29ff46971bce34e245eca3b84ab41bdf8b7e9ced /src/socket.c
parentc545ff6f3eec08730a87cf0e469c904180a16ff6 (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
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c43
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.