diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2016-05-26 15:40:03 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2016-05-26 16:38:00 +0000 |
commit | 8d685a365d4db018a0b3e624d3fdb544e30bc42c (patch) | |
tree | 25262482ef8a98c3b6359fec6914885439e6c6cb /usr/src | |
parent | 430df2d8b04c918ae55249a677210a90ba43b9d4 (diff) | |
download | illumos-joyent-8d685a365d4db018a0b3e624d3fdb544e30bc42c.tar.gz |
OS-5432 lxbrand IP_RECVTTL cmsg not translated
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_socket.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_socket.c b/usr/src/uts/common/brand/lx/syscall/lx_socket.c index c8001add4f..e8e9714143 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_socket.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_socket.c @@ -649,7 +649,13 @@ typedef struct lx_cmsg_xlate { static int cmsg_conv_generic(struct cmsghdr *, struct cmsghdr *); static int stol_conv_ucred(struct cmsghdr *, struct cmsghdr *); static int ltos_conv_ucred(struct cmsghdr *, struct cmsghdr *); +static int stol_conv_recvttl(struct cmsghdr *, struct cmsghdr *); +/* + * Table describing SunOS <-> Linux cmsg translation mappings. + * Certain types (IP_RECVTTL) are only converted in one direction and are + * indicated by one of the translation functions being set to NULL. + */ static lx_cmsg_xlate_t lx_cmsg_xlate_tbl[] = { { SOL_SOCKET, SCM_RIGHTS, cmsg_conv_generic, LX_SOL_SOCKET, LX_SCM_RIGHTS, cmsg_conv_generic }, @@ -659,6 +665,10 @@ static lx_cmsg_xlate_t lx_cmsg_xlate_tbl[] = { LX_SOL_SOCKET, LX_SCM_TIMESTAMP, cmsg_conv_generic }, { IPPROTO_IP, IP_PKTINFO, cmsg_conv_generic, LX_IPPROTO_IP, LX_IP_PKTINFO, cmsg_conv_generic }, + { IPPROTO_IP, IP_RECVTTL, stol_conv_recvttl, + LX_IPPROTO_IP, LX_IP_TTL, NULL }, + { IPPROTO_IP, IP_TTL, cmsg_conv_generic, + LX_IPPROTO_IP, LX_IP_TTL, cmsg_conv_generic }, { IPPROTO_IPV6, IPV6_HOPLIMIT, cmsg_conv_generic, LX_IPPROTO_IPV6, LX_IPV6_HOPLIMIT, cmsg_conv_generic }, { IPPROTO_IPV6, IPV6_PKTINFO, cmsg_conv_generic, @@ -761,6 +771,25 @@ ltos_conv_ucred(struct cmsghdr *inmsg, struct cmsghdr *omsg) } static int +stol_conv_recvttl(struct cmsghdr *inmsg, struct cmsghdr *omsg) +{ + /* + * SunOS communicates the TTL of incoming packets via IP_RECVTTL using + * a uint8_t value instead of IP_TTL using an int. This conversion is + * only needed in the one direction since Linux does not handle + * IP_RECVTTL in the sendmsg path. + */ + if (omsg != NULL) { + uint8_t *inttl = (uint8_t *)CMSG_CONTENT(inmsg); + int *ottl = (int *)CMSG_CONTENT(omsg); + + *ottl = (int)*inttl; + } + + return (sizeof (struct cmsghdr) + sizeof (int)); +} + +static int cmsg_conv_generic(struct cmsghdr *inmsg, struct cmsghdr *omsg) { if (omsg != NULL) { @@ -785,8 +814,8 @@ lx_xlate_cmsg(struct cmsghdr *inmsg, struct cmsghdr *omsg, lx_xlate_dir_t dir) lx_cmsg_xlate_t *xlate = &lx_cmsg_xlate_tbl[i]; if (dir == LX_TO_SUNOS && inmsg->cmsg_level == xlate->lcx_linux_level && - inmsg->cmsg_type == xlate->lcx_linux_type) { - ASSERT(xlate->lcx_ltos_conv != NULL); + inmsg->cmsg_type == xlate->lcx_linux_type && + xlate->lcx_ltos_conv != NULL) { len = xlate->lcx_ltos_conv(inmsg, omsg); if (omsg != NULL) { omsg->cmsg_len = len; @@ -796,8 +825,8 @@ lx_xlate_cmsg(struct cmsghdr *inmsg, struct cmsghdr *omsg, lx_xlate_dir_t dir) return (len); } else if (dir == SUNOS_TO_LX && inmsg->cmsg_level == xlate->lcx_sunos_level && - inmsg->cmsg_type == xlate->lcx_sunos_type) { - ASSERT(xlate->lcx_stol_conv != NULL); + inmsg->cmsg_type == xlate->lcx_sunos_type && + xlate->lcx_stol_conv != NULL) { len = xlate->lcx_stol_conv(inmsg, omsg); if (omsg != NULL) { omsg->cmsg_len = len; |