Print this page
13175 Add support for IP_RECVTOS
13182 CMSG_ macros should have man pages
Change-ID: I784aa36cfd3c17e3cccbf1fd329fa7e69b663ef9
@@ -19,10 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1990 Mentat Inc. */
#include <sys/types.h>
#include <sys/stream.h>
@@ -233,15 +234,26 @@
sizeof (timestruc_t) + _POINTER_ALIGNMENT;
IP_STAT(ipst, conn_in_timestamp);
}
/*
+ * If IP_RECVTOS is set allocate the appropriately sized buffer
+ */
+ if (recv_ancillary.crb_recvtos &&
+ (ira->ira_flags & IRAF_IS_IPV4)) {
+ ancil_size += sizeof (struct T_opthdr) +
+ P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
+ IP_STAT(ipst, conn_in_recvtos);
+ }
+
+ /*
* If IP_RECVTTL is set allocate the appropriate sized buffer
*/
if (recv_ancillary.crb_recvttl &&
(ira->ira_flags & IRAF_IS_IPV4)) {
- ancil_size += sizeof (struct T_opthdr) + sizeof (uint8_t);
+ ancil_size += sizeof (struct T_opthdr) +
+ P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
IP_STAT(ipst, conn_in_recvttl);
}
return (ancil_size);
}
@@ -547,33 +559,46 @@
gethrestime((timestruc_t *)ancil_buf);
ancil_buf = (uchar_t *)toh + toh->len;
ancil_size -= toh->len;
}
- /*
- * CAUTION:
- * Due to aligment issues
- * Processing of IP_RECVTTL option
- * should always be the last. Adding
- * any option processing after this will
- * cause alignment panic.
- */
+ if (recv_ancillary.crb_recvtos &&
+ (ira->ira_flags & IRAF_IS_IPV4)) {
+ struct T_opthdr *toh;
+ uint8_t *dstptr;
+
+ toh = (struct T_opthdr *)ancil_buf;
+ toh->level = IPPROTO_IP;
+ toh->name = IP_RECVTOS;
+ toh->len = sizeof (struct T_opthdr) +
+ P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
+ toh->status = 0;
+ ancil_buf += sizeof (struct T_opthdr);
+ dstptr = (uint8_t *)ancil_buf;
+ *dstptr = ipp->ipp_type_of_service;
+ ancil_buf = (uchar_t *)toh + toh->len;
+ ancil_size -= toh->len;
+ ASSERT(__TPI_TOPT_ISALIGNED(toh));
+ }
+
if (recv_ancillary.crb_recvttl &&
(ira->ira_flags & IRAF_IS_IPV4)) {
struct T_opthdr *toh;
uint8_t *dstptr;
toh = (struct T_opthdr *)ancil_buf;
toh->level = IPPROTO_IP;
toh->name = IP_RECVTTL;
- toh->len = sizeof (struct T_opthdr) + sizeof (uint8_t);
+ toh->len = sizeof (struct T_opthdr) +
+ P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
toh->status = 0;
ancil_buf += sizeof (struct T_opthdr);
dstptr = (uint8_t *)ancil_buf;
*dstptr = ipp->ipp_hoplimit;
- ancil_buf += sizeof (uint8_t);
+ ancil_buf = (uchar_t *)toh + toh->len;
ancil_size -= toh->len;
+ ASSERT(__TPI_TOPT_ISALIGNED(toh));
}
/* Consumed all of allocated space */
ASSERT(ancil_size == 0);
@@ -771,10 +796,13 @@
*i1 = connp->conn_recv_ancillary.crb_recvslla;
break; /* goto sizeof (int) option return */
case IP_RECVTTL:
*i1 = connp->conn_recv_ancillary.crb_recvttl;
break; /* goto sizeof (int) option return */
+ case IP_RECVTOS:
+ *i1 = connp->conn_recv_ancillary.crb_recvtos;
+ break; /* goto sizeof (int) option return */
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
case IP_BLOCK_SOURCE:
@@ -1363,10 +1391,15 @@
case IP_RECVTTL:
mutex_enter(&connp->conn_lock);
connp->conn_recv_ancillary.crb_recvttl = onoff;
mutex_exit(&connp->conn_lock);
break;
+ case IP_RECVTOS:
+ mutex_enter(&connp->conn_lock);
+ connp->conn_recv_ancillary.crb_recvtos = onoff;
+ mutex_exit(&connp->conn_lock);
+ break;
case IP_PKTINFO: {
/*
* This also handles IP_RECVPKTINFO.
* IP_PKTINFO and IP_RECVPKTINFO have same value.
* Differentiation is based on the size of the