|
3 | 3 | * Copyright (c) 2021 Nordic Semiconductor
|
4 | 4 | * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved.
|
5 | 5 | * Copyright (c) 2025 Aerlync Labs Inc.
|
| 6 | + * Copyright 2025 NXP |
6 | 7 | *
|
7 | 8 | * SPDX-License-Identifier: Apache-2.0
|
8 | 9 | */
|
@@ -1061,6 +1062,35 @@ static int add_pktinfo(struct net_context *ctx,
|
1061 | 1062 | return ret;
|
1062 | 1063 | }
|
1063 | 1064 |
|
| 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 | + |
1064 | 1094 | static int update_msg_controllen(struct msghdr *msg)
|
1065 | 1095 | {
|
1066 | 1096 | struct cmsghdr *cmsg;
|
@@ -1231,6 +1261,13 @@ static ssize_t zsock_recv_dgram(struct net_context *ctx,
|
1231 | 1261 | }
|
1232 | 1262 | }
|
1233 | 1263 |
|
| 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 | + |
1234 | 1271 | /* msg_controllen must be updated to reflect the total length of all
|
1235 | 1272 | * control messages in the buffer. If there are no control data,
|
1236 | 1273 | * 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,
|
2584 | 2621 |
|
2585 | 2622 | break;
|
2586 | 2623 |
|
| 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 | + |
2587 | 2641 | case IP_MULTICAST_IF:
|
2588 | 2642 | if (IS_ENABLED(CONFIG_NET_IPV4)) {
|
2589 | 2643 | return ipv4_multicast_if(ctx, optval, optlen, false);
|
@@ -2704,6 +2758,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
|
2704 | 2758 |
|
2705 | 2759 | break;
|
2706 | 2760 |
|
| 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 | + |
2707 | 2778 | case IPV6_ADDR_PREFERENCES:
|
2708 | 2779 | if (IS_ENABLED(CONFIG_NET_IPV6)) {
|
2709 | 2780 | ret = net_context_set_option(ctx,
|
|
0 commit comments