net: socket: Add support for setting pktinfo options

Add IP_PKTINFO or IPV6_RECVPKTINFO BSD socket options that
can be used to get extra information of received data in
the ancillary data in recvmsg() call.

For IPV6_RECVPKTINFO see RFC 3542 for details.
For IP_PKTINFO see Linux ip(7) manual page for details.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2023-11-22 15:08:59 +02:00 committed by Carles Cufí
parent c3acd56e27
commit 80704bb361
2 changed files with 57 additions and 0 deletions

View file

@ -1095,10 +1095,33 @@ struct ifreq {
/** sockopt: Set or receive the Type-Of-Service value for an outgoing packet. */
#define IP_TOS 1
/** sockopt: Pass an IP_PKTINFO ancillary message that contains a
* pktinfo structure that supplies some information about the
* incoming packet.
*/
#define IP_PKTINFO 8
struct in_pktinfo {
unsigned int ipi_ifindex; /* Interface index */
struct in_addr ipi_spec_dst; /* Local address */
struct in_addr ipi_addr; /* Header Destination address */
};
/* Socket options for IPPROTO_IPV6 level */
/** sockopt: Don't support IPv4 access (ignored, for compatibility) */
#define IPV6_V6ONLY 26
/** sockopt: Pass an IPV6_RECVPKTINFO ancillary message that contains a
* in6_pktinfo structure that supplies some information about the
* incoming packet. See RFC 3542.
*/
#define IPV6_RECVPKTINFO 49
struct in6_pktinfo {
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
unsigned int ipi6_ifindex; /* send/recv interface index */
};
/** sockopt: Set or receive the traffic class value for an outgoing packet. */
#define IPV6_TCLASS 67

View file

@ -2756,6 +2756,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
return 0;
}
break;
case IP_PKTINFO:
if (IS_ENABLED(CONFIG_NET_IPV4) &&
IS_ENABLED(CONFIG_NET_CONTEXT_RECV_PKTINFO)) {
ret = net_context_set_option(ctx,
NET_OPT_RECV_PKTINFO,
optval,
optlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
break;
}
@ -2777,6 +2794,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
return 0;
case IPV6_RECVPKTINFO:
if (IS_ENABLED(CONFIG_NET_IPV6) &&
IS_ENABLED(CONFIG_NET_CONTEXT_RECV_PKTINFO)) {
ret = net_context_set_option(ctx,
NET_OPT_RECV_PKTINFO,
optval,
optlen);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
break;
case IPV6_TCLASS:
if (IS_ENABLED(CONFIG_NET_CONTEXT_DSCP_ECN)) {
ret = net_context_set_option(ctx,