Print this page
13175 Add support for IP_RECVTOS
13182 CMSG_ macros should have man pages
Change-ID: I784aa36cfd3c17e3cccbf1fd329fa7e69b663ef9
        
*** 22,31 ****
--- 22,32 ----
  /*
   * 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,5115 ****
--- 5107,5125 ----
          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,5136 ****
          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 ...
           * 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 &&
--- 5135,5147 ----
          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 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,5213 ****
--- 5215,5241 ----
          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) {