Skip to content

Commit 05f8edf

Browse files
Cristib05jhedberg
authored andcommitted
net: socket: Add support for setting hop limit options
Add IP_RECVTTL or IPV6_RECVHOPLIMIT BSD socket options that can be used to extract ttl/hop limit from ancillary data in recvmsg() call. Signed-off-by: Cristian Bulacu <[email protected]>
1 parent 4388cb1 commit 05f8edf

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

include/zephyr/net/socket.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* Copyright (c) 2017-2018 Linaro Limited
1010
* Copyright (c) 2021 Nordic Semiconductor
1111
* Copyright (c) 2025 Aerlync Labs Inc.
12+
* Copyright 2025 NXP
1213
*
1314
* SPDX-License-Identifier: Apache-2.0
1415
*/
@@ -991,6 +992,11 @@ struct in_pktinfo {
991992
struct in_addr ipi_addr; /**< Header Destination address */
992993
};
993994

995+
/** Pass an IP_RECVTTL ancillary message that contains information
996+
* about the time to live of the incoming packet.
997+
*/
998+
#define IP_RECVTTL 12
999+
9941000
/** Retrieve the current known path MTU of the current socket. Returns an
9951001
* integer. IP_MTU is valid only for getsockopt and can be employed only when
9961002
* the socket has been connected.
@@ -1086,6 +1092,14 @@ struct ipv6_mreq {
10861092
*/
10871093
#define IPV6_RECVPKTINFO 49
10881094

1095+
/** Pass an IPV6_RECVHOPLIMIT ancillary message that contains information
1096+
* about the hop limit of the incoming packet. See RFC 3542.
1097+
*/
1098+
#define IPV6_RECVHOPLIMIT 51
1099+
1100+
/** Set or receive the hoplimit value for an outgoing packet. */
1101+
#define IPV6_HOPLIMIT 52
1102+
10891103
/** RFC5014: Source address selection. */
10901104
#define IPV6_ADDR_PREFERENCES 72
10911105

subsys/net/lib/sockets/sockets_inet.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2021 Nordic Semiconductor
44
* Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved.
55
* Copyright (c) 2025 Aerlync Labs Inc.
6+
* Copyright 2025 NXP
67
*
78
* SPDX-License-Identifier: Apache-2.0
89
*/
@@ -1061,6 +1062,35 @@ static int add_pktinfo(struct net_context *ctx,
10611062
return ret;
10621063
}
10631064

1065+
static int add_hoplimit(struct net_context *ctx,
1066+
struct net_pkt *pkt,
1067+
struct msghdr *msg)
1068+
{
1069+
int ret = -ENOTSUP;
1070+
1071+
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
1072+
int ttl = net_pkt_ipv4_ttl(pkt);
1073+
1074+
ret = insert_pktinfo(msg, IPPROTO_IP, IP_TTL,
1075+
&ttl, sizeof(ttl));
1076+
1077+
goto out;
1078+
}
1079+
1080+
if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
1081+
int hop_limit = net_pkt_ipv6_hop_limit(pkt);
1082+
1083+
ret = insert_pktinfo(msg, IPPROTO_IPV6, IPV6_HOPLIMIT,
1084+
&hop_limit, sizeof(hop_limit));
1085+
1086+
goto out;
1087+
}
1088+
1089+
out:
1090+
1091+
return ret;
1092+
}
1093+
10641094
static int update_msg_controllen(struct msghdr *msg)
10651095
{
10661096
struct cmsghdr *cmsg;
@@ -1231,6 +1261,13 @@ static ssize_t zsock_recv_dgram(struct net_context *ctx,
12311261
}
12321262
}
12331263

1264+
if (IS_ENABLED(CONFIG_NET_CONTEXT_RECV_HOPLIMIT) &&
1265+
net_context_is_recv_hoplimit_set(ctx)) {
1266+
if (add_hoplimit(ctx, pkt, msg) < 0) {
1267+
msg->msg_flags |= ZSOCK_MSG_CTRUNC;
1268+
}
1269+
}
1270+
12341271
/* msg_controllen must be updated to reflect the total length of all
12351272
* control messages in the buffer. If there are no control data,
12361273
* msg_controllen will be cleared as expected It will also take into
@@ -2584,6 +2621,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
25842621

25852622
break;
25862623

2624+
case IP_RECVTTL:
2625+
if (IS_ENABLED(CONFIG_NET_IPV4) &&
2626+
IS_ENABLED(CONFIG_NET_CONTEXT_RECV_HOPLIMIT)) {
2627+
ret = net_context_set_option(ctx,
2628+
NET_OPT_RECV_HOPLIMIT,
2629+
optval,
2630+
optlen);
2631+
if (ret < 0) {
2632+
errno = -ret;
2633+
return -1;
2634+
}
2635+
2636+
return 0;
2637+
}
2638+
2639+
break;
2640+
25872641
case IP_MULTICAST_IF:
25882642
if (IS_ENABLED(CONFIG_NET_IPV4)) {
25892643
return ipv4_multicast_if(ctx, optval, optlen, false);
@@ -2704,6 +2758,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
27042758

27052759
break;
27062760

2761+
case IPV6_RECVHOPLIMIT:
2762+
if (IS_ENABLED(CONFIG_NET_IPV6) &&
2763+
IS_ENABLED(CONFIG_NET_CONTEXT_RECV_HOPLIMIT)) {
2764+
ret = net_context_set_option(ctx,
2765+
NET_OPT_RECV_HOPLIMIT,
2766+
optval,
2767+
optlen);
2768+
if (ret < 0) {
2769+
errno = -ret;
2770+
return -1;
2771+
}
2772+
2773+
return 0;
2774+
}
2775+
2776+
break;
2777+
27072778
case IPV6_ADDR_PREFERENCES:
27082779
if (IS_ENABLED(CONFIG_NET_IPV6)) {
27092780
ret = net_context_set_option(ctx,

0 commit comments

Comments
 (0)