Print this page
13175 Add support for IP_RECVTOS
13182 CMSG_ macros should have man pages
Change-ID: I784aa36cfd3c17e3cccbf1fd329fa7e69b663ef9

@@ -22,10 +22,11 @@
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2019 Joyent, Inc.
  * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  */
 
 /* This file contains all TCP input processing functions. */
 
 #include <sys/types.h>

@@ -5106,10 +5107,19 @@
         mblk_t *mp1;
         conn_t  *connp = tcp->tcp_connp;
 
         optlen = 0;
         addflag.crb_all = 0;
+
+        /* If app asked for TOS and it has changed ... */
+        if (connp->conn_recv_ancillary.crb_recvtos &&
+            ipp->ipp_type_of_service != tcp->tcp_recvtos &&
+            (ira->ira_flags & IRAF_IS_IPV4)) {
+                optlen += sizeof (struct T_opthdr) +
+                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
+                addflag.crb_recvtos = 1;
+        }
         /* If app asked for pktinfo and the index has changed ... */
         if (connp->conn_recv_ancillary.crb_ip_recvpktinfo &&
             ira->ira_ruifindex != tcp->tcp_recvifindex) {
                 optlen += sizeof (struct T_opthdr) +
                     sizeof (struct in6_pktinfo);

@@ -5125,12 +5135,13 @@
         if (connp->conn_recv_ancillary.crb_ipv6_recvtclass &&
             ipp->ipp_tclass != tcp->tcp_recvtclass) {
                 optlen += sizeof (struct T_opthdr) + sizeof (uint_t);
                 addflag.crb_ipv6_recvtclass = 1;
         }
+
         /*
-         * If app asked for hopbyhop headers and it has changed ...
+         * If app asked for hop-by-hop headers and it has changed ...
          * For security labels, note that (1) security labels can't change on
          * a connected socket at all, (2) we're connected to at most one peer,
          * (3) if anything changes, then it must be some other extra option.
          */
         if (connp->conn_recv_ancillary.crb_ipv6_recvhopopts &&

@@ -5204,10 +5215,27 @@
         todi->PRIM_type = T_OPTDATA_IND;
         todi->DATA_flag = 1;    /* MORE data */
         todi->OPT_length = optlen;
         todi->OPT_offset = sizeof (*todi);
         optptr = (uchar_t *)&todi[1];
+
+        /* If app asked for TOS and it has changed ... */
+        if (addflag.crb_recvtos) {
+                toh = (struct T_opthdr *)optptr;
+                toh->level = IPPROTO_IP;
+                toh->name = IP_RECVTOS;
+                toh->len = sizeof (*toh) +
+                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
+                toh->status = 0;
+                optptr += sizeof (*toh);
+                *(uint8_t *)optptr = ipp->ipp_type_of_service;
+                optptr = (uchar_t *)toh + toh->len;
+                ASSERT(__TPI_TOPT_ISALIGNED(optptr));
+                /* Save as "last" value */
+                tcp->tcp_recvtos = ipp->ipp_type_of_service;
+        }
+
         /*
          * If app asked for pktinfo and the index has changed ...
          * Note that the local address never changes for the connection.
          */
         if (addflag.crb_ip_recvpktinfo) {