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));
|