diff options
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r-- | usr/src/uts/common/fs/sockfs/socksubr.c | 20 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/conn_opt.c | 55 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip_stack.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ipclassifier.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_input.c | 30 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_opt_data.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp_opt_data.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/netinet/in.h | 12 |
11 files changed, 127 insertions, 26 deletions
diff --git a/usr/src/uts/common/fs/sockfs/socksubr.c b/usr/src/uts/common/fs/sockfs/socksubr.c index 2fc51eba4a..73c36ce0d4 100644 --- a/usr/src/uts/common/fs/sockfs/socksubr.c +++ b/usr/src/uts/common/fs/sockfs/socksubr.c @@ -1318,8 +1318,24 @@ so_opt2cmsg(mblk_t *mp, void *opt, t_uscalar_t optlen, int oldflg, cmsg->cmsg_level = tohp->level; cmsg->cmsg_type = tohp->name; - cmsg->cmsg_len = (socklen_t)(_TPI_TOPT_DATALEN(tohp) + - sizeof (struct cmsghdr)); + cmsg->cmsg_len = (socklen_t)sizeof (struct cmsghdr); + if (tohp->level == IPPROTO_IP && + (tohp->name == IP_RECVTOS || + tohp->name == IP_RECVTTL)) { + /* + * The data for these is a uint8_t but, in + * order to maintain alignment for any + * following TPI primitives in the message, + * there will be some trailing padding bytes + * which are included in the TPI_TOPT_DATALEN. + * For these types, we set the cmsg_len + * explicitly to the correct value. + */ + cmsg->cmsg_len += (socklen_t)sizeof (uint8_t); + } else { + cmsg->cmsg_len += + (socklen_t)(_TPI_TOPT_DATALEN(tohp)); + } /* copy content to control data part */ bcopy(&tohp[1], CMSG_CONTENT(cmsg), diff --git a/usr/src/uts/common/inet/ip/conn_opt.c b/usr/src/uts/common/inet/ip/conn_opt.c index 71ff8187d2..7aac9b655a 100644 --- a/usr/src/uts/common/inet/ip/conn_opt.c +++ b/usr/src/uts/common/inet/ip/conn_opt.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -235,11 +236,22 @@ conn_recvancillary_size(conn_t *connp, crb_t recv_ancillary, } /* + * 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); } @@ -549,14 +561,25 @@ conn_recvancillary_add(conn_t *connp, crb_t recv_ancillary, 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; @@ -565,13 +588,15 @@ conn_recvancillary_add(conn_t *connp, crb_t recv_ancillary, 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 */ @@ -773,6 +798,9 @@ conn_opt_get(conn_opt_arg_t *coa, t_scalar_t level, t_scalar_t name, 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: @@ -1365,6 +1393,11 @@ conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen, 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. diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 04b26edc4b..b073fe0895 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -25,6 +25,7 @@ * Copyright (c) 2017 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. * Copyright (c) 2019 Joyent, Inc. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/types.h> @@ -13975,6 +13976,7 @@ ip_kstat2_init(netstackid_t stackid, ip_stat_t *ip_statisticsp) { "conn_in_recvslla", KSTAT_DATA_UINT64 }, { "conn_in_recvucred", KSTAT_DATA_UINT64 }, { "conn_in_recvttl", KSTAT_DATA_UINT64 }, + { "conn_in_recvtos", KSTAT_DATA_UINT64 }, { "conn_in_recvhopopts", KSTAT_DATA_UINT64 }, { "conn_in_recvhoplimit", KSTAT_DATA_UINT64 }, { "conn_in_recvdstopts", KSTAT_DATA_UINT64 }, diff --git a/usr/src/uts/common/inet/ip_stack.h b/usr/src/uts/common/inet/ip_stack.h index 85885f9dd9..e45e44ad08 100644 --- a/usr/src/uts/common/inet/ip_stack.h +++ b/usr/src/uts/common/inet/ip_stack.h @@ -26,6 +26,7 @@ /* * Copyright 2019 Joyent, Inc. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #ifndef _INET_IP_STACK_H @@ -85,6 +86,7 @@ typedef struct ip_stat { kstat_named_t conn_in_recvslla; kstat_named_t conn_in_recvucred; kstat_named_t conn_in_recvttl; + kstat_named_t conn_in_recvtos; kstat_named_t conn_in_recvhopopts; kstat_named_t conn_in_recvhoplimit; kstat_named_t conn_in_recvdstopts; diff --git a/usr/src/uts/common/inet/ipclassifier.h b/usr/src/uts/common/inet/ipclassifier.h index ceff69a0a7..89968826b3 100644 --- a/usr/src/uts/common/inet/ipclassifier.h +++ b/usr/src/uts/common/inet/ipclassifier.h @@ -24,7 +24,7 @@ */ /* - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #ifndef _INET_IPCLASSIFIER_H @@ -185,6 +185,7 @@ typedef struct crb_s { crbb_recvslla : 1, /* IP_RECVSLLA option */ crbb_recvttl : 1, /* IP_RECVTTL option */ + crbb_recvtos : 1, /* IP_RECVTOS option */ crbb_ip_recvpktinfo : 1, /* IP*_RECVPKTINFO option */ crbb_ipv6_recvhoplimit : 1, /* IPV6_RECVHOPLIMIT option */ crbb_ipv6_recvhopopts : 1, /* IPV6_RECVHOPOPTS option */ @@ -208,6 +209,7 @@ typedef struct crb_s { #define crb_recvif crbu.crbb.crbb_recvif #define crb_recvslla crbu.crbb.crbb_recvslla #define crb_recvttl crbu.crbb.crbb_recvttl +#define crb_recvtos crbu.crbb.crbb_recvtos #define crb_ip_recvpktinfo crbu.crbb.crbb_ip_recvpktinfo #define crb_ipv6_recvhoplimit crbu.crbb.crbb_ipv6_recvhoplimit #define crb_ipv6_recvhopopts crbu.crbb.crbb_ipv6_recvhopopts diff --git a/usr/src/uts/common/inet/tcp.h b/usr/src/uts/common/inet/tcp.h index 5058412c32..8b1e9bcb07 100644 --- a/usr/src/uts/common/inet/tcp.h +++ b/usr/src/uts/common/inet/tcp.h @@ -23,6 +23,7 @@ * Copyright (c) 2011, Joyent, Inc. All rights reserved. * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014, 2017 by Delphix. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -376,6 +377,7 @@ typedef struct tcp_s { int tcp_ipsec_overhead; + uint_t tcp_recvtos; /* Last received IP_RECVTOS */ uint_t tcp_recvifindex; /* Last received IPV6_RCVPKTINFO */ uint_t tcp_recvhops; /* Last received IPV6_RECVHOPLIMIT */ uint_t tcp_recvtclass; /* Last received IPV6_RECVTCLASS */ diff --git a/usr/src/uts/common/inet/tcp/tcp_input.c b/usr/src/uts/common/inet/tcp/tcp_input.c index 490308f60e..b3e4a07303 100644 --- a/usr/src/uts/common/inet/tcp/tcp_input.c +++ b/usr/src/uts/common/inet/tcp/tcp_input.c @@ -24,6 +24,7 @@ * 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. */ @@ -5108,6 +5109,15 @@ tcp_input_add_ancillary(tcp_t *tcp, mblk_t *mp, ip_pkt_t *ipp, 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) { @@ -5127,8 +5137,9 @@ tcp_input_add_ancillary(tcp_t *tcp, mblk_t *mp, ip_pkt_t *ipp, 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. @@ -5206,6 +5217,23 @@ tcp_input_add_ancillary(tcp_t *tcp, mblk_t *mp, ip_pkt_t *ipp, 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. diff --git a/usr/src/uts/common/inet/tcp/tcp_opt_data.c b/usr/src/uts/common/inet/tcp/tcp_opt_data.c index 03dad923be..fa7c8b2f48 100644 --- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c +++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c @@ -23,6 +23,7 @@ * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/types.h> @@ -156,6 +157,7 @@ opdes_t tcp_opt_arr[] = { { T_IP_TOS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, { IP_TTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_DEF_FN, sizeof (int), -1 /* not initialized */ }, +{ IP_RECVTOS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, { IP_SEC_OPT, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_NODEFAULT, sizeof (ipsec_req_t), -1 /* not initialized */ }, @@ -527,9 +529,9 @@ tcp_opt_set(conn_t *connp, uint_t optset_context, int level, int name, /* * Note: Implies T_CHECK semantics for T_OPTCOM_REQ * inlen != 0 implies value supplied and - * we have to "pretend" to set it. + * we have to "pretend" to set it. * inlen == 0 implies that there is no - * value part in T_CHECK request and just validation + * value part in T_CHECK request and just validation * done elsewhere should be enough, we just return here. */ if (inlen == 0) { @@ -1032,6 +1034,16 @@ tcp_opt_set(conn_t *connp, uint_t optset_context, int level, int name, return (EINVAL); } break; + case IP_RECVTOS: + if (!checkonly) { + /* + * Force it to be sent up with the next msg + * by setting it to a value which cannot + * appear in a packet (TOS is only 8-bits) + */ + tcp->tcp_recvtos = 0xffffffffU; + } + break; } break; case IPPROTO_IPV6: diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index 279611fe07..5f0c72cc3d 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -22,6 +22,7 @@ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -2347,8 +2348,8 @@ udp_input(void *arg1, mblk_t *mp, void *arg2, ip_recv_attr_t *ira) *(uint32_t *)&sin->sin_zero[4] = 0; /* - * Add options if IP_RECVDSTADDR, IP_RECVIF, IP_RECVSLLA or - * IP_RECVTTL has been set. + * Add options if IP_RECVDSTADDR, IP_RECVIF, IP_RECVSLLA, + * IP_RECVTTL or IP_RECVTOS has been set. */ if (udi_size != 0) { conn_recvancillary_add(connp, recv_ancillary, ira, diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c index c279bb4a21..a36b013c87 100644 --- a/usr/src/uts/common/inet/udp/udp_opt_data.c +++ b/usr/src/uts/common/inet/udp/udp_opt_data.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/types.h> @@ -111,8 +112,8 @@ opdes_t udp_opt_arr[] = { }, { IP_RECVIF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, { IP_RECVSLLA, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, -{ IP_RECVTTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), - 0 }, +{ IP_RECVTTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, +{ IP_RECVTOS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, { IP_MULTICAST_IF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (struct in_addr), 0 /* INADDR_ANY */ }, diff --git a/usr/src/uts/common/netinet/in.h b/usr/src/uts/common/netinet/in.h index 9ac3066362..019333b1bf 100644 --- a/usr/src/uts/common/netinet/in.h +++ b/usr/src/uts/common/netinet/in.h @@ -3,6 +3,7 @@ * Use is subject to license terms. * * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* * Copyright (c) 1982, 1986 Regents of the University of California. @@ -381,7 +382,7 @@ struct in_addr { /* Well known 6to4 Relay Router Anycast address defined in RFC 3068 */ #if !defined(_XPG4_2) || !defined(__EXTENSIONS__) -#define INADDR_6TO4RRANYCAST 0xc0586301U /* 192.88.99.1 */ +#define INADDR_6TO4RRANYCAST 0xc0586301U /* 192.88.99.1 */ #endif /* !defined(_XPG4_2) || !defined(__EXTENSIONS__) */ #define IN_LOOPBACKNET 127 /* official! */ @@ -466,7 +467,7 @@ struct sockaddr_in6 { #define IN6ADDR_ANY_INIT { 0, 0, 0, 0, \ 0, 0, 0, 0, \ - 0, 0, 0, 0, \ + 0, 0, 0, 0, \ 0, 0, 0, 0 } #define IN6ADDR_LOOPBACK_INIT { 0, 0, 0, 0, \ @@ -905,6 +906,7 @@ struct sockaddr_in6 { #define IP_RECVIF 0x9 /* int; receive the inbound interface index */ #define IP_RECVSLLA 0xa /* sockaddr_dl; get source link layer address */ #define IP_RECVTTL 0xb /* uint8_t; get TTL for inbound packet */ +#define IP_RECVTOS 0xc /* uint8_t; get TOS for inbound packet */ #define IP_MULTICAST_IF 0x10 /* set/get IP multicast interface */ #define IP_MULTICAST_TTL 0x11 /* set/get IP multicast timetolive */ @@ -939,8 +941,8 @@ struct sockaddr_in6 { */ typedef struct ipsec_req { - uint_t ipsr_ah_req; /* AH request */ - uint_t ipsr_esp_req; /* ESP request */ + uint_t ipsr_ah_req; /* AH request */ + uint_t ipsr_esp_req; /* ESP request */ uint_t ipsr_self_encap_req; /* Self-Encap request */ uint8_t ipsr_auth_alg; /* Auth algs for AH */ uint8_t ipsr_esp_alg; /* Encr algs for ESP */ @@ -1246,7 +1248,7 @@ typedef struct { #define IPV6_RECVRTHDRDSTOPTS 0x17 #define IPV6_CHECKSUM 0x18 /* Control checksum on raw sockets */ -#define IPV6_RECVTCLASS 0x19 /* enable/disable IPV6_CLASS */ +#define IPV6_RECVTCLASS 0x19 /* enable/disable IPV6_TCLASS */ #define IPV6_USE_MIN_MTU 0x20 /* send packets with minimum MTU */ #define IPV6_DONTFRAG 0x21 /* don't fragment packets */ #define IPV6_SEC_OPT 0x22 /* Used to set IPSEC options */ |