1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #define _SUN_TPI_VERSION 2
  30 #include <sys/tihdr.h>
  31 #include <sys/socket.h>
  32 #include <sys/xti_xtiopt.h>
  33 #include <sys/xti_inet.h>
  34 
  35 #include <inet/common.h>
  36 #include <netinet/ip6.h>
  37 #include <inet/ip.h>
  38 #include <inet/udp_impl.h>
  39 /*
  40  * MK_XXX Following 2 includes temporary to import ip6_rthdr_t
  41  *        definition. May not be needed if we fix ip6_dg_snd_attrs_t
  42  *        to do all extension headers in identical manner.
  43  */
  44 #include <net/if.h>
  45 #include <inet/ip6.h>
  46 
  47 #include <netinet/in.h>
  48 #include <netinet/udp.h>
  49 #include <inet/optcom.h>
  50 
  51 /*
  52  * Table of all known options handled on a UDP protocol stack.
  53  *
  54  * Note: This table contains options processed by both UDP and IP levels
  55  *       and is the superset of options that can be performed on a UDP over IP
  56  *       stack.
  57  */
  58 opdes_t udp_opt_arr[] = {
  59 
  60 { SO_DEBUG,     SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  61 { SO_DONTROUTE, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  62 { SO_USELOOPBACK, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
  63         },
  64 { SO_BROADCAST, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  65 { SO_REUSEADDR, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  66 { SO_TYPE,      SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
  67 { SO_SNDBUF,    SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  68 { SO_RCVBUF,    SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  69 { SO_SNDTIMEO,  SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0,
  70         sizeof (struct timeval), 0 },
  71 { SO_RCVTIMEO,  SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0,
  72         sizeof (struct timeval), 0 },
  73 { SO_DGRAM_ERRIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
  74         0 },
  75 { SO_RECVUCRED, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
  76         },
  77 { SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, 0, sizeof (int),
  78         0 },
  79 { SO_VRRP, SOL_SOCKET, OA_RW, OA_RW, OP_CONFIG, 0, sizeof (int), 0 },
  80 { SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
  81         },
  82 { SO_ANON_MLP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
  83     0 },
  84 { SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
  85     0 },
  86 { SO_MAC_IMPLICIT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
  87     0 },
  88 /*
  89  * The maximum size reported here depends on the maximum value for
  90  * ucredsize; unfortunately, we can't add ucredsize here so we need
  91  * to estimate here.  Before it was 512 or 384 + NGROUPS_UMAX * sizeof (gid_t);
  92  * as we're changing NGROUPS_UMAX we now codify this here using NGROUPS_UMAX.
  93  */
  94 { SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT,
  95     384 + NGROUPS_UMAX * sizeof (gid_t), 0 },
  96 { SO_EXCLBIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  97 { SO_DOMAIN,    SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
  98 { SO_PROTOTYPE, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
  99 
 100 { IP_OPTIONS,   IPPROTO_IP, OA_RW, OA_RW, OP_NP,
 101         (OP_VARLEN|OP_NODEFAULT),
 102         IP_MAX_OPT_LENGTH + IP_ADDR_LEN, -1 /* not initialized */ },
 103 { T_IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
 104         (OP_VARLEN|OP_NODEFAULT),
 105         IP_MAX_OPT_LENGTH + IP_ADDR_LEN, -1 /* not initialized */ },
 106 
 107 { IP_TOS,       IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 108 { T_IP_TOS,     IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 109 { IP_TTL,       IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 110 { IP_RECVOPTS,  IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 111 { IP_RECVDSTADDR, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
 112         },
 113 { IP_RECVIF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 114 { IP_RECVSLLA, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 115 { IP_RECVTTL,   IPPROTO_IP,  OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 116 { IP_RECVTOS,   IPPROTO_IP,  OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 117 { IP_MULTICAST_IF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0,
 118         sizeof (struct in_addr),        0 /* INADDR_ANY */ },
 119 
 120 { IP_MULTICAST_LOOP, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
 121         sizeof (uchar_t), -1 /* not initialized */},
 122 
 123 { IP_MULTICAST_TTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
 124         sizeof (uchar_t), -1 /* not initialized */ },
 125 
 126 { IP_ADD_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
 127         sizeof (struct ip_mreq), -1 /* not initialized */ },
 128 
 129 { IP_DROP_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
 130         sizeof (struct ip_mreq), -1 /* not initialized */ },
 131 
 132 { IP_BLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
 133         sizeof (struct ip_mreq_source), -1 /* not initialized */ },
 134 
 135 { IP_UNBLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
 136         sizeof (struct ip_mreq_source), -1 /* not initialized */ },
 137 
 138 { IP_ADD_SOURCE_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 139         OP_NODEFAULT, sizeof (struct ip_mreq_source), -1 },
 140 
 141 { IP_DROP_SOURCE_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 142         OP_NODEFAULT, sizeof (struct ip_mreq_source), -1 },
 143 
 144 { IP_SEC_OPT, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_NODEFAULT,
 145         sizeof (ipsec_req_t), -1 /* not initialized */ },
 146 
 147 { IP_BOUND_IF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0,
 148         sizeof (int),   0 /* no ifindex */ },
 149 
 150 { IP_DHCPINIT_IF, IPPROTO_IP, OA_R, OA_RW, OP_CONFIG, 0,
 151         sizeof (int), 0 },
 152 
 153 { IP_UNSPEC_SRC, IPPROTO_IP, OA_R, OA_RW, OP_RAW, 0,
 154         sizeof (int), 0 },
 155 
 156 { IP_BROADCAST_TTL, IPPROTO_IP, OA_R, OA_RW, OP_RAW, 0, sizeof (uchar_t),
 157         0 /* disabled */ },
 158 
 159 { IP_PKTINFO, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
 160         (OP_NODEFAULT|OP_VARLEN),
 161         sizeof (struct in_pktinfo), -1 /* not initialized */ },
 162 { IP_NEXTHOP, IPPROTO_IP, OA_R, OA_RW, OP_CONFIG, 0,
 163         sizeof (in_addr_t),     -1 /* not initialized  */ },
 164 
 165 { IP_DONTFRAG, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
 166 
 167 { MCAST_JOIN_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 168         OP_NODEFAULT, sizeof (struct group_req),
 169         -1 /* not initialized */ },
 170 { MCAST_LEAVE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 171         OP_NODEFAULT, sizeof (struct group_req),
 172         -1 /* not initialized */ },
 173 { MCAST_BLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP,
 174         OP_NODEFAULT, sizeof (struct group_source_req),
 175         -1 /* not initialized */ },
 176 { MCAST_UNBLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP,
 177         OP_NODEFAULT, sizeof (struct group_source_req),
 178         -1 /* not initialized */ },
 179 { MCAST_JOIN_SOURCE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 180         OP_NODEFAULT, sizeof (struct group_source_req),
 181         -1 /* not initialized */ },
 182 { MCAST_LEAVE_SOURCE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
 183         OP_NODEFAULT, sizeof (struct group_source_req),
 184         -1 /* not initialized */ },
 185 
 186 { IPV6_MULTICAST_IF, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 187         sizeof (int), 0 },
 188 
 189 { IPV6_MULTICAST_HOPS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 190         OP_DEF_FN, sizeof (int), -1 /* not initialized */ },
 191 
 192 { IPV6_MULTICAST_LOOP, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 193         OP_DEF_FN, sizeof (int), -1 /* not initialized */},
 194 
 195 { IPV6_JOIN_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP, OP_NODEFAULT,
 196         sizeof (struct ipv6_mreq), -1 /* not initialized */ },
 197 
 198 { IPV6_LEAVE_GROUP,     IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 199         OP_NODEFAULT,
 200         sizeof (struct ipv6_mreq), -1 /* not initialized */ },
 201 
 202 { IPV6_UNICAST_HOPS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
 203         sizeof (int), -1 /* not initialized */ },
 204 
 205 { IPV6_BOUND_IF, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 206         sizeof (int),   0 /* no ifindex */ },
 207 
 208 { IPV6_UNSPEC_SRC, IPPROTO_IPV6, OA_R, OA_RW, OP_RAW, 0,
 209         sizeof (int), 0 },
 210 
 211 { IPV6_PKTINFO, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 212         (OP_NODEFAULT|OP_VARLEN),
 213         sizeof (struct in6_pktinfo), -1 /* not initialized */ },
 214 { IPV6_HOPLIMIT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 215         OP_NODEFAULT,
 216         sizeof (int), -1 /* not initialized */ },
 217 { IPV6_NEXTHOP, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 218         (OP_NODEFAULT|OP_VARLEN),
 219         sizeof (sin6_t), -1 /* not initialized */ },
 220 { IPV6_HOPOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 221         (OP_VARLEN|OP_NODEFAULT),
 222         MAX_EHDR_LEN, -1 /* not initialized */ },
 223 { IPV6_DSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 224         (OP_VARLEN|OP_NODEFAULT),
 225         MAX_EHDR_LEN, -1 /* not initialized */ },
 226 { IPV6_RTHDRDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 227         (OP_VARLEN|OP_NODEFAULT),
 228         MAX_EHDR_LEN, -1 /* not initialized */ },
 229 { IPV6_RTHDR, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 230         (OP_VARLEN|OP_NODEFAULT),
 231         MAX_EHDR_LEN, -1 /* not initialized */ },
 232 { IPV6_TCLASS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 233         OP_NODEFAULT,
 234         sizeof (int), -1 /* not initialized */ },
 235 { IPV6_PATHMTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 236         OP_NODEFAULT,
 237         sizeof (struct ip6_mtuinfo), -1 },
 238 { IPV6_DONTFRAG, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 239         sizeof (int), 0 },
 240 { IPV6_USE_MIN_MTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 241         sizeof (int), 0 },
 242 { IPV6_V6ONLY, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 243         sizeof (int), 0 },
 244 
 245 { IPV6_RECVPKTINFO, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 246         sizeof (int), 0 },
 247 { IPV6_RECVHOPLIMIT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 248         sizeof (int), 0 },
 249 { IPV6_RECVHOPOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 250         sizeof (int), 0 },
 251 { _OLD_IPV6_RECVDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 252         sizeof (int), 0 },
 253 { IPV6_RECVDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 254         sizeof (int), 0 },
 255 { IPV6_RECVRTHDR, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 256         sizeof (int), 0 },
 257 { IPV6_RECVRTHDRDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 258         sizeof (int), 0 },
 259 { IPV6_RECVPATHMTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
 260         0, sizeof (int), 0 },
 261 { IPV6_RECVTCLASS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 262         sizeof (int), 0 },
 263 
 264 { IPV6_SEC_OPT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, OP_NODEFAULT,
 265         sizeof (ipsec_req_t), -1 /* not initialized */ },
 266 { IPV6_SRC_PREFERENCES, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
 267         sizeof (uint32_t), IPV6_PREFER_SRC_DEFAULT },
 268 
 269 { MCAST_JOIN_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 270         OP_NODEFAULT, sizeof (struct group_req),
 271         -1 /* not initialized */ },
 272 { MCAST_LEAVE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 273         OP_NODEFAULT, sizeof (struct group_req),
 274         -1 /* not initialized */ },
 275 { MCAST_BLOCK_SOURCE, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 276         OP_NODEFAULT, sizeof (struct group_source_req),
 277         -1 /* not initialized */ },
 278 { MCAST_UNBLOCK_SOURCE, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 279         OP_NODEFAULT, sizeof (struct group_source_req),
 280         -1 /* not initialized */ },
 281 { MCAST_JOIN_SOURCE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 282         OP_NODEFAULT, sizeof (struct group_source_req),
 283         -1 /* not initialized */ },
 284 { MCAST_LEAVE_SOURCE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
 285         OP_NODEFAULT, sizeof (struct group_source_req),
 286         -1 /* not initialized */ },
 287 
 288 { UDP_ANONPRIVBIND, IPPROTO_UDP, OA_R, OA_RW, OP_PRIVPORT, 0,
 289         sizeof (int), 0 },
 290 { UDP_EXCLBIND, IPPROTO_UDP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
 291         },
 292 { UDP_RCVHDR, IPPROTO_UDP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
 293         },
 294 { UDP_NAT_T_ENDPOINT, IPPROTO_UDP, OA_RW, OA_RW, OP_PRIVPORT, 0, sizeof (int),
 295         0 },
 296 };
 297 
 298 /*
 299  * Table of all supported levels
 300  * Note: Some levels (e.g. XTI_GENERIC) may be valid but may not have
 301  * any supported options so we need this info separately.
 302  *
 303  * This is needed only for topmost tpi providers and is used only by
 304  * XTI interfaces.
 305  */
 306 optlevel_t      udp_valid_levels_arr[] = {
 307         XTI_GENERIC,
 308         SOL_SOCKET,
 309         IPPROTO_UDP,
 310         IPPROTO_IP,
 311         IPPROTO_IPV6
 312 };
 313 
 314 #define UDP_VALID_LEVELS_CNT    A_CNT(udp_valid_levels_arr)
 315 #define UDP_OPT_ARR_CNT         A_CNT(udp_opt_arr)
 316 
 317 uint_t udp_max_optsize; /* initialized when UDP driver is loaded */
 318 
 319 /*
 320  * Initialize option database object for UDP
 321  *
 322  * This object represents database of options to search passed to
 323  * {sock,tpi}optcom_req() interface routine to take care of option
 324  * management and associated methods.
 325  */
 326 
 327 optdb_obj_t udp_opt_obj = {
 328         udp_opt_default,        /* UDP default value function pointer */
 329         udp_tpi_opt_get,        /* UDP get function pointer */
 330         udp_tpi_opt_set,        /* UDP set function pointer */
 331         UDP_OPT_ARR_CNT,        /* UDP option database count of entries */
 332         udp_opt_arr,            /* UDP option database */
 333         UDP_VALID_LEVELS_CNT,   /* UDP valid level count of entries */
 334         udp_valid_levels_arr    /* UDP valid level array */
 335 };