206 *
207 * void ipcl_hash_remove(connp);
208 *
209 * Removes the 'connp' from the connection fanout table.
210 *
211 * Connection Creation/Destruction
212 * -------------------------------
213 *
214 * conn_t *ipcl_conn_create(type, sleep, netstack_t *)
215 *
216 * Creates a new conn based on the type flag, inserts it into
217 * globalhash table.
218 *
219 * type: This flag determines the type of conn_t which needs to be
220 * created i.e., which kmem_cache it comes from.
221 * IPCL_TCPCONN indicates a TCP connection
222 * IPCL_SCTPCONN indicates a SCTP connection
223 * IPCL_UDPCONN indicates a UDP conn_t.
224 * IPCL_RAWIPCONN indicates a RAWIP/ICMP conn_t.
225 * IPCL_RTSCONN indicates a RTS conn_t.
226 * IPCL_IPCCONN indicates all other connections.
227 *
228 * void ipcl_conn_destroy(connp)
229 *
230 * Destroys the connection state, removes it from the global
231 * connection hash table and frees its memory.
232 */
233
234 #include <sys/types.h>
235 #include <sys/stream.h>
236 #include <sys/stropts.h>
237 #include <sys/sysmacros.h>
238 #include <sys/strsubr.h>
239 #include <sys/strsun.h>
240 #define _SUN_TPI_VERSION 2
241 #include <sys/ddi.h>
242 #include <sys/cmn_err.h>
243 #include <sys/debug.h>
244
245 #include <sys/systm.h>
246 #include <sys/param.h>
247 #include <sys/kmem.h>
248 #include <sys/isa_defs.h>
249 #include <inet/common.h>
250 #include <netinet/ip6.h>
251 #include <netinet/icmp6.h>
252
253 #include <inet/ip.h>
254 #include <inet/ip_if.h>
255 #include <inet/ip_ire.h>
256 #include <inet/ip6.h>
257 #include <inet/ip_ndp.h>
258 #include <inet/ip_impl.h>
259 #include <inet/udp_impl.h>
260 #include <inet/sctp_ip.h>
261 #include <inet/sctp/sctp_impl.h>
262 #include <inet/rawip_impl.h>
263 #include <inet/rts_impl.h>
264 #include <inet/iptun/iptun_impl.h>
265
266 #include <sys/cpuvar.h>
267
268 #include <inet/ipclassifier.h>
269 #include <inet/tcp.h>
270 #include <inet/ipsec_impl.h>
271
272 #include <sys/tsol/tnet.h>
273 #include <sys/sockio.h>
274
275 /* Old value for compatibility. Setable in /etc/system */
276 uint_t tcp_conn_hash_size = 0;
277
278 /* New value. Zero means choose automatically. Setable in /etc/system */
279 uint_t ipcl_conn_hash_size = 0;
280 uint_t ipcl_conn_hash_memfactor = 8192;
281 uint_t ipcl_conn_hash_maxsize = 82500;
282
283 /* bind/udp fanout table size */
284 uint_t ipcl_bind_fanout_size = 512;
285 uint_t ipcl_udp_fanout_size = 16384;
286
287 /* Raw socket fanout size. Must be a power of 2. */
288 uint_t ipcl_raw_fanout_size = 256;
289
290 /*
291 * The IPCL_IPTUN_HASH() function works best with a prime table size. We
292 * expect that most large deployments would have hundreds of tunnels, and
293 * thousands in the extreme case.
294 */
295 uint_t ipcl_iptun_fanout_size = 6143;
296
297 /*
298 * Power of 2^N Primes useful for hashing for N of 0-28,
299 * these primes are the nearest prime <= 2^N - 2^(N-2).
300 */
301
302 #define P2Ps() {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 761, 1531, 3067, \
303 6143, 12281, 24571, 49139, 98299, 196597, 393209, \
304 786431, 1572853, 3145721, 6291449, 12582893, 25165813, \
305 50331599, 100663291, 201326557, 0}
306
307 /*
308 * wrapper structure to ensure that conn and what follows it (tcp_t, etc)
309 * are aligned on cache lines.
310 */
311 typedef union itc_s {
312 conn_t itc_conn;
313 char itcu_filler[CACHE_ALIGN(conn_s)];
314 } itc_t;
315
316 struct kmem_cache *tcp_conn_cache;
317 struct kmem_cache *ip_conn_cache;
318 extern struct kmem_cache *sctp_conn_cache;
319 struct kmem_cache *udp_conn_cache;
320 struct kmem_cache *rawip_conn_cache;
321 struct kmem_cache *rts_conn_cache;
322
323 extern void tcp_timermp_free(tcp_t *);
324 extern mblk_t *tcp_timermp_alloc(int);
325
326 static int ip_conn_constructor(void *, void *, int);
327 static void ip_conn_destructor(void *, void *);
328
329 static int tcp_conn_constructor(void *, void *, int);
330 static void tcp_conn_destructor(void *, void *);
331
332 static int udp_conn_constructor(void *, void *, int);
333 static void udp_conn_destructor(void *, void *);
334
335 static int rawip_conn_constructor(void *, void *, int);
336 static void rawip_conn_destructor(void *, void *);
337
338 static int rts_conn_constructor(void *, void *, int);
339 static void rts_conn_destructor(void *, void *);
340
341 /*
342 * Global (for all stack instances) init routine
343 */
344 void
345 ipcl_g_init(void)
346 {
347 ip_conn_cache = kmem_cache_create("ip_conn_cache",
348 sizeof (conn_t), CACHE_ALIGN_SIZE,
349 ip_conn_constructor, ip_conn_destructor,
350 NULL, NULL, NULL, 0);
351
352 tcp_conn_cache = kmem_cache_create("tcp_conn_cache",
353 sizeof (itc_t) + sizeof (tcp_t), CACHE_ALIGN_SIZE,
354 tcp_conn_constructor, tcp_conn_destructor,
355 tcp_conn_reclaim, NULL, NULL, 0);
356
357 udp_conn_cache = kmem_cache_create("udp_conn_cache",
358 sizeof (itc_t) + sizeof (udp_t), CACHE_ALIGN_SIZE,
359 udp_conn_constructor, udp_conn_destructor,
360 NULL, NULL, NULL, 0);
361
362 rawip_conn_cache = kmem_cache_create("rawip_conn_cache",
363 sizeof (itc_t) + sizeof (icmp_t), CACHE_ALIGN_SIZE,
364 rawip_conn_constructor, rawip_conn_destructor,
365 NULL, NULL, NULL, 0);
366
367 rts_conn_cache = kmem_cache_create("rts_conn_cache",
368 sizeof (itc_t) + sizeof (rts_t), CACHE_ALIGN_SIZE,
369 rts_conn_constructor, rts_conn_destructor,
370 NULL, NULL, NULL, 0);
371 }
372
373 /*
374 * ipclassifier intialization routine, sets up hash tables.
375 */
376 void
377 ipcl_init(ip_stack_t *ipst)
378 {
379 int i;
380 int sizes[] = P2Ps();
381
382 /*
383 * Calculate size of conn fanout table from /etc/system settings
384 */
385 if (ipcl_conn_hash_size != 0) {
386 ipst->ips_ipcl_conn_fanout_size = ipcl_conn_hash_size;
387 } else if (tcp_conn_hash_size != 0) {
388 ipst->ips_ipcl_conn_fanout_size = tcp_conn_hash_size;
389 } else {
390 extern pgcnt_t freemem;
393 (freemem * PAGESIZE) / ipcl_conn_hash_memfactor;
394
395 if (ipst->ips_ipcl_conn_fanout_size > ipcl_conn_hash_maxsize) {
396 ipst->ips_ipcl_conn_fanout_size =
397 ipcl_conn_hash_maxsize;
398 }
399 }
400
401 for (i = 9; i < sizeof (sizes) / sizeof (*sizes) - 1; i++) {
402 if (sizes[i] >= ipst->ips_ipcl_conn_fanout_size) {
403 break;
404 }
405 }
406 if ((ipst->ips_ipcl_conn_fanout_size = sizes[i]) == 0) {
407 /* Out of range, use the 2^16 value */
408 ipst->ips_ipcl_conn_fanout_size = sizes[16];
409 }
410
411 /* Take values from /etc/system */
412 ipst->ips_ipcl_bind_fanout_size = ipcl_bind_fanout_size;
413 ipst->ips_ipcl_udp_fanout_size = ipcl_udp_fanout_size;
414 ipst->ips_ipcl_raw_fanout_size = ipcl_raw_fanout_size;
415 ipst->ips_ipcl_iptun_fanout_size = ipcl_iptun_fanout_size;
416
417 ASSERT(ipst->ips_ipcl_conn_fanout == NULL);
418
419 ipst->ips_ipcl_conn_fanout = kmem_zalloc(
420 ipst->ips_ipcl_conn_fanout_size * sizeof (connf_t), KM_SLEEP);
421
422 for (i = 0; i < ipst->ips_ipcl_conn_fanout_size; i++) {
423 mutex_init(&ipst->ips_ipcl_conn_fanout[i].connf_lock, NULL,
424 MUTEX_DEFAULT, NULL);
425 }
426
427 ipst->ips_ipcl_bind_fanout = kmem_zalloc(
428 ipst->ips_ipcl_bind_fanout_size * sizeof (connf_t), KM_SLEEP);
429
430 for (i = 0; i < ipst->ips_ipcl_bind_fanout_size; i++) {
431 mutex_init(&ipst->ips_ipcl_bind_fanout[i].connf_lock, NULL,
432 MUTEX_DEFAULT, NULL);
460 ipst->ips_ipcl_iptun_fanout = kmem_zalloc(
461 ipst->ips_ipcl_iptun_fanout_size * sizeof (connf_t), KM_SLEEP);
462 for (i = 0; i < ipst->ips_ipcl_iptun_fanout_size; i++) {
463 mutex_init(&ipst->ips_ipcl_iptun_fanout[i].connf_lock, NULL,
464 MUTEX_DEFAULT, NULL);
465 }
466
467 ipst->ips_ipcl_raw_fanout = kmem_zalloc(
468 ipst->ips_ipcl_raw_fanout_size * sizeof (connf_t), KM_SLEEP);
469 for (i = 0; i < ipst->ips_ipcl_raw_fanout_size; i++) {
470 mutex_init(&ipst->ips_ipcl_raw_fanout[i].connf_lock, NULL,
471 MUTEX_DEFAULT, NULL);
472 }
473
474 ipst->ips_ipcl_globalhash_fanout = kmem_zalloc(
475 sizeof (connf_t) * CONN_G_HASH_SIZE, KM_SLEEP);
476 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
477 mutex_init(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock,
478 NULL, MUTEX_DEFAULT, NULL);
479 }
480 }
481
482 void
483 ipcl_g_destroy(void)
484 {
485 kmem_cache_destroy(ip_conn_cache);
486 kmem_cache_destroy(tcp_conn_cache);
487 kmem_cache_destroy(udp_conn_cache);
488 kmem_cache_destroy(rawip_conn_cache);
489 kmem_cache_destroy(rts_conn_cache);
490 }
491
492 /*
493 * All user-level and kernel use of the stack must be gone
494 * by now.
495 */
496 void
497 ipcl_destroy(ip_stack_t *ipst)
498 {
499 int i;
500
501 for (i = 0; i < ipst->ips_ipcl_conn_fanout_size; i++) {
502 ASSERT(ipst->ips_ipcl_conn_fanout[i].connf_head == NULL);
503 mutex_destroy(&ipst->ips_ipcl_conn_fanout[i].connf_lock);
504 }
505 kmem_free(ipst->ips_ipcl_conn_fanout, ipst->ips_ipcl_conn_fanout_size *
506 sizeof (connf_t));
507 ipst->ips_ipcl_conn_fanout = NULL;
508
509 for (i = 0; i < ipst->ips_ipcl_bind_fanout_size; i++) {
545 kmem_free(ipst->ips_ipcl_iptun_fanout,
546 ipst->ips_ipcl_iptun_fanout_size * sizeof (connf_t));
547 ipst->ips_ipcl_iptun_fanout = NULL;
548
549 for (i = 0; i < ipst->ips_ipcl_raw_fanout_size; i++) {
550 ASSERT(ipst->ips_ipcl_raw_fanout[i].connf_head == NULL);
551 mutex_destroy(&ipst->ips_ipcl_raw_fanout[i].connf_lock);
552 }
553 kmem_free(ipst->ips_ipcl_raw_fanout, ipst->ips_ipcl_raw_fanout_size *
554 sizeof (connf_t));
555 ipst->ips_ipcl_raw_fanout = NULL;
556
557 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
558 ASSERT(ipst->ips_ipcl_globalhash_fanout[i].connf_head == NULL);
559 mutex_destroy(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock);
560 }
561 kmem_free(ipst->ips_ipcl_globalhash_fanout,
562 sizeof (connf_t) * CONN_G_HASH_SIZE);
563 ipst->ips_ipcl_globalhash_fanout = NULL;
564
565 ASSERT(ipst->ips_rts_clients->connf_head == NULL);
566 mutex_destroy(&ipst->ips_rts_clients->connf_lock);
567 kmem_free(ipst->ips_rts_clients, sizeof (connf_t));
568 ipst->ips_rts_clients = NULL;
569 }
570
571 /*
572 * conn creation routine. initialize the conn, sets the reference
573 * and inserts it in the global hash table.
574 */
575 conn_t *
576 ipcl_conn_create(uint32_t type, int sleep, netstack_t *ns)
577 {
578 conn_t *connp;
579 struct kmem_cache *conn_cache;
580
581 switch (type) {
582 case IPCL_SCTPCONN:
583 if ((connp = kmem_cache_alloc(sctp_conn_cache, sleep)) == NULL)
584 return (NULL);
593 case IPCL_TCPCONN:
594 conn_cache = tcp_conn_cache;
595 break;
596
597 case IPCL_UDPCONN:
598 conn_cache = udp_conn_cache;
599 break;
600
601 case IPCL_RAWIPCONN:
602 conn_cache = rawip_conn_cache;
603 break;
604
605 case IPCL_RTSCONN:
606 conn_cache = rts_conn_cache;
607 break;
608
609 case IPCL_IPCCONN:
610 conn_cache = ip_conn_cache;
611 break;
612
613 default:
614 connp = NULL;
615 ASSERT(0);
616 }
617
618 if ((connp = kmem_cache_alloc(conn_cache, sleep)) == NULL)
619 return (NULL);
620
621 connp->conn_ref = 1;
622 netstack_hold(ns);
623 connp->conn_netstack = ns;
624 connp->conn_ixa->ixa_ipst = ns->netstack_ip;
625 connp->conn_ixa->ixa_conn_id = (long)connp;
626 ipcl_globalhash_insert(connp);
627 return (connp);
628 }
629
630 void
631 ipcl_conn_destroy(conn_t *connp)
632 {
703 ASSERT(tcp->tcp_tcps == NULL);
704 connp->conn_netstack = NULL;
705 connp->conn_ixa->ixa_ipst = NULL;
706 netstack_rele(ns);
707 }
708
709 bzero(tcp, sizeof (tcp_t));
710
711 tcp->tcp_timercache = mp;
712 tcp->tcp_connp = connp;
713 kmem_cache_free(tcp_conn_cache, connp);
714 return;
715 }
716
717 if (connp->conn_flags & IPCL_SCTPCONN) {
718 ASSERT(ns != NULL);
719 sctp_free(connp);
720 return;
721 }
722
723 ipcl_conn_cleanup(connp);
724 if (ns != NULL) {
725 connp->conn_netstack = NULL;
726 connp->conn_ixa->ixa_ipst = NULL;
727 netstack_rele(ns);
728 }
729
730 /* leave conn_priv aka conn_udp, conn_icmp, etc in place. */
731 if (connp->conn_flags & IPCL_UDPCONN) {
732 connp->conn_flags = IPCL_UDPCONN;
733 kmem_cache_free(udp_conn_cache, connp);
734 } else if (connp->conn_flags & IPCL_RAWIPCONN) {
735 connp->conn_flags = IPCL_RAWIPCONN;
736 connp->conn_proto = IPPROTO_ICMP;
737 connp->conn_ixa->ixa_protocol = connp->conn_proto;
738 kmem_cache_free(rawip_conn_cache, connp);
739 } else if (connp->conn_flags & IPCL_RTSCONN) {
740 connp->conn_flags = IPCL_RTSCONN;
741 kmem_cache_free(rts_conn_cache, connp);
742 } else {
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
1245 ipcl_bind_insert_v6(conn_t *connp)
1246 {
1247 connf_t *connfp;
1248 int ret = 0;
1249 ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
1250 uint16_t lport = connp->conn_lport;
1251 uint8_t protocol = connp->conn_proto;
1252
1253 if (IPCL_IS_IPTUN(connp)) {
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))
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
1309 case IPPROTO_SCTP:
1310 ret = ipcl_sctp_hash_insert(connp, lport);
1311 break;
1312 }
1313
1314 return (ret);
1315 }
1316
1317 /*
1318 * ipcl_conn_hash insertion routines.
1319 * The caller has already set conn_proto and the addresses/ports in the conn_t.
1320 */
1321
1322 int
1323 ipcl_conn_insert(conn_t *connp)
1324 {
1325 if (connp->conn_ipversion == IPV6_VERSION)
1326 return (ipcl_conn_insert_v6(connp));
1327 else
1328 return (ipcl_conn_insert_v4(connp));
1329 }
1330
1331 int
1376 IPCL_HASH_REMOVE(connp);
1377 mutex_enter(&connfp->connf_lock);
1378 }
1379
1380 ASSERT(connp->conn_recv != NULL);
1381 ASSERT(connp->conn_recvicmp != NULL);
1382
1383 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1384 mutex_exit(&connfp->connf_lock);
1385 break;
1386
1387 case IPPROTO_SCTP:
1388 /*
1389 * The raw socket may have already been bound, remove it
1390 * from the hash first.
1391 */
1392 IPCL_HASH_REMOVE(connp);
1393 ret = ipcl_sctp_hash_insert(connp, lport);
1394 break;
1395
1396 default:
1397 /*
1398 * Check for conflicts among MAC exempt bindings. For
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
1471 }
1472 }
1473 if (connp->conn_fanout != NULL) {
1474 /*
1475 * Probably a XTI/TLI application trying to do a
1476 * rebind. Let it happen.
1477 */
1478 mutex_exit(&connfp->connf_lock);
1479 IPCL_HASH_REMOVE(connp);
1480 mutex_enter(&connfp->connf_lock);
1481 }
1482 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1483 mutex_exit(&connfp->connf_lock);
1484 break;
1485
1486 case IPPROTO_SCTP:
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 }
1638 ira, connp)) {
1639 DTRACE_PROBE3(tx__ip__log__info__classify__udp,
1640 char *, "connp(1) could not receive mp(2)",
1641 conn_t *, connp, mblk_t *, mp);
1642 connp = NULL;
1643 }
1644
1645 if (connp != NULL) {
1646 CONN_INC_REF(connp);
1647 mutex_exit(&connfp->connf_lock);
1648 return (connp);
1649 }
1650
1651 /*
1652 * We shouldn't come here for multicast/broadcast packets
1653 */
1654 mutex_exit(&connfp->connf_lock);
1655
1656 break;
1657
1658 case IPPROTO_ENCAP:
1659 case IPPROTO_IPV6:
1660 return (ipcl_iptun_classify_v4(&ipha->ipha_src,
1661 &ipha->ipha_dst, ipst));
1662 }
1663
1664 return (NULL);
1665 }
1666
1667 conn_t *
1668 ipcl_classify_v6(mblk_t *mp, uint8_t protocol, uint_t hdr_len,
1669 ip_recv_attr_t *ira, ip_stack_t *ipst)
1670 {
1671 ip6_t *ip6h;
1672 connf_t *connfp, *bind_connfp;
1673 uint16_t lport;
1674 uint16_t fport;
1675 tcpha_t *tcpha;
1676 uint32_t ports;
1677 conn_t *connp;
2158 itc_t *itc = (itc_t *)buf;
2159 conn_t *connp = &itc->itc_conn;
2160 rts_t *rts = (rts_t *)&itc[1];
2161
2162 ASSERT(connp->conn_flags & IPCL_RTSCONN);
2163 ASSERT(rts->rts_connp == connp);
2164 ASSERT(connp->conn_rts == rts);
2165 mutex_destroy(&connp->conn_lock);
2166 cv_destroy(&connp->conn_cv);
2167 rw_destroy(&connp->conn_ilg_lock);
2168
2169 /* Can be NULL if constructor failed */
2170 if (connp->conn_ixa != NULL) {
2171 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2172 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2173 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2174 ixa_refrele(connp->conn_ixa);
2175 }
2176 }
2177
2178 /*
2179 * Called as part of ipcl_conn_destroy to assert and clear any pointers
2180 * in the conn_t.
2181 *
2182 * Below we list all the pointers in the conn_t as a documentation aid.
2183 * The ones that we can not ASSERT to be NULL are #ifdef'ed out.
2184 * If you add any pointers to the conn_t please add an ASSERT here
2185 * and #ifdef it out if it can't be actually asserted to be NULL.
2186 * In any case, we bzero most of the conn_t at the end of the function.
2187 */
2188 void
2189 ipcl_conn_cleanup(conn_t *connp)
2190 {
2191 ip_xmit_attr_t *ixa;
2192
2193 ASSERT(connp->conn_latch == NULL);
2194 ASSERT(connp->conn_latch_in_policy == NULL);
2195 ASSERT(connp->conn_latch_in_action == NULL);
2196 #ifdef notdef
2197 ASSERT(connp->conn_rq == NULL);
|
206 *
207 * void ipcl_hash_remove(connp);
208 *
209 * Removes the 'connp' from the connection fanout table.
210 *
211 * Connection Creation/Destruction
212 * -------------------------------
213 *
214 * conn_t *ipcl_conn_create(type, sleep, netstack_t *)
215 *
216 * Creates a new conn based on the type flag, inserts it into
217 * globalhash table.
218 *
219 * type: This flag determines the type of conn_t which needs to be
220 * created i.e., which kmem_cache it comes from.
221 * IPCL_TCPCONN indicates a TCP connection
222 * IPCL_SCTPCONN indicates a SCTP connection
223 * IPCL_UDPCONN indicates a UDP conn_t.
224 * IPCL_RAWIPCONN indicates a RAWIP/ICMP conn_t.
225 * IPCL_RTSCONN indicates a RTS conn_t.
226 * IPCL_DCCPCONN indicates a DCCP conn_t.
227 * IPCL_IPCCONN indicates all other connections.
228 *
229 * void ipcl_conn_destroy(connp)
230 *
231 * Destroys the connection state, removes it from the global
232 * connection hash table and frees its memory.
233 */
234
235 #include <sys/types.h>
236 #include <sys/stream.h>
237 #include <sys/stropts.h>
238 #include <sys/sysmacros.h>
239 #include <sys/strsubr.h>
240 #include <sys/strsun.h>
241 #define _SUN_TPI_VERSION 2
242 #include <sys/ddi.h>
243 #include <sys/cmn_err.h>
244 #include <sys/debug.h>
245
246 #include <sys/systm.h>
247 #include <sys/param.h>
248 #include <sys/kmem.h>
249 #include <sys/isa_defs.h>
250 #include <inet/common.h>
251 #include <netinet/ip6.h>
252 #include <netinet/icmp6.h>
253
254 #include <inet/ip.h>
255 #include <inet/ip_if.h>
256 #include <inet/ip_ire.h>
257 #include <inet/ip6.h>
258 #include <inet/ip_ndp.h>
259 #include <inet/ip_impl.h>
260 #include <inet/udp_impl.h>
261 #include <inet/dccp/dccp_impl.h>
262 #include <inet/sctp_ip.h>
263 #include <inet/sctp/sctp_impl.h>
264 #include <inet/rawip_impl.h>
265 #include <inet/rts_impl.h>
266 #include <inet/iptun/iptun_impl.h>
267
268 #include <sys/cpuvar.h>
269
270 #include <inet/ipclassifier.h>
271 #include <inet/tcp.h>
272 #include <inet/ipsec_impl.h>
273
274 #include <sys/tsol/tnet.h>
275 #include <sys/sockio.h>
276
277 /* Old value for compatibility. Setable in /etc/system */
278 uint_t tcp_conn_hash_size = 0;
279
280 /* New value. Zero means choose automatically. Setable in /etc/system */
281 uint_t ipcl_conn_hash_size = 0;
282 uint_t ipcl_conn_hash_memfactor = 8192;
283 uint_t ipcl_conn_hash_maxsize = 82500;
284
285 /* bind/dccp/udp fanout table size */
286 uint_t ipcl_bind_fanout_size = 512;
287 uint_t ipcl_dccp_fanout_size = 512;
288 uint_t ipcl_udp_fanout_size = 16384;
289
290 /* Raw socket fanout size. Must be a power of 2. */
291 uint_t ipcl_raw_fanout_size = 256;
292
293 /*
294 * The IPCL_IPTUN_HASH() function works best with a prime table size. We
295 * expect that most large deployments would have hundreds of tunnels, and
296 * thousands in the extreme case.
297 */
298 uint_t ipcl_iptun_fanout_size = 6143;
299
300 /*
301 * Power of 2^N Primes useful for hashing for N of 0-28,
302 * these primes are the nearest prime <= 2^N - 2^(N-2).
303 */
304
305 #define P2Ps() {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 761, 1531, 3067, \
306 6143, 12281, 24571, 49139, 98299, 196597, 393209, \
307 786431, 1572853, 3145721, 6291449, 12582893, 25165813, \
308 50331599, 100663291, 201326557, 0}
309
310 /*
311 * wrapper structure to ensure that conn and what follows it (tcp_t, etc)
312 * are aligned on cache lines.
313 */
314 typedef union itc_s {
315 conn_t itc_conn;
316 char itcu_filler[CACHE_ALIGN(conn_s)];
317 } itc_t;
318
319 struct kmem_cache *tcp_conn_cache;
320 struct kmem_cache *ip_conn_cache;
321 extern struct kmem_cache *sctp_conn_cache;
322 struct kmem_cache *udp_conn_cache;
323 struct kmem_cache *rawip_conn_cache;
324 struct kmem_cache *rts_conn_cache;
325 struct kmem_cache *dccp_conn_cache;
326
327 extern void tcp_timermp_free(tcp_t *);
328 extern mblk_t *tcp_timermp_alloc(int);
329
330 static int ip_conn_constructor(void *, void *, int);
331 static void ip_conn_destructor(void *, void *);
332
333 static int tcp_conn_constructor(void *, void *, int);
334 static void tcp_conn_destructor(void *, void *);
335
336 static int udp_conn_constructor(void *, void *, int);
337 static void udp_conn_destructor(void *, void *);
338
339 static int rawip_conn_constructor(void *, void *, int);
340 static void rawip_conn_destructor(void *, void *);
341
342 static int rts_conn_constructor(void *, void *, int);
343 static void rts_conn_destructor(void *, void *);
344
345 static int dccp_conn_constructor(void *, void *, int);
346 static void dccp_conn_destructor(void *, void *);
347
348 /*
349 * Global (for all stack instances) init routine
350 */
351 void
352 ipcl_g_init(void)
353 {
354 ip_conn_cache = kmem_cache_create("ip_conn_cache",
355 sizeof (conn_t), CACHE_ALIGN_SIZE,
356 ip_conn_constructor, ip_conn_destructor,
357 NULL, NULL, NULL, 0);
358
359 tcp_conn_cache = kmem_cache_create("tcp_conn_cache",
360 sizeof (itc_t) + sizeof (tcp_t), CACHE_ALIGN_SIZE,
361 tcp_conn_constructor, tcp_conn_destructor,
362 tcp_conn_reclaim, NULL, NULL, 0);
363
364 udp_conn_cache = kmem_cache_create("udp_conn_cache",
365 sizeof (itc_t) + sizeof (udp_t), CACHE_ALIGN_SIZE,
366 udp_conn_constructor, udp_conn_destructor,
367 NULL, NULL, NULL, 0);
368
369 rawip_conn_cache = kmem_cache_create("rawip_conn_cache",
370 sizeof (itc_t) + sizeof (icmp_t), CACHE_ALIGN_SIZE,
371 rawip_conn_constructor, rawip_conn_destructor,
372 NULL, NULL, NULL, 0);
373
374 rts_conn_cache = kmem_cache_create("rts_conn_cache",
375 sizeof (itc_t) + sizeof (rts_t), CACHE_ALIGN_SIZE,
376 rts_conn_constructor, rts_conn_destructor,
377 NULL, NULL, NULL, 0);
378
379 /* XXX:DCCP reclaim */
380 dccp_conn_cache = kmem_cache_create("dccp_conn_cache",
381 sizeof (itc_t) + sizeof (dccp_t), CACHE_ALIGN_SIZE,
382 dccp_conn_constructor, dccp_conn_destructor,
383 NULL, NULL, NULL, 0);
384 }
385
386 /*
387 * ipclassifier intialization routine, sets up hash tables.
388 */
389 void
390 ipcl_init(ip_stack_t *ipst)
391 {
392 int i;
393 int sizes[] = P2Ps();
394
395 /*
396 * Calculate size of conn fanout table from /etc/system settings
397 */
398 if (ipcl_conn_hash_size != 0) {
399 ipst->ips_ipcl_conn_fanout_size = ipcl_conn_hash_size;
400 } else if (tcp_conn_hash_size != 0) {
401 ipst->ips_ipcl_conn_fanout_size = tcp_conn_hash_size;
402 } else {
403 extern pgcnt_t freemem;
406 (freemem * PAGESIZE) / ipcl_conn_hash_memfactor;
407
408 if (ipst->ips_ipcl_conn_fanout_size > ipcl_conn_hash_maxsize) {
409 ipst->ips_ipcl_conn_fanout_size =
410 ipcl_conn_hash_maxsize;
411 }
412 }
413
414 for (i = 9; i < sizeof (sizes) / sizeof (*sizes) - 1; i++) {
415 if (sizes[i] >= ipst->ips_ipcl_conn_fanout_size) {
416 break;
417 }
418 }
419 if ((ipst->ips_ipcl_conn_fanout_size = sizes[i]) == 0) {
420 /* Out of range, use the 2^16 value */
421 ipst->ips_ipcl_conn_fanout_size = sizes[16];
422 }
423
424 /* Take values from /etc/system */
425 ipst->ips_ipcl_bind_fanout_size = ipcl_bind_fanout_size;
426 ipst->ips_ipcl_dccp_fanout_size = ipcl_dccp_fanout_size;
427 ipst->ips_ipcl_udp_fanout_size = ipcl_udp_fanout_size;
428 ipst->ips_ipcl_raw_fanout_size = ipcl_raw_fanout_size;
429 ipst->ips_ipcl_iptun_fanout_size = ipcl_iptun_fanout_size;
430
431 ASSERT(ipst->ips_ipcl_conn_fanout == NULL);
432
433 ipst->ips_ipcl_conn_fanout = kmem_zalloc(
434 ipst->ips_ipcl_conn_fanout_size * sizeof (connf_t), KM_SLEEP);
435
436 for (i = 0; i < ipst->ips_ipcl_conn_fanout_size; i++) {
437 mutex_init(&ipst->ips_ipcl_conn_fanout[i].connf_lock, NULL,
438 MUTEX_DEFAULT, NULL);
439 }
440
441 ipst->ips_ipcl_bind_fanout = kmem_zalloc(
442 ipst->ips_ipcl_bind_fanout_size * sizeof (connf_t), KM_SLEEP);
443
444 for (i = 0; i < ipst->ips_ipcl_bind_fanout_size; i++) {
445 mutex_init(&ipst->ips_ipcl_bind_fanout[i].connf_lock, NULL,
446 MUTEX_DEFAULT, NULL);
474 ipst->ips_ipcl_iptun_fanout = kmem_zalloc(
475 ipst->ips_ipcl_iptun_fanout_size * sizeof (connf_t), KM_SLEEP);
476 for (i = 0; i < ipst->ips_ipcl_iptun_fanout_size; i++) {
477 mutex_init(&ipst->ips_ipcl_iptun_fanout[i].connf_lock, NULL,
478 MUTEX_DEFAULT, NULL);
479 }
480
481 ipst->ips_ipcl_raw_fanout = kmem_zalloc(
482 ipst->ips_ipcl_raw_fanout_size * sizeof (connf_t), KM_SLEEP);
483 for (i = 0; i < ipst->ips_ipcl_raw_fanout_size; i++) {
484 mutex_init(&ipst->ips_ipcl_raw_fanout[i].connf_lock, NULL,
485 MUTEX_DEFAULT, NULL);
486 }
487
488 ipst->ips_ipcl_globalhash_fanout = kmem_zalloc(
489 sizeof (connf_t) * CONN_G_HASH_SIZE, KM_SLEEP);
490 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
491 mutex_init(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock,
492 NULL, MUTEX_DEFAULT, NULL);
493 }
494
495 ipst->ips_ipcl_dccp_fanout = kmem_zalloc(
496 ipst->ips_ipcl_dccp_fanout_size * sizeof (connf_t), KM_SLEEP);
497 for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) {
498 mutex_init(&ipst->ips_ipcl_dccp_fanout[i].connf_lock, NULL,
499 MUTEX_DEFAULT, NULL);
500 }
501 }
502
503 void
504 ipcl_g_destroy(void)
505 {
506 kmem_cache_destroy(ip_conn_cache);
507 kmem_cache_destroy(tcp_conn_cache);
508 kmem_cache_destroy(udp_conn_cache);
509 kmem_cache_destroy(rawip_conn_cache);
510 kmem_cache_destroy(rts_conn_cache);
511 kmem_cache_destroy(dccp_conn_cache);
512 }
513
514 /*
515 * All user-level and kernel use of the stack must be gone
516 * by now.
517 */
518 void
519 ipcl_destroy(ip_stack_t *ipst)
520 {
521 int i;
522
523 for (i = 0; i < ipst->ips_ipcl_conn_fanout_size; i++) {
524 ASSERT(ipst->ips_ipcl_conn_fanout[i].connf_head == NULL);
525 mutex_destroy(&ipst->ips_ipcl_conn_fanout[i].connf_lock);
526 }
527 kmem_free(ipst->ips_ipcl_conn_fanout, ipst->ips_ipcl_conn_fanout_size *
528 sizeof (connf_t));
529 ipst->ips_ipcl_conn_fanout = NULL;
530
531 for (i = 0; i < ipst->ips_ipcl_bind_fanout_size; i++) {
567 kmem_free(ipst->ips_ipcl_iptun_fanout,
568 ipst->ips_ipcl_iptun_fanout_size * sizeof (connf_t));
569 ipst->ips_ipcl_iptun_fanout = NULL;
570
571 for (i = 0; i < ipst->ips_ipcl_raw_fanout_size; i++) {
572 ASSERT(ipst->ips_ipcl_raw_fanout[i].connf_head == NULL);
573 mutex_destroy(&ipst->ips_ipcl_raw_fanout[i].connf_lock);
574 }
575 kmem_free(ipst->ips_ipcl_raw_fanout, ipst->ips_ipcl_raw_fanout_size *
576 sizeof (connf_t));
577 ipst->ips_ipcl_raw_fanout = NULL;
578
579 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
580 ASSERT(ipst->ips_ipcl_globalhash_fanout[i].connf_head == NULL);
581 mutex_destroy(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock);
582 }
583 kmem_free(ipst->ips_ipcl_globalhash_fanout,
584 sizeof (connf_t) * CONN_G_HASH_SIZE);
585 ipst->ips_ipcl_globalhash_fanout = NULL;
586
587 for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) {
588 ASSERT(ipst->ips_ipcl_dccp_fanout[i].connf_head == NULL);
589 mutex_destroy(&ipst->ips_ipcl_dccp_fanout[i].connf_lock);
590 }
591 kmem_free(ipst->ips_ipcl_dccp_fanout, ipst->ips_ipcl_dccp_fanout_size *
592 sizeof (connf_t));
593 ipst->ips_ipcl_dccp_fanout = NULL;
594
595 ASSERT(ipst->ips_rts_clients->connf_head == NULL);
596 mutex_destroy(&ipst->ips_rts_clients->connf_lock);
597 kmem_free(ipst->ips_rts_clients, sizeof (connf_t));
598 ipst->ips_rts_clients = NULL;
599 }
600
601 /*
602 * conn creation routine. initialize the conn, sets the reference
603 * and inserts it in the global hash table.
604 */
605 conn_t *
606 ipcl_conn_create(uint32_t type, int sleep, netstack_t *ns)
607 {
608 conn_t *connp;
609 struct kmem_cache *conn_cache;
610
611 switch (type) {
612 case IPCL_SCTPCONN:
613 if ((connp = kmem_cache_alloc(sctp_conn_cache, sleep)) == NULL)
614 return (NULL);
623 case IPCL_TCPCONN:
624 conn_cache = tcp_conn_cache;
625 break;
626
627 case IPCL_UDPCONN:
628 conn_cache = udp_conn_cache;
629 break;
630
631 case IPCL_RAWIPCONN:
632 conn_cache = rawip_conn_cache;
633 break;
634
635 case IPCL_RTSCONN:
636 conn_cache = rts_conn_cache;
637 break;
638
639 case IPCL_IPCCONN:
640 conn_cache = ip_conn_cache;
641 break;
642
643 case IPCL_DCCPCONN:
644 conn_cache = dccp_conn_cache;
645 break;
646
647 default:
648 connp = NULL;
649 ASSERT(0);
650 }
651
652 if ((connp = kmem_cache_alloc(conn_cache, sleep)) == NULL)
653 return (NULL);
654
655 connp->conn_ref = 1;
656 netstack_hold(ns);
657 connp->conn_netstack = ns;
658 connp->conn_ixa->ixa_ipst = ns->netstack_ip;
659 connp->conn_ixa->ixa_conn_id = (long)connp;
660 ipcl_globalhash_insert(connp);
661 return (connp);
662 }
663
664 void
665 ipcl_conn_destroy(conn_t *connp)
666 {
737 ASSERT(tcp->tcp_tcps == NULL);
738 connp->conn_netstack = NULL;
739 connp->conn_ixa->ixa_ipst = NULL;
740 netstack_rele(ns);
741 }
742
743 bzero(tcp, sizeof (tcp_t));
744
745 tcp->tcp_timercache = mp;
746 tcp->tcp_connp = connp;
747 kmem_cache_free(tcp_conn_cache, connp);
748 return;
749 }
750
751 if (connp->conn_flags & IPCL_SCTPCONN) {
752 ASSERT(ns != NULL);
753 sctp_free(connp);
754 return;
755 }
756
757 if (connp->conn_flags & IPCL_DCCPCONN) {
758 dccp_t *dccp = connp->conn_dccp;
759
760 cmn_err(CE_NOTE, "ipclassifier: conn_flags DCCP cache_free");
761
762 /* XXX:DCCP */
763 /* Crash bug here: udp_conn_cache and dccp_conn_cache */
764 /*
765 ipcl_conn_cleanup(connp);
766 connp->conn_flags = IPCL_DCCPCONN;
767 bzero(dccp, sizeof (dccp_t));
768 dccp->dccp_connp = connp;
769 kmem_cache_free(dccp_conn_cache, connp);
770 return;
771 */
772 }
773
774 ipcl_conn_cleanup(connp);
775 if (ns != NULL) {
776 connp->conn_netstack = NULL;
777 connp->conn_ixa->ixa_ipst = NULL;
778 netstack_rele(ns);
779 }
780
781 /* leave conn_priv aka conn_udp, conn_icmp, etc in place. */
782 if (connp->conn_flags & IPCL_UDPCONN) {
783 connp->conn_flags = IPCL_UDPCONN;
784 kmem_cache_free(udp_conn_cache, connp);
785 } else if (connp->conn_flags & IPCL_RAWIPCONN) {
786 connp->conn_flags = IPCL_RAWIPCONN;
787 connp->conn_proto = IPPROTO_ICMP;
788 connp->conn_ixa->ixa_protocol = connp->conn_proto;
789 kmem_cache_free(rawip_conn_cache, connp);
790 } else if (connp->conn_flags & IPCL_RTSCONN) {
791 connp->conn_flags = IPCL_RTSCONN;
792 kmem_cache_free(rts_conn_cache, connp);
793 } else {
1270 connfp = &ipst->ips_ipcl_bind_fanout[
1271 IPCL_BIND_HASH(lport, ipst)];
1272 if (connp->conn_laddr_v4 != INADDR_ANY) {
1273 IPCL_HASH_INSERT_BOUND(connfp, connp);
1274 } else {
1275 IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1276 }
1277 if (cl_inet_listen != NULL) {
1278 ASSERT(connp->conn_ipversion == IPV4_VERSION);
1279 connp->conn_flags |= IPCL_CL_LISTENER;
1280 (*cl_inet_listen)(
1281 connp->conn_netstack->netstack_stackid,
1282 IPPROTO_TCP, AF_INET,
1283 (uint8_t *)&connp->conn_bound_addr_v4, lport, NULL);
1284 }
1285 break;
1286
1287 case IPPROTO_SCTP:
1288 ret = ipcl_sctp_hash_insert(connp, lport);
1289 break;
1290
1291 case IPPROTO_DCCP:
1292 cmn_err(CE_NOTE, "ipcl_bind_insert_v4");
1293 ASSERT(connp->conn_zoneid != ALL_ZONES);
1294 connfp = &ipst->ips_ipcl_dccp_fanout[
1295 IPCL_DCCP_HASH(lport, ipst)];
1296 if (connp->conn_laddr_v4 != INADDR_ANY) {
1297 IPCL_HASH_INSERT_BOUND(connfp, connp);
1298 } else {
1299 IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1300 }
1301 /* XXX:DCCP */
1302 break;
1303 }
1304
1305
1306 return (ret);
1307 }
1308
1309 int
1310 ipcl_bind_insert_v6(conn_t *connp)
1311 {
1312 connf_t *connfp;
1313 int ret = 0;
1314 ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
1315 uint16_t lport = connp->conn_lport;
1316 uint8_t protocol = connp->conn_proto;
1317
1318 if (IPCL_IS_IPTUN(connp)) {
1319 return (ipcl_iptun_hash_insert_v6(connp, ipst));
1320 }
1321
1322 switch (protocol) {
1323 default:
1324 if (is_system_labeled() &&
1325 check_exempt_conflict_v6(connp, ipst))
1357 uint8_t *laddrp;
1358
1359 if (connp->conn_ipversion == IPV6_VERSION) {
1360 addr_family = AF_INET6;
1361 laddrp =
1362 (uint8_t *)&connp->conn_bound_addr_v6;
1363 } else {
1364 addr_family = AF_INET;
1365 laddrp = (uint8_t *)&connp->conn_bound_addr_v4;
1366 }
1367 connp->conn_flags |= IPCL_CL_LISTENER;
1368 (*cl_inet_listen)(
1369 connp->conn_netstack->netstack_stackid,
1370 IPPROTO_TCP, addr_family, laddrp, lport, NULL);
1371 }
1372 break;
1373
1374 case IPPROTO_SCTP:
1375 ret = ipcl_sctp_hash_insert(connp, lport);
1376 break;
1377
1378 case IPPROTO_DCCP:
1379 /* XXX:DCCP */
1380 break;
1381 }
1382
1383 return (ret);
1384 }
1385
1386 /*
1387 * ipcl_conn_hash insertion routines.
1388 * The caller has already set conn_proto and the addresses/ports in the conn_t.
1389 */
1390
1391 int
1392 ipcl_conn_insert(conn_t *connp)
1393 {
1394 if (connp->conn_ipversion == IPV6_VERSION)
1395 return (ipcl_conn_insert_v6(connp));
1396 else
1397 return (ipcl_conn_insert_v4(connp));
1398 }
1399
1400 int
1445 IPCL_HASH_REMOVE(connp);
1446 mutex_enter(&connfp->connf_lock);
1447 }
1448
1449 ASSERT(connp->conn_recv != NULL);
1450 ASSERT(connp->conn_recvicmp != NULL);
1451
1452 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1453 mutex_exit(&connfp->connf_lock);
1454 break;
1455
1456 case IPPROTO_SCTP:
1457 /*
1458 * The raw socket may have already been bound, remove it
1459 * from the hash first.
1460 */
1461 IPCL_HASH_REMOVE(connp);
1462 ret = ipcl_sctp_hash_insert(connp, lport);
1463 break;
1464
1465 case IPPROTO_DCCP:
1466 cmn_err(CE_NOTE, "insert v4");
1467
1468 connfp = &ipst->ips_ipcl_conn_fanout[
1469 IPCL_CONN_HASH(connp->conn_faddr_v4,
1470 connp->conn_ports, ipst)];
1471 mutex_enter(&connfp->connf_lock);
1472 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1473 mutex_exit(&connfp->connf_lock);
1474 /* XXX:DCCP */
1475 break;
1476
1477 default:
1478 /*
1479 * Check for conflicts among MAC exempt bindings. For
1480 * transports with port numbers, this is done by the upper
1481 * level per-transport binding logic. For all others, it's
1482 * done here.
1483 */
1484 if (is_system_labeled() &&
1485 check_exempt_conflict_v4(connp, ipst))
1486 return (EADDRINUSE);
1487 /* FALLTHROUGH */
1488
1489 case IPPROTO_UDP:
1490 if (protocol == IPPROTO_UDP) {
1491 connfp = &ipst->ips_ipcl_udp_fanout[
1492 IPCL_UDP_HASH(lport, ipst)];
1493 } else {
1494 connfp = &ipst->ips_ipcl_proto_fanout_v4[protocol];
1495 }
1496
1552 }
1553 }
1554 if (connp->conn_fanout != NULL) {
1555 /*
1556 * Probably a XTI/TLI application trying to do a
1557 * rebind. Let it happen.
1558 */
1559 mutex_exit(&connfp->connf_lock);
1560 IPCL_HASH_REMOVE(connp);
1561 mutex_enter(&connfp->connf_lock);
1562 }
1563 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1564 mutex_exit(&connfp->connf_lock);
1565 break;
1566
1567 case IPPROTO_SCTP:
1568 IPCL_HASH_REMOVE(connp);
1569 ret = ipcl_sctp_hash_insert(connp, lport);
1570 break;
1571
1572 case IPPROTO_DCCP:
1573 /* XXX:DCCP */
1574 break;
1575
1576 default:
1577 if (is_system_labeled() &&
1578 check_exempt_conflict_v6(connp, ipst))
1579 return (EADDRINUSE);
1580 /* FALLTHROUGH */
1581 case IPPROTO_UDP:
1582 if (protocol == IPPROTO_UDP) {
1583 connfp = &ipst->ips_ipcl_udp_fanout[
1584 IPCL_UDP_HASH(lport, ipst)];
1585 } else {
1586 connfp = &ipst->ips_ipcl_proto_fanout_v6[protocol];
1587 }
1588
1589 if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) {
1590 IPCL_HASH_INSERT_CONNECTED(connfp, connp);
1591 } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1592 IPCL_HASH_INSERT_BOUND(connfp, connp);
1593 } else {
1594 IPCL_HASH_INSERT_WILDCARD(connfp, connp);
1595 }
1723 ira, connp)) {
1724 DTRACE_PROBE3(tx__ip__log__info__classify__udp,
1725 char *, "connp(1) could not receive mp(2)",
1726 conn_t *, connp, mblk_t *, mp);
1727 connp = NULL;
1728 }
1729
1730 if (connp != NULL) {
1731 CONN_INC_REF(connp);
1732 mutex_exit(&connfp->connf_lock);
1733 return (connp);
1734 }
1735
1736 /*
1737 * We shouldn't come here for multicast/broadcast packets
1738 */
1739 mutex_exit(&connfp->connf_lock);
1740
1741 break;
1742
1743 case IPPROTO_DCCP:
1744 fport = up[0];
1745 lport = up[1];
1746 connfp = &ipst->ips_ipcl_dccp_fanout[IPCL_DCCP_HASH(
1747 lport, ipst)];
1748 mutex_enter(&connfp->connf_lock);
1749 for (connp = connfp->connf_head; connp != NULL;
1750 connp = connp->conn_next) {
1751 cmn_err(CE_NOTE, "connfp found");
1752 /* XXX:DCCP */
1753 if (IPCL_UDP_MATCH(connp, lport, ipha->ipha_dst,
1754 fport, ipha->ipha_src)) {
1755 break;
1756 }
1757 }
1758
1759 if (connp != NULL) {
1760 CONN_INC_REF(connp);
1761 mutex_exit(&connfp->connf_lock);
1762 return (connp);
1763 }
1764
1765 mutex_exit(&connfp->connf_lock);
1766 break;
1767
1768 case IPPROTO_ENCAP:
1769 case IPPROTO_IPV6:
1770 return (ipcl_iptun_classify_v4(&ipha->ipha_src,
1771 &ipha->ipha_dst, ipst));
1772 }
1773
1774 return (NULL);
1775 }
1776
1777 conn_t *
1778 ipcl_classify_v6(mblk_t *mp, uint8_t protocol, uint_t hdr_len,
1779 ip_recv_attr_t *ira, ip_stack_t *ipst)
1780 {
1781 ip6_t *ip6h;
1782 connf_t *connfp, *bind_connfp;
1783 uint16_t lport;
1784 uint16_t fport;
1785 tcpha_t *tcpha;
1786 uint32_t ports;
1787 conn_t *connp;
2268 itc_t *itc = (itc_t *)buf;
2269 conn_t *connp = &itc->itc_conn;
2270 rts_t *rts = (rts_t *)&itc[1];
2271
2272 ASSERT(connp->conn_flags & IPCL_RTSCONN);
2273 ASSERT(rts->rts_connp == connp);
2274 ASSERT(connp->conn_rts == rts);
2275 mutex_destroy(&connp->conn_lock);
2276 cv_destroy(&connp->conn_cv);
2277 rw_destroy(&connp->conn_ilg_lock);
2278
2279 /* Can be NULL if constructor failed */
2280 if (connp->conn_ixa != NULL) {
2281 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2282 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2283 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2284 ixa_refrele(connp->conn_ixa);
2285 }
2286 }
2287
2288 /* ARGSUSED */
2289 static int
2290 dccp_conn_constructor(void *buf, void *cdrarg, int kmflags)
2291 {
2292 itc_t *itc = (itc_t *)buf;
2293 conn_t *connp = &itc->itc_conn;
2294 dccp_t *dccp = (dccp_t *)&itc[1];
2295
2296 bzero(connp, sizeof (conn_t));
2297 bzero(dccp, sizeof (dccp_t));
2298
2299 mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL);
2300 cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL);
2301 rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL);
2302
2303 connp->conn_dccp = dccp;
2304 connp->conn_flags = IPCL_DCCPCONN;
2305 connp->conn_proto = IPPROTO_DCCP;
2306 dccp->dccp_connp = connp;
2307 connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags);
2308 if (connp->conn_ixa == NULL)
2309 return (NULL);
2310 connp->conn_ixa->ixa_refcnt = 1;
2311 connp->conn_ixa->ixa_protocol = connp->conn_proto;
2312 connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp);
2313
2314 return (0);
2315 }
2316
2317 /* ARGSUSED */
2318 static void
2319 dccp_conn_destructor(void *buf, void *cdrarg)
2320 {
2321 itc_t *itc = (itc_t *)buf;
2322 conn_t *connp = &itc->itc_conn;
2323 dccp_t *dccp = (dccp_t *)&itc[1];
2324
2325 ASSERT(connp->conn_flags & IPCL_DCCPCONN);
2326 ASSERT(dccp->dccp_connp == connp);
2327 ASSERT(connp->conn_dccp == dccp);
2328
2329 mutex_destroy(&connp->conn_lock);
2330 cv_destroy(&connp->conn_cv);
2331 rw_destroy(&connp->conn_ilg_lock);
2332
2333 if (connp->conn_ixa != NULL) {
2334 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2335 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2336 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2337
2338 ixa_refrele(connp->conn_ixa);
2339 }
2340 }
2341
2342 /*
2343 * Called as part of ipcl_conn_destroy to assert and clear any pointers
2344 * in the conn_t.
2345 *
2346 * Below we list all the pointers in the conn_t as a documentation aid.
2347 * The ones that we can not ASSERT to be NULL are #ifdef'ed out.
2348 * If you add any pointers to the conn_t please add an ASSERT here
2349 * and #ifdef it out if it can't be actually asserted to be NULL.
2350 * In any case, we bzero most of the conn_t at the end of the function.
2351 */
2352 void
2353 ipcl_conn_cleanup(conn_t *connp)
2354 {
2355 ip_xmit_attr_t *ixa;
2356
2357 ASSERT(connp->conn_latch == NULL);
2358 ASSERT(connp->conn_latch_in_policy == NULL);
2359 ASSERT(connp->conn_latch_in_action == NULL);
2360 #ifdef notdef
2361 ASSERT(connp->conn_rq == NULL);
|