summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/fs/sockfs/socksubr.c20
-rw-r--r--usr/src/uts/common/inet/ip/conn_opt.c55
-rw-r--r--usr/src/uts/common/inet/ip/ip.c2
-rw-r--r--usr/src/uts/common/inet/ip_stack.h2
-rw-r--r--usr/src/uts/common/inet/ipclassifier.h4
-rw-r--r--usr/src/uts/common/inet/tcp.h2
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_input.c30
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_opt_data.c16
-rw-r--r--usr/src/uts/common/inet/udp/udp.c5
-rw-r--r--usr/src/uts/common/inet/udp/udp_opt_data.c5
-rw-r--r--usr/src/uts/common/netinet/in.h12
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 */