Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177541891
D60962.1794671719.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
D60962.1794671719.diff
View Options
diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -235,6 +235,12 @@
#define LINUX_IP_BIND_ADDRESS_NO_PORT 24
#define LINUX_IP_RECVFRAGSIZE 25
+struct l_in_pktinfo {
+ l_int ipi_ifindex;
+ l_uint ipi_spec_dst;
+ l_uint ipi_addr;
+};
+
#define LINUX_IP_MULTICAST_IF 32
#define LINUX_IP_MULTICAST_TTL 33
#define LINUX_IP_MULTICAST_LOOP 34
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -48,6 +48,7 @@
#include <security/audit/audit.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -138,6 +139,9 @@
return (IP_RECVTTL);
case LINUX_IP_RECVTOS:
return (IP_RECVTOS);
+ case LINUX_IP_PKTINFO:
+ /* Handled specially by linux_setsockopt(). */
+ return (IP_RECVDSTADDR);
case LINUX_IP_FREEBIND:
LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_FREEBIND");
return (IP_BINDANY);
@@ -191,11 +195,6 @@
"unsupported IPv4 socket option IP_ROUTER_ALERT (%d), you can not do user-space routing from linux programs",
opt);
return (-2);
- case LINUX_IP_PKTINFO:
- LINUX_RATELIMIT_MSG_OPT1(
- "unsupported IPv4 socket option IP_PKTINFO (%d), you can not get extended packet info for datagram sockets in linux programs",
- opt);
- return (-2);
case LINUX_IP_PKTOPTIONS:
LINUX_RATELIMIT_MSG_OPT1(
"unsupported IPv4 socket option IP_PKTOPTIONS (%d)",
@@ -701,6 +700,8 @@
switch (cmsg_type) {
case IP_RECVORIGDSTADDR:
return (LINUX_IP_RECVORIGDSTADDR);
+ case IP_RECVDSTADDR:
+ return (LINUX_IP_PKTINFO);
case IP_RECVTOS:
return (LINUX_IP_TOS);
}
@@ -1420,6 +1421,7 @@
struct msghdr msg;
struct l_cmsghdr linux_cmsg;
struct l_cmsghdr *ptr_cmsg;
+ struct l_in_pktinfo pktinfo;
struct l_msghdr linux_msghdr;
struct iovec *iov;
socklen_t datalen;
@@ -1505,15 +1507,30 @@
if (datalen + CMSG_HDRSZ > MCLBYTES)
goto bad;
- /*
- * Now we support only SCM_RIGHTS and SCM_CRED,
- * so return EINVAL in any other cmsg_type
- */
cmsg = data;
- cmsg->cmsg_type =
- linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
cmsg->cmsg_level =
linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level);
+ if (cmsg->cmsg_level == IPPROTO_IP &&
+ linux_cmsg.cmsg_type == LINUX_IP_PKTINFO) {
+ if (sa_family != AF_INET ||
+ linux_cmsg.cmsg_len <
+ LINUX_CMSG_LEN(sizeof(pktinfo)))
+ goto bad;
+ len = sizeof(struct in_addr);
+ if (datalen + CMSG_SPACE(len) > MCLBYTES)
+ goto bad;
+ error = copyin(LINUX_CMSG_DATA(ptr_cmsg),
+ &pktinfo, sizeof(pktinfo));
+ if (error != 0)
+ goto bad;
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ bcopy(&pktinfo.ipi_spec_dst, CMSG_DATA(data),
+ len);
+ goto converted;
+ }
+
+ cmsg->cmsg_type =
+ linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
if (cmsg->cmsg_type == -1
|| cmsg->cmsg_level != SOL_SOCKET) {
linux_msg(curthread,
@@ -1552,6 +1569,7 @@
goto bad;
}
+converted:
cmsg->cmsg_len = CMSG_LEN(len);
data = (char *)data + CMSG_SPACE(len);
datalen += CMSG_SPACE(len);
@@ -1812,8 +1830,41 @@
}
static int
-recvmsg_scm_ipproto_ip(l_int msg_type, l_int lmsg_type, socklen_t *datalen,
- void **data, void **udata)
+recvmsg_scm_ip_pktinfo(struct mbuf *control, socklen_t *datalen, void **data,
+ void **udata)
+{
+ struct l_in_pktinfo *pktinfo;
+ struct sockaddr_dl *sdl;
+ struct cmsghdr *cm;
+ struct mbuf *m;
+
+ if (*datalen != sizeof(struct in_addr))
+ return (EINVAL);
+
+ pktinfo = malloc(sizeof(*pktinfo), M_LINUX, M_WAITOK | M_ZERO);
+ bcopy(*data, &pktinfo->ipi_spec_dst, sizeof(struct in_addr));
+ bcopy(*data, &pktinfo->ipi_addr, sizeof(struct in_addr));
+
+ for (m = control; m != NULL; m = m->m_next) {
+ cm = mtod(m, struct cmsghdr *);
+ if (cm->cmsg_level != IPPROTO_IP || cm->cmsg_type != IP_RECVIF)
+ continue;
+ if (cm->cmsg_len >= CMSG_LEN(offsetof(struct sockaddr_dl,
+ sdl_data))) {
+ sdl = (struct sockaddr_dl *)CMSG_DATA(cm);
+ pktinfo->ipi_ifindex = sdl->sdl_index;
+ }
+ break;
+ }
+
+ *data = *udata = pktinfo;
+ *datalen = sizeof(*pktinfo);
+ return (0);
+}
+
+static int
+recvmsg_scm_ipproto_ip(struct mbuf *control, l_int msg_type,
+ l_int lmsg_type, socklen_t *datalen, void **data, void **udata)
{
int error;
@@ -1823,6 +1874,9 @@
error = recvmsg_scm_ip_origdstaddr(datalen, data,
udata);
break;
+ case IP_RECVDSTADDR:
+ error = recvmsg_scm_ip_pktinfo(control, datalen, data, udata);
+ break;
}
return (error);
@@ -1911,6 +1965,9 @@
outbuf = PTRIN(l_msghdr.msg_control);
for (m = control; m != NULL; m = m->m_next) {
cm = mtod(m, struct cmsghdr *);
+ /* IP_RECVIF is folded into the Linux IP_PKTINFO message. */
+ if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF)
+ continue;
lcm->cmsg_type = bsd_to_linux_cmsg_type(p, cm->cmsg_type,
cm->cmsg_level);
lcm->cmsg_level = bsd_to_linux_sockopt_level(cm->cmsg_level);
@@ -1931,7 +1988,7 @@
switch (cm->cmsg_level) {
case IPPROTO_IP:
- error = recvmsg_scm_ipproto_ip(cm->cmsg_type,
+ error = recvmsg_scm_ipproto_ip(control, cm->cmsg_type,
lcm->cmsg_type, &datalen, &data, &udata);
break;
case SOL_SOCKET:
@@ -2176,6 +2233,26 @@
*/
return (0);
}
+ if (args->optname == LINUX_IP_PKTINFO) {
+ if (args->optlen < sizeof(val))
+ return (EINVAL);
+ error = copyin(PTRIN(args->optval), &val, sizeof(val));
+ if (error != 0)
+ return (error);
+ error = kern_setsockopt(td, args->s, IPPROTO_IP,
+ IP_RECVDSTADDR, &val, UIO_SYSSPACE, sizeof(val));
+ if (error != 0)
+ return (error);
+ error = kern_setsockopt(td, args->s, IPPROTO_IP,
+ IP_RECVIF, &val, UIO_SYSSPACE, sizeof(val));
+ if (error != 0) {
+ val = !val;
+ (void)kern_setsockopt(td, args->s, IPPROTO_IP,
+ IP_RECVDSTADDR, &val, UIO_SYSSPACE,
+ sizeof(val));
+ }
+ return (error);
+ }
name = linux_to_bsd_ip_sockopt(args->optname);
break;
case IPPROTO_IPV6:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 14, 3:55 PM (9 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41448794
Default Alt Text
D60962.1794671719.diff (6 KB)
Attached To
Mode
D60962: linux: Add support for IP_PKTINFO
Attached
Detach File
Event Timeline