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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * IP PACKET CLASSIFIER
  27  *
  28  * The IP packet classifier provides mapping between IP packets and persistent
  29  * connection state for connection-oriented protocols. It also provides
  30  * interface for managing connection states.
  31  *
  32  * The connection state is kept in conn_t data structure and contains, among
  33  * other things:
  34  *
  35  *      o local/remote address and ports
  36  *      o Transport protocol
  37  *      o squeue for the connection (for TCP only)
  38  *      o reference counter
  39  *      o Connection state
  40  *      o hash table linkage
  41  *      o interface/ire information
  42  *      o credentials
 
 
 851         ASSERT((connp)->conn_next == NULL);                          \
 852         ASSERT((connp)->conn_prev == NULL);                          \
 853         if ((connfp)->connf_head != NULL) {                          \
 854                 (connfp)->connf_head->conn_prev = (connp);                \
 855                 (connp)->conn_next = (connfp)->connf_head;                \
 856         }                                                               \
 857         (connp)->conn_fanout = (connfp);                             \
 858         (connfp)->connf_head = (connp);                                      \
 859         (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \
 860             IPCL_CONNECTED;                                             \
 861         CONN_INC_REF(connp);                                            \
 862 }
 863 
 864 #define IPCL_HASH_INSERT_CONNECTED(connfp, connp) {                     \
 865         IPCL_HASH_REMOVE((connp));                                      \
 866         mutex_enter(&(connfp)->connf_lock);                              \
 867         IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);               \
 868         mutex_exit(&(connfp)->connf_lock);                               \
 869 }
 870 
 871 #define IPCL_HASH_INSERT_BOUND(connfp, connp) {                         \
 872         conn_t *pconnp = NULL, *nconnp;                                 \
 873         IPCL_HASH_REMOVE((connp));                                      \
 874         mutex_enter(&(connfp)->connf_lock);                              \
 875         nconnp = (connfp)->connf_head;                                       \
 876         while (nconnp != NULL &&                                        \
 877             !_IPCL_V4_MATCH_ANY(nconnp->conn_laddr_v6)) {            \
 878                 pconnp = nconnp;                                        \
 879                 nconnp = nconnp->conn_next;                          \
 880         }                                                               \
 881         if (pconnp != NULL) {                                           \
 882                 pconnp->conn_next = (connp);                         \
 883                 (connp)->conn_prev = pconnp;                         \
 884         } else {                                                        \
 885                 (connfp)->connf_head = (connp);                              \
 886         }                                                               \
 887         if (nconnp != NULL) {                                           \
 888                 (connp)->conn_next = nconnp;                         \
 889                 nconnp->conn_prev = (connp);                         \
 890         }                                                               \
 891         (connp)->conn_fanout = (connfp);                             \
 892         (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \
 893             IPCL_BOUND;                                                 \
 894         CONN_INC_REF(connp);                                            \
 895         mutex_exit(&(connfp)->connf_lock);                               \
 896 }
 897 
 898 #define IPCL_HASH_INSERT_WILDCARD(connfp, connp) {                      \
 899         conn_t **list, *prev, *next;                                    \
 900         boolean_t isv4mapped =                                          \
 901             IN6_IS_ADDR_V4MAPPED(&(connp)->conn_laddr_v6);               \
 902         IPCL_HASH_REMOVE((connp));                                      \
 903         mutex_enter(&(connfp)->connf_lock);                              \
 904         list = &(connfp)->connf_head;                                    \
 905         prev = NULL;                                                    \
 906         while ((next = *list) != NULL) {                                \
 907                 if (isv4mapped &&                                       \
 908                     IN6_IS_ADDR_UNSPECIFIED(&next->conn_laddr_v6) &&     \
 909                     connp->conn_zoneid == next->conn_zoneid) {            \
 910                         (connp)->conn_next = next;                   \
 911                         if (prev != NULL)                               \
 912                                 prev = next->conn_prev;                      \
 913                         next->conn_prev = (connp);                   \
 914                         break;                                          \
 915                 }                                                       \
 916                 list = &next->conn_next;                         \
 917                 prev = next;                                            \
 918         }                                                               \
 919         (connp)->conn_prev = prev;                                   \
 920         *list = (connp);                                                \
 921         (connp)->conn_fanout = (connfp);                             \
 922         (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \
 923             IPCL_BOUND;                                                 \
 924         CONN_INC_REF((connp));                                          \
 925         mutex_exit(&(connfp)->connf_lock);                               \
 926 }
 927 
 928 void
 929 ipcl_hash_insert_wildcard(connf_t *connfp, conn_t *connp)
 930 {
 931         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
 932 }
 933 
 934 /*
 935  * Because the classifier is used to classify inbound packets, the destination
 936  * address is meant to be our local tunnel address (tunnel source), and the
 937  * source the remote tunnel address (tunnel destination).
 938  *
 939  * Note that conn_proto can't be used for fanout since the upper protocol
 940  * can be both 41 and 4 when IPv6 and IPv4 are over the same tunnel.
 941  */
 942 conn_t *
 943 ipcl_iptun_classify_v4(ipaddr_t *src, ipaddr_t *dst, ip_stack_t *ipst)
 944 {
 945         connf_t *connfp;
 946         conn_t  *connp;
 947 
 948         /* first look for IPv4 tunnel links */
 949         connfp = &ipst->ips_ipcl_iptun_fanout[IPCL_IPTUN_HASH(*dst, *src)];
 950         mutex_enter(&connfp->connf_lock);
 951         for (connp = connfp->connf_head; connp != NULL;
 
1017                 if (oconnp->conn_lport == lport &&
1018                     oconnp->conn_zoneid == connp->conn_zoneid &&
1019                     oconnp->conn_family == connp->conn_family &&
1020                     ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
1021                     IN6_IS_ADDR_UNSPECIFIED(&oconnp->conn_laddr_v6) ||
1022                     IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6) ||
1023                     IN6_IS_ADDR_V4MAPPED_ANY(&oconnp->conn_laddr_v6)) ||
1024                     IN6_ARE_ADDR_EQUAL(&oconnp->conn_laddr_v6,
1025                     &connp->conn_laddr_v6))) {
1026                         break;
1027                 }
1028         }
1029         mutex_exit(&connfp->connf_lock);
1030         if (oconnp != NULL)
1031                 return (EADDRNOTAVAIL);
1032 
1033         if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
1034             IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_faddr_v6)) {
1035                 if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
1036                     IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6)) {
1037                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1038                 } else {
1039                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1040                 }
1041         } else {
1042                 IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1043         }
1044         return (0);
1045 }
1046 
1047 static int
1048 ipcl_iptun_hash_insert(conn_t *connp, ip_stack_t *ipst)
1049 {
1050         connf_t *connfp;
1051         conn_t  *tconnp;
1052         ipaddr_t laddr = connp->conn_laddr_v4;
1053         ipaddr_t faddr = connp->conn_faddr_v4;
1054 
1055         connfp = &ipst->ips_ipcl_iptun_fanout[IPCL_IPTUN_HASH(laddr, faddr)];
1056         mutex_enter(&connfp->connf_lock);
1057         for (tconnp = connfp->connf_head; tconnp != NULL;
1058             tconnp = tconnp->conn_next) {
1059                 if (IPCL_IPTUN_MATCH(tconnp, laddr, faddr)) {
 
1188         if (IPCL_IS_IPTUN(connp))
1189                 return (ipcl_iptun_hash_insert(connp, ipst));
1190 
1191         switch (protocol) {
1192         default:
1193                 if (is_system_labeled() &&
1194                     check_exempt_conflict_v4(connp, ipst))
1195                         return (EADDRINUSE);
1196                 /* FALLTHROUGH */
1197         case IPPROTO_UDP:
1198                 if (protocol == IPPROTO_UDP) {
1199                         connfp = &ipst->ips_ipcl_udp_fanout[
1200                             IPCL_UDP_HASH(lport, ipst)];
1201                 } else {
1202                         connfp = &ipst->ips_ipcl_proto_fanout_v4[protocol];
1203                 }
1204 
1205                 if (connp->conn_faddr_v4 != INADDR_ANY) {
1206                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1207                 } else if (connp->conn_laddr_v4 != INADDR_ANY) {
1208                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1209                 } else {
1210                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1211                 }
1212                 if (protocol == IPPROTO_RSVP)
1213                         ill_set_inputfn_all(ipst);
1214                 break;
1215 
1216         case IPPROTO_TCP:
1217                 /* Insert it in the Bind Hash */
1218                 ASSERT(connp->conn_zoneid != ALL_ZONES);
1219                 connfp = &ipst->ips_ipcl_bind_fanout[
1220                     IPCL_BIND_HASH(lport, ipst)];
1221                 if (connp->conn_laddr_v4 != INADDR_ANY) {
1222                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1223                 } else {
1224                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1225                 }
1226                 if (cl_inet_listen != NULL) {
1227                         ASSERT(connp->conn_ipversion == IPV4_VERSION);
1228                         connp->conn_flags |= IPCL_CL_LISTENER;
1229                         (*cl_inet_listen)(
1230                             connp->conn_netstack->netstack_stackid,
1231                             IPPROTO_TCP, AF_INET,
1232                             (uint8_t *)&connp->conn_bound_addr_v4, lport, NULL);
1233                 }
1234                 break;
1235 
1236         case IPPROTO_SCTP:
1237                 ret = ipcl_sctp_hash_insert(connp, lport);
1238                 break;
1239         }
1240 
1241         return (ret);
1242 }
1243 
1244 int
 
1254                 return (ipcl_iptun_hash_insert_v6(connp, ipst));
1255         }
1256 
1257         switch (protocol) {
1258         default:
1259                 if (is_system_labeled() &&
1260                     check_exempt_conflict_v6(connp, ipst))
1261                         return (EADDRINUSE);
1262                 /* FALLTHROUGH */
1263         case IPPROTO_UDP:
1264                 if (protocol == IPPROTO_UDP) {
1265                         connfp = &ipst->ips_ipcl_udp_fanout[
1266                             IPCL_UDP_HASH(lport, ipst)];
1267                 } else {
1268                         connfp = &ipst->ips_ipcl_proto_fanout_v6[protocol];
1269                 }
1270 
1271                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) {
1272                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1273                 } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1274                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1275                 } else {
1276                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1277                 }
1278                 break;
1279 
1280         case IPPROTO_TCP:
1281                 /* Insert it in the Bind Hash */
1282                 ASSERT(connp->conn_zoneid != ALL_ZONES);
1283                 connfp = &ipst->ips_ipcl_bind_fanout[
1284                     IPCL_BIND_HASH(lport, ipst)];
1285                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1286                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1287                 } else {
1288                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1289                 }
1290                 if (cl_inet_listen != NULL) {
1291                         sa_family_t     addr_family;
1292                         uint8_t         *laddrp;
1293 
1294                         if (connp->conn_ipversion == IPV6_VERSION) {
1295                                 addr_family = AF_INET6;
1296                                 laddrp =
1297                                     (uint8_t *)&connp->conn_bound_addr_v6;
1298                         } else {
1299                                 addr_family = AF_INET;
1300                                 laddrp = (uint8_t *)&connp->conn_bound_addr_v4;
1301                         }
1302                         connp->conn_flags |= IPCL_CL_LISTENER;
1303                         (*cl_inet_listen)(
1304                             connp->conn_netstack->netstack_stackid,
1305                             IPPROTO_TCP, addr_family, laddrp, lport, NULL);
1306                 }
1307                 break;
1308 
 
1399                  * transports with port numbers, this is done by the upper
1400                  * level per-transport binding logic.  For all others, it's
1401                  * done here.
1402                  */
1403                 if (is_system_labeled() &&
1404                     check_exempt_conflict_v4(connp, ipst))
1405                         return (EADDRINUSE);
1406                 /* FALLTHROUGH */
1407 
1408         case IPPROTO_UDP:
1409                 if (protocol == IPPROTO_UDP) {
1410                         connfp = &ipst->ips_ipcl_udp_fanout[
1411                             IPCL_UDP_HASH(lport, ipst)];
1412                 } else {
1413                         connfp = &ipst->ips_ipcl_proto_fanout_v4[protocol];
1414                 }
1415 
1416                 if (connp->conn_faddr_v4 != INADDR_ANY) {
1417                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1418                 } else if (connp->conn_laddr_v4 != INADDR_ANY) {
1419                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1420                 } else {
1421                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1422                 }
1423                 break;
1424         }
1425 
1426         return (ret);
1427 }
1428 
1429 int
1430 ipcl_conn_insert_v6(conn_t *connp)
1431 {
1432         connf_t         *connfp;
1433         conn_t          *tconnp;
1434         int             ret = 0;
1435         ip_stack_t      *ipst = connp->conn_netstack->netstack_ip;
1436         uint16_t        lport = connp->conn_lport;
1437         uint8_t         protocol = connp->conn_proto;
1438         uint_t          ifindex = connp->conn_bound_if;
1439 
1440         if (IPCL_IS_IPTUN(connp))
1441                 return (ipcl_iptun_hash_insert_v6(connp, ipst));
 
1487                 IPCL_HASH_REMOVE(connp);
1488                 ret = ipcl_sctp_hash_insert(connp, lport);
1489                 break;
1490 
1491         default:
1492                 if (is_system_labeled() &&
1493                     check_exempt_conflict_v6(connp, ipst))
1494                         return (EADDRINUSE);
1495                 /* FALLTHROUGH */
1496         case IPPROTO_UDP:
1497                 if (protocol == IPPROTO_UDP) {
1498                         connfp = &ipst->ips_ipcl_udp_fanout[
1499                             IPCL_UDP_HASH(lport, ipst)];
1500                 } else {
1501                         connfp = &ipst->ips_ipcl_proto_fanout_v6[protocol];
1502                 }
1503 
1504                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) {
1505                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1506                 } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1507                         IPCL_HASH_INSERT_BOUND(connfp, connp);
1508                 } else {
1509                         IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1510                 }
1511                 break;
1512         }
1513 
1514         return (ret);
1515 }
1516 
1517 /*
1518  * v4 packet classifying function. looks up the fanout table to
1519  * find the conn, the packet belongs to. returns the conn with
1520  * the reference held, null otherwise.
1521  *
1522  * If zoneid is ALL_ZONES, then the search rules described in the "Connection
1523  * Lookup" comment block are applied.  Labels are also checked as described
1524  * above.  If the packet is from the inside (looped back), and is from the same
1525  * zone, then label checks are omitted.
1526  */
1527 conn_t *
1528 ipcl_classify_v4(mblk_t *mp, uint8_t protocol, uint_t hdr_len,
1529     ip_recv_attr_t *ira, ip_stack_t *ipst)
 
2075         }
2076 }
2077 
2078 /* ARGSUSED */
2079 static int
2080 rawip_conn_constructor(void *buf, void *cdrarg, int kmflags)
2081 {
2082         itc_t   *itc = (itc_t *)buf;
2083         conn_t  *connp = &itc->itc_conn;
2084         icmp_t  *icmp = (icmp_t *)&itc[1];
2085 
2086         bzero(connp, sizeof (conn_t));
2087         bzero(icmp, sizeof (icmp_t));
2088 
2089         mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL);
2090         cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL);
2091         connp->conn_icmp = icmp;
2092         connp->conn_flags = IPCL_RAWIPCONN;
2093         connp->conn_proto = IPPROTO_ICMP;
2094         icmp->icmp_connp = connp;
2095         rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL);
2096         connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags);
2097         if (connp->conn_ixa == NULL)
2098                 return (ENOMEM);
2099         connp->conn_ixa->ixa_refcnt = 1;
2100         connp->conn_ixa->ixa_protocol = connp->conn_proto;
2101         connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp);
2102         return (0);
2103 }
2104 
2105 /* ARGSUSED */
2106 static void
2107 rawip_conn_destructor(void *buf, void *cdrarg)
2108 {
2109         itc_t   *itc = (itc_t *)buf;
2110         conn_t  *connp = &itc->itc_conn;
2111         icmp_t  *icmp = (icmp_t *)&itc[1];
2112 
2113         ASSERT(connp->conn_flags & IPCL_RAWIPCONN);
2114         ASSERT(icmp->icmp_connp == connp);
2115         ASSERT(connp->conn_icmp == icmp);
2116         mutex_destroy(&connp->conn_lock);
2117         cv_destroy(&connp->conn_cv);
2118         rw_destroy(&connp->conn_ilg_lock);
2119 
2120         /* Can be NULL if constructor failed */
2121         if (connp->conn_ixa != NULL) {
2122                 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2123                 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2124                 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2125                 ixa_refrele(connp->conn_ixa);
2126         }
2127 }
2128 
2129 /* ARGSUSED */
2130 static int
2131 rts_conn_constructor(void *buf, void *cdrarg, int kmflags)
2132 {
2133         itc_t   *itc = (itc_t *)buf;
2134         conn_t  *connp = &itc->itc_conn;
2135         rts_t   *rts = (rts_t *)&itc[1];
2136 
2137         bzero(connp, sizeof (conn_t));
2138         bzero(rts, sizeof (rts_t));
 
 | 
 
 
   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2016 Joyent, Inc.
  24  */
  25 
  26 /*
  27  * IP PACKET CLASSIFIER
  28  *
  29  * The IP packet classifier provides mapping between IP packets and persistent
  30  * connection state for connection-oriented protocols. It also provides
  31  * interface for managing connection states.
  32  *
  33  * The connection state is kept in conn_t data structure and contains, among
  34  * other things:
  35  *
  36  *      o local/remote address and ports
  37  *      o Transport protocol
  38  *      o squeue for the connection (for TCP only)
  39  *      o reference counter
  40  *      o Connection state
  41  *      o hash table linkage
  42  *      o interface/ire information
  43  *      o credentials
 
 
 852         ASSERT((connp)->conn_next == NULL);                          \
 853         ASSERT((connp)->conn_prev == NULL);                          \
 854         if ((connfp)->connf_head != NULL) {                          \
 855                 (connfp)->connf_head->conn_prev = (connp);                \
 856                 (connp)->conn_next = (connfp)->connf_head;                \
 857         }                                                               \
 858         (connp)->conn_fanout = (connfp);                             \
 859         (connfp)->connf_head = (connp);                                      \
 860         (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \
 861             IPCL_CONNECTED;                                             \
 862         CONN_INC_REF(connp);                                            \
 863 }
 864 
 865 #define IPCL_HASH_INSERT_CONNECTED(connfp, connp) {                     \
 866         IPCL_HASH_REMOVE((connp));                                      \
 867         mutex_enter(&(connfp)->connf_lock);                              \
 868         IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);               \
 869         mutex_exit(&(connfp)->connf_lock);                               \
 870 }
 871 
 872 /*
 873  * When inserting bound or wildcard entries into the hash, ordering rules are
 874  * used to facilitate timely and correct lookups.  The order is as follows:
 875  * 1. Entries bound to a specific address
 876  * 2. Entries bound to INADDR_ANY
 877  * 3. Entries bound to ADDR_UNSPECIFIED
 878  * Entries in a category which share conn_lport (such as those using
 879  * SO_REUSEPORT) will be ordered such that the newest inserted is first.
 880  */
 881 
 882 void
 883 ipcl_hash_insert_bound(connf_t *connfp, conn_t *connp)
 884 {
 885         conn_t *pconnp, *nconnp;
 886 
 887         IPCL_HASH_REMOVE(connp);
 888         mutex_enter(&connfp->connf_lock);
 889         nconnp = connfp->connf_head;
 890         pconnp = NULL;
 891         while (nconnp != NULL) {
 892                 /*
 893                  * Walk though entries associated with the fanout until one is
 894                  * found which fulfills any of these conditions:
 895                  * 1. Listen address of ADDR_ANY/ADDR_UNSPECIFIED
 896                  * 2. Listen port the same as connp
 897                  */
 898                 if (_IPCL_V4_MATCH_ANY(nconnp->conn_laddr_v6) ||
 899                     connp->conn_lport == nconnp->conn_lport)
 900                         break;
 901                 pconnp = nconnp;
 902                 nconnp = nconnp->conn_next;
 903         }
 904         if (pconnp != NULL) {
 905                 pconnp->conn_next = connp;
 906                 connp->conn_prev = pconnp;
 907         } else {
 908                 connfp->connf_head = connp;
 909         }
 910         if (nconnp != NULL) {
 911                 connp->conn_next = nconnp;
 912                 nconnp->conn_prev = connp;
 913         }
 914         connp->conn_fanout = connfp;
 915         connp->conn_flags = (connp->conn_flags & ~IPCL_REMOVED) | IPCL_BOUND;
 916         CONN_INC_REF(connp);
 917         mutex_exit(&connfp->connf_lock);
 918 }
 919 
 920 void
 921 ipcl_hash_insert_wildcard(connf_t *connfp, conn_t *connp)
 922 {
 923         conn_t *pconnp = NULL, *nconnp;
 924         boolean_t isv4mapped = IN6_IS_ADDR_V4MAPPED(&connp->conn_laddr_v6);
 925 
 926         IPCL_HASH_REMOVE(connp);
 927         mutex_enter(&connfp->connf_lock);
 928         nconnp = connfp->connf_head;
 929         pconnp = NULL;
 930         while (nconnp != NULL) {
 931                 if (IN6_IS_ADDR_V4MAPPED_ANY(&nconnp->conn_laddr_v6) &&
 932                     isv4mapped && connp->conn_lport == nconnp->conn_lport)
 933                         break;
 934                 if (IN6_IS_ADDR_UNSPECIFIED(&nconnp->conn_laddr_v6) &&
 935                     (isv4mapped ||
 936                     connp->conn_lport == nconnp->conn_lport))
 937                         break;
 938 
 939                 pconnp = nconnp;
 940                 nconnp = nconnp->conn_next;
 941         }
 942         if (pconnp != NULL) {
 943                 pconnp->conn_next = connp;
 944                 connp->conn_prev = pconnp;
 945         } else {
 946                 connfp->connf_head = connp;
 947         }
 948         if (nconnp != NULL) {
 949                 connp->conn_next = nconnp;
 950                 nconnp->conn_prev = connp;
 951         }
 952         connp->conn_fanout = connfp;
 953         connp->conn_flags = (connp->conn_flags & ~IPCL_REMOVED) | IPCL_BOUND;
 954         CONN_INC_REF(connp);
 955         mutex_exit(&connfp->connf_lock);
 956 }
 957 
 958 /*
 959  * Because the classifier is used to classify inbound packets, the destination
 960  * address is meant to be our local tunnel address (tunnel source), and the
 961  * source the remote tunnel address (tunnel destination).
 962  *
 963  * Note that conn_proto can't be used for fanout since the upper protocol
 964  * can be both 41 and 4 when IPv6 and IPv4 are over the same tunnel.
 965  */
 966 conn_t *
 967 ipcl_iptun_classify_v4(ipaddr_t *src, ipaddr_t *dst, ip_stack_t *ipst)
 968 {
 969         connf_t *connfp;
 970         conn_t  *connp;
 971 
 972         /* first look for IPv4 tunnel links */
 973         connfp = &ipst->ips_ipcl_iptun_fanout[IPCL_IPTUN_HASH(*dst, *src)];
 974         mutex_enter(&connfp->connf_lock);
 975         for (connp = connfp->connf_head; connp != NULL;
 
1041                 if (oconnp->conn_lport == lport &&
1042                     oconnp->conn_zoneid == connp->conn_zoneid &&
1043                     oconnp->conn_family == connp->conn_family &&
1044                     ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
1045                     IN6_IS_ADDR_UNSPECIFIED(&oconnp->conn_laddr_v6) ||
1046                     IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6) ||
1047                     IN6_IS_ADDR_V4MAPPED_ANY(&oconnp->conn_laddr_v6)) ||
1048                     IN6_ARE_ADDR_EQUAL(&oconnp->conn_laddr_v6,
1049                     &connp->conn_laddr_v6))) {
1050                         break;
1051                 }
1052         }
1053         mutex_exit(&connfp->connf_lock);
1054         if (oconnp != NULL)
1055                 return (EADDRNOTAVAIL);
1056 
1057         if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
1058             IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_faddr_v6)) {
1059                 if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
1060                     IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6)) {
1061                         ipcl_hash_insert_wildcard(connfp, connp);
1062                 } else {
1063                         ipcl_hash_insert_bound(connfp, connp);
1064                 }
1065         } else {
1066                 IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1067         }
1068         return (0);
1069 }
1070 
1071 static int
1072 ipcl_iptun_hash_insert(conn_t *connp, ip_stack_t *ipst)
1073 {
1074         connf_t *connfp;
1075         conn_t  *tconnp;
1076         ipaddr_t laddr = connp->conn_laddr_v4;
1077         ipaddr_t faddr = connp->conn_faddr_v4;
1078 
1079         connfp = &ipst->ips_ipcl_iptun_fanout[IPCL_IPTUN_HASH(laddr, faddr)];
1080         mutex_enter(&connfp->connf_lock);
1081         for (tconnp = connfp->connf_head; tconnp != NULL;
1082             tconnp = tconnp->conn_next) {
1083                 if (IPCL_IPTUN_MATCH(tconnp, laddr, faddr)) {
 
1212         if (IPCL_IS_IPTUN(connp))
1213                 return (ipcl_iptun_hash_insert(connp, ipst));
1214 
1215         switch (protocol) {
1216         default:
1217                 if (is_system_labeled() &&
1218                     check_exempt_conflict_v4(connp, ipst))
1219                         return (EADDRINUSE);
1220                 /* FALLTHROUGH */
1221         case IPPROTO_UDP:
1222                 if (protocol == IPPROTO_UDP) {
1223                         connfp = &ipst->ips_ipcl_udp_fanout[
1224                             IPCL_UDP_HASH(lport, ipst)];
1225                 } else {
1226                         connfp = &ipst->ips_ipcl_proto_fanout_v4[protocol];
1227                 }
1228 
1229                 if (connp->conn_faddr_v4 != INADDR_ANY) {
1230                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1231                 } else if (connp->conn_laddr_v4 != INADDR_ANY) {
1232                         ipcl_hash_insert_bound(connfp, connp);
1233                 } else {
1234                         ipcl_hash_insert_wildcard(connfp, connp);
1235                 }
1236                 if (protocol == IPPROTO_RSVP)
1237                         ill_set_inputfn_all(ipst);
1238                 break;
1239 
1240         case IPPROTO_TCP:
1241                 /* Insert it in the Bind Hash */
1242                 ASSERT(connp->conn_zoneid != ALL_ZONES);
1243                 connfp = &ipst->ips_ipcl_bind_fanout[
1244                     IPCL_BIND_HASH(lport, ipst)];
1245                 if (connp->conn_laddr_v4 != INADDR_ANY) {
1246                         ipcl_hash_insert_bound(connfp, connp);
1247                 } else {
1248                         ipcl_hash_insert_wildcard(connfp, connp);
1249                 }
1250                 if (cl_inet_listen != NULL) {
1251                         ASSERT(connp->conn_ipversion == IPV4_VERSION);
1252                         connp->conn_flags |= IPCL_CL_LISTENER;
1253                         (*cl_inet_listen)(
1254                             connp->conn_netstack->netstack_stackid,
1255                             IPPROTO_TCP, AF_INET,
1256                             (uint8_t *)&connp->conn_bound_addr_v4, lport, NULL);
1257                 }
1258                 break;
1259 
1260         case IPPROTO_SCTP:
1261                 ret = ipcl_sctp_hash_insert(connp, lport);
1262                 break;
1263         }
1264 
1265         return (ret);
1266 }
1267 
1268 int
 
1278                 return (ipcl_iptun_hash_insert_v6(connp, ipst));
1279         }
1280 
1281         switch (protocol) {
1282         default:
1283                 if (is_system_labeled() &&
1284                     check_exempt_conflict_v6(connp, ipst))
1285                         return (EADDRINUSE);
1286                 /* FALLTHROUGH */
1287         case IPPROTO_UDP:
1288                 if (protocol == IPPROTO_UDP) {
1289                         connfp = &ipst->ips_ipcl_udp_fanout[
1290                             IPCL_UDP_HASH(lport, ipst)];
1291                 } else {
1292                         connfp = &ipst->ips_ipcl_proto_fanout_v6[protocol];
1293                 }
1294 
1295                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) {
1296                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1297                 } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1298                         ipcl_hash_insert_bound(connfp, connp);
1299                 } else {
1300                         ipcl_hash_insert_wildcard(connfp, connp);
1301                 }
1302                 break;
1303 
1304         case IPPROTO_TCP:
1305                 /* Insert it in the Bind Hash */
1306                 ASSERT(connp->conn_zoneid != ALL_ZONES);
1307                 connfp = &ipst->ips_ipcl_bind_fanout[
1308                     IPCL_BIND_HASH(lport, ipst)];
1309                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1310                         ipcl_hash_insert_bound(connfp, connp);
1311                 } else {
1312                         ipcl_hash_insert_wildcard(connfp, connp);
1313                 }
1314                 if (cl_inet_listen != NULL) {
1315                         sa_family_t     addr_family;
1316                         uint8_t         *laddrp;
1317 
1318                         if (connp->conn_ipversion == IPV6_VERSION) {
1319                                 addr_family = AF_INET6;
1320                                 laddrp =
1321                                     (uint8_t *)&connp->conn_bound_addr_v6;
1322                         } else {
1323                                 addr_family = AF_INET;
1324                                 laddrp = (uint8_t *)&connp->conn_bound_addr_v4;
1325                         }
1326                         connp->conn_flags |= IPCL_CL_LISTENER;
1327                         (*cl_inet_listen)(
1328                             connp->conn_netstack->netstack_stackid,
1329                             IPPROTO_TCP, addr_family, laddrp, lport, NULL);
1330                 }
1331                 break;
1332 
 
1423                  * transports with port numbers, this is done by the upper
1424                  * level per-transport binding logic.  For all others, it's
1425                  * done here.
1426                  */
1427                 if (is_system_labeled() &&
1428                     check_exempt_conflict_v4(connp, ipst))
1429                         return (EADDRINUSE);
1430                 /* FALLTHROUGH */
1431 
1432         case IPPROTO_UDP:
1433                 if (protocol == IPPROTO_UDP) {
1434                         connfp = &ipst->ips_ipcl_udp_fanout[
1435                             IPCL_UDP_HASH(lport, ipst)];
1436                 } else {
1437                         connfp = &ipst->ips_ipcl_proto_fanout_v4[protocol];
1438                 }
1439 
1440                 if (connp->conn_faddr_v4 != INADDR_ANY) {
1441                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1442                 } else if (connp->conn_laddr_v4 != INADDR_ANY) {
1443                         ipcl_hash_insert_bound(connfp, connp);
1444                 } else {
1445                         ipcl_hash_insert_wildcard(connfp, connp);
1446                 }
1447                 break;
1448         }
1449 
1450         return (ret);
1451 }
1452 
1453 int
1454 ipcl_conn_insert_v6(conn_t *connp)
1455 {
1456         connf_t         *connfp;
1457         conn_t          *tconnp;
1458         int             ret = 0;
1459         ip_stack_t      *ipst = connp->conn_netstack->netstack_ip;
1460         uint16_t        lport = connp->conn_lport;
1461         uint8_t         protocol = connp->conn_proto;
1462         uint_t          ifindex = connp->conn_bound_if;
1463 
1464         if (IPCL_IS_IPTUN(connp))
1465                 return (ipcl_iptun_hash_insert_v6(connp, ipst));
 
1511                 IPCL_HASH_REMOVE(connp);
1512                 ret = ipcl_sctp_hash_insert(connp, lport);
1513                 break;
1514 
1515         default:
1516                 if (is_system_labeled() &&
1517                     check_exempt_conflict_v6(connp, ipst))
1518                         return (EADDRINUSE);
1519                 /* FALLTHROUGH */
1520         case IPPROTO_UDP:
1521                 if (protocol == IPPROTO_UDP) {
1522                         connfp = &ipst->ips_ipcl_udp_fanout[
1523                             IPCL_UDP_HASH(lport, ipst)];
1524                 } else {
1525                         connfp = &ipst->ips_ipcl_proto_fanout_v6[protocol];
1526                 }
1527 
1528                 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) {
1529                         IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1530                 } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1531                         ipcl_hash_insert_bound(connfp, connp);
1532                 } else {
1533                         ipcl_hash_insert_wildcard(connfp, connp);
1534                 }
1535                 break;
1536         }
1537 
1538         return (ret);
1539 }
1540 
1541 /*
1542  * v4 packet classifying function. looks up the fanout table to
1543  * find the conn, the packet belongs to. returns the conn with
1544  * the reference held, null otherwise.
1545  *
1546  * If zoneid is ALL_ZONES, then the search rules described in the "Connection
1547  * Lookup" comment block are applied.  Labels are also checked as described
1548  * above.  If the packet is from the inside (looped back), and is from the same
1549  * zone, then label checks are omitted.
1550  */
1551 conn_t *
1552 ipcl_classify_v4(mblk_t *mp, uint8_t protocol, uint_t hdr_len,
1553     ip_recv_attr_t *ira, ip_stack_t *ipst)
 
2099         }
2100 }
2101 
2102 /* ARGSUSED */
2103 static int
2104 rawip_conn_constructor(void *buf, void *cdrarg, int kmflags)
2105 {
2106         itc_t   *itc = (itc_t *)buf;
2107         conn_t  *connp = &itc->itc_conn;
2108         icmp_t  *icmp = (icmp_t *)&itc[1];
2109 
2110         bzero(connp, sizeof (conn_t));
2111         bzero(icmp, sizeof (icmp_t));
2112 
2113         mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL);
2114         cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL);
2115         connp->conn_icmp = icmp;
2116         connp->conn_flags = IPCL_RAWIPCONN;
2117         connp->conn_proto = IPPROTO_ICMP;
2118         icmp->icmp_connp = connp;
2119         rw_init(&icmp->icmp_bpf_lock, NULL, RW_DEFAULT, NULL);
2120         rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL);
2121         connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags);
2122         if (connp->conn_ixa == NULL)
2123                 return (ENOMEM);
2124         connp->conn_ixa->ixa_refcnt = 1;
2125         connp->conn_ixa->ixa_protocol = connp->conn_proto;
2126         connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp);
2127         return (0);
2128 }
2129 
2130 /* ARGSUSED */
2131 static void
2132 rawip_conn_destructor(void *buf, void *cdrarg)
2133 {
2134         itc_t   *itc = (itc_t *)buf;
2135         conn_t  *connp = &itc->itc_conn;
2136         icmp_t  *icmp = (icmp_t *)&itc[1];
2137 
2138         ASSERT(connp->conn_flags & IPCL_RAWIPCONN);
2139         ASSERT(icmp->icmp_connp == connp);
2140         ASSERT(connp->conn_icmp == icmp);
2141         mutex_destroy(&connp->conn_lock);
2142         cv_destroy(&connp->conn_cv);
2143         rw_destroy(&connp->conn_ilg_lock);
2144         rw_destroy(&icmp->icmp_bpf_lock);
2145 
2146         /* Can be NULL if constructor failed */
2147         if (connp->conn_ixa != NULL) {
2148                 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2149                 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2150                 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2151                 ixa_refrele(connp->conn_ixa);
2152         }
2153 }
2154 
2155 /* ARGSUSED */
2156 static int
2157 rts_conn_constructor(void *buf, void *cdrarg, int kmflags)
2158 {
2159         itc_t   *itc = (itc_t *)buf;
2160         conn_t  *connp = &itc->itc_conn;
2161         rts_t   *rts = (rts_t *)&itc[1];
2162 
2163         bzero(connp, sizeof (conn_t));
2164         bzero(rts, sizeof (rts_t));
 
 |