Print this page
dccp: conn_t


 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, "ipclassifier.c: ipcl_conn_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 
1473                 IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
1474                 mutex_exit(&connfp->connf_lock);
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         }
2311         connp->conn_ixa->ixa_refcnt = 1;
2312         connp->conn_ixa->ixa_protocol = connp->conn_proto;
2313         connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp);
2314 
2315         return (0);
2316 }
2317 
2318 /* ARGSUSED */
2319 static void
2320 dccp_conn_destructor(void *buf, void *cdrarg)
2321 {
2322         itc_t   *itc = (itc_t *)buf;
2323         conn_t  *connp = &itc->itc_conn;
2324         dccp_t  *dccp = (dccp_t *)&itc[1];
2325 
2326         ASSERT(connp->conn_flags & IPCL_DCCPCONN);
2327         ASSERT(dccp->dccp_connp == connp);
2328         ASSERT(connp->conn_dccp == dccp);
2329 
2330         mutex_destroy(&connp->conn_lock);
2331         cv_destroy(&connp->conn_cv);
2332         rw_destroy(&connp->conn_ilg_lock);
2333 
2334         if (connp->conn_ixa != NULL) {
2335                 ASSERT(connp->conn_ixa->ixa_refcnt == 1);
2336                 ASSERT(connp->conn_ixa->ixa_ire == NULL);
2337                 ASSERT(connp->conn_ixa->ixa_nce == NULL);
2338 
2339                 ixa_refrele(connp->conn_ixa);
2340         }
2341 }
2342 
2343 /*
2344  * Called as part of ipcl_conn_destroy to assert and clear any pointers
2345  * in the conn_t.
2346  *
2347  * Below we list all the pointers in the conn_t as a documentation aid.
2348  * The ones that we can not ASSERT to be NULL are #ifdef'ed out.
2349  * If you add any pointers to the conn_t please add an ASSERT here
2350  * and #ifdef it out if it can't be actually asserted to be NULL.
2351  * In any case, we bzero most of the conn_t at the end of the function.
2352  */
2353 void
2354 ipcl_conn_cleanup(conn_t *connp)
2355 {
2356         ip_xmit_attr_t  *ixa;
2357 
2358         ASSERT(connp->conn_latch == NULL);
2359         ASSERT(connp->conn_latch_in_policy == NULL);
2360         ASSERT(connp->conn_latch_in_action == NULL);
2361 #ifdef notdef
2362         ASSERT(connp->conn_rq == NULL);