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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/conn_opt.c
          +++ new/usr/src/uts/common/inet/ip/conn_opt.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  24   25   */
  25   26  /* Copyright (c) 1990 Mentat Inc. */
  26   27  
  27   28  #include <sys/types.h>
  28   29  #include <sys/stream.h>
  29   30  #include <sys/strsun.h>
  30   31  #define _SUN_TPI_VERSION 2
  31   32  #include <sys/tihdr.h>
  32   33  #include <sys/xti_inet.h>
  33   34  #include <sys/ucred.h>
↓ open down ↓ 194 lines elided ↑ open up ↑
 228  229           * argument, we allocate space necessary for extra
 229  230           * alignment (even though it might not be used).
 230  231           */
 231  232          if (recv_ancillary.crb_timestamp) {
 232  233                  ancil_size += sizeof (struct T_opthdr) +
 233  234                      sizeof (timestruc_t) + _POINTER_ALIGNMENT;
 234  235                  IP_STAT(ipst, conn_in_timestamp);
 235  236          }
 236  237  
 237  238          /*
      239 +         * If IP_RECVTOS is set allocate the appropriately sized buffer
      240 +         */
      241 +        if (recv_ancillary.crb_recvtos &&
      242 +            (ira->ira_flags & IRAF_IS_IPV4)) {
      243 +                ancil_size += sizeof (struct T_opthdr) +
      244 +                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
      245 +                IP_STAT(ipst, conn_in_recvtos);
      246 +        }
      247 +
      248 +        /*
 238  249           * If IP_RECVTTL is set allocate the appropriate sized buffer
 239  250           */
 240  251          if (recv_ancillary.crb_recvttl &&
 241  252              (ira->ira_flags & IRAF_IS_IPV4)) {
 242      -                ancil_size += sizeof (struct T_opthdr) + sizeof (uint8_t);
      253 +                ancil_size += sizeof (struct T_opthdr) +
      254 +                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
 243  255                  IP_STAT(ipst, conn_in_recvttl);
 244  256          }
 245  257  
 246  258          return (ancil_size);
 247  259  }
 248  260  
 249  261  /*
 250  262   * Lay down the ancillary data items at "ancil_buf".
 251  263   * Assumes caller has used conn_recvancillary_size to allocate a sufficiently
 252  264   * large buffer - ancil_size.
↓ open down ↓ 289 lines elided ↑ open up ↑
 542  554                  toh->status = 0;
 543  555                  ancil_buf += sizeof (struct T_opthdr);
 544  556                  /* Align for gethrestime() */
 545  557                  ancil_buf = (uchar_t *)P2ROUNDUP((intptr_t)ancil_buf,
 546  558                      sizeof (intptr_t));
 547  559                  gethrestime((timestruc_t *)ancil_buf);
 548  560                  ancil_buf = (uchar_t *)toh + toh->len;
 549  561                  ancil_size -= toh->len;
 550  562          }
 551  563  
 552      -        /*
 553      -         * CAUTION:
 554      -         * Due to aligment issues
 555      -         * Processing of IP_RECVTTL option
 556      -         * should always be the last. Adding
 557      -         * any option processing after this will
 558      -         * cause alignment panic.
 559      -         */
      564 +        if (recv_ancillary.crb_recvtos &&
      565 +            (ira->ira_flags & IRAF_IS_IPV4)) {
      566 +                struct  T_opthdr *toh;
      567 +                uint8_t *dstptr;
      568 +
      569 +                toh = (struct T_opthdr *)ancil_buf;
      570 +                toh->level = IPPROTO_IP;
      571 +                toh->name = IP_RECVTOS;
      572 +                toh->len = sizeof (struct T_opthdr) +
      573 +                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
      574 +                toh->status = 0;
      575 +                ancil_buf += sizeof (struct T_opthdr);
      576 +                dstptr = (uint8_t *)ancil_buf;
      577 +                *dstptr = ipp->ipp_type_of_service;
      578 +                ancil_buf = (uchar_t *)toh + toh->len;
      579 +                ancil_size -= toh->len;
      580 +                ASSERT(__TPI_TOPT_ISALIGNED(toh));
      581 +        }
      582 +
 560  583          if (recv_ancillary.crb_recvttl &&
 561  584              (ira->ira_flags & IRAF_IS_IPV4)) {
 562  585                  struct  T_opthdr *toh;
 563  586                  uint8_t *dstptr;
 564  587  
 565  588                  toh = (struct T_opthdr *)ancil_buf;
 566  589                  toh->level = IPPROTO_IP;
 567  590                  toh->name = IP_RECVTTL;
 568      -                toh->len = sizeof (struct T_opthdr) + sizeof (uint8_t);
      591 +                toh->len = sizeof (struct T_opthdr) +
      592 +                    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
 569  593                  toh->status = 0;
 570  594                  ancil_buf += sizeof (struct T_opthdr);
 571  595                  dstptr = (uint8_t *)ancil_buf;
 572  596                  *dstptr = ipp->ipp_hoplimit;
 573      -                ancil_buf += sizeof (uint8_t);
      597 +                ancil_buf = (uchar_t *)toh + toh->len;
 574  598                  ancil_size -= toh->len;
      599 +                ASSERT(__TPI_TOPT_ISALIGNED(toh));
 575  600          }
 576  601  
 577  602          /* Consumed all of allocated space */
 578  603          ASSERT(ancil_size == 0);
 579  604  
 580  605  }
 581  606  
 582  607  /*
 583  608   * This routine retrieves the current status of socket options.
 584  609   * It returns the size of the option retrieved, or -1.
↓ open down ↓ 181 lines elided ↑ open up ↑
 766  791                          break;  /* goto sizeof (int) option return */
 767  792                  case IP_RECVIF:
 768  793                          *i1 = connp->conn_recv_ancillary.crb_recvif;
 769  794                          break;  /* goto sizeof (int) option return */
 770  795                  case IP_RECVSLLA:
 771  796                          *i1 = connp->conn_recv_ancillary.crb_recvslla;
 772  797                          break;  /* goto sizeof (int) option return */
 773  798                  case IP_RECVTTL:
 774  799                          *i1 = connp->conn_recv_ancillary.crb_recvttl;
 775  800                          break;  /* goto sizeof (int) option return */
      801 +                case IP_RECVTOS:
      802 +                        *i1 = connp->conn_recv_ancillary.crb_recvtos;
      803 +                        break;  /* goto sizeof (int) option return */
 776  804                  case IP_ADD_MEMBERSHIP:
 777  805                  case IP_DROP_MEMBERSHIP:
 778  806                  case MCAST_JOIN_GROUP:
 779  807                  case MCAST_LEAVE_GROUP:
 780  808                  case IP_BLOCK_SOURCE:
 781  809                  case IP_UNBLOCK_SOURCE:
 782  810                  case IP_ADD_SOURCE_MEMBERSHIP:
 783  811                  case IP_DROP_SOURCE_MEMBERSHIP:
 784  812                  case MCAST_BLOCK_SOURCE:
 785  813                  case MCAST_UNBLOCK_SOURCE:
↓ open down ↓ 572 lines elided ↑ open up ↑
1358 1386          case IP_RECVSLLA:
1359 1387                  mutex_enter(&connp->conn_lock);
1360 1388                  connp->conn_recv_ancillary.crb_recvslla = onoff;
1361 1389                  mutex_exit(&connp->conn_lock);
1362 1390                  break;
1363 1391          case IP_RECVTTL:
1364 1392                  mutex_enter(&connp->conn_lock);
1365 1393                  connp->conn_recv_ancillary.crb_recvttl = onoff;
1366 1394                  mutex_exit(&connp->conn_lock);
1367 1395                  break;
     1396 +        case IP_RECVTOS:
     1397 +                mutex_enter(&connp->conn_lock);
     1398 +                connp->conn_recv_ancillary.crb_recvtos = onoff;
     1399 +                mutex_exit(&connp->conn_lock);
     1400 +                break;
1368 1401          case IP_PKTINFO: {
1369 1402                  /*
1370 1403                   * This also handles IP_RECVPKTINFO.
1371 1404                   * IP_PKTINFO and IP_RECVPKTINFO have same value.
1372 1405                   * Differentiation is based on the size of the
1373 1406                   * argument passed in.
1374 1407                   */
1375 1408                  struct in_pktinfo *pktinfo;
1376 1409  
1377 1410                  if (inlen == sizeof (int)) {
↓ open down ↓ 1561 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX