Print this page
%B

*** 221,230 **** --- 221,231 ---- * IPCL_TCPCONN indicates a TCP connection * IPCL_SCTPCONN indicates a SCTP connection * IPCL_UDPCONN indicates a UDP conn_t. * IPCL_RAWIPCONN indicates a RAWIP/ICMP conn_t. * IPCL_RTSCONN indicates a RTS conn_t. + * IPCL_DCCPCONN indicates a DCCP conn_t. * IPCL_IPCCONN indicates all other connections. * * void ipcl_conn_destroy(connp) * * Destroys the connection state, removes it from the global
*** 255,264 **** --- 256,266 ---- #include <inet/ip_ire.h> #include <inet/ip6.h> #include <inet/ip_ndp.h> #include <inet/ip_impl.h> #include <inet/udp_impl.h> + #include <inet/dccp/dccp_impl.h> #include <inet/sctp_ip.h> #include <inet/sctp/sctp_impl.h> #include <inet/rawip_impl.h> #include <inet/rts_impl.h> #include <inet/iptun/iptun_impl.h>
*** 278,289 **** /* New value. Zero means choose automatically. Setable in /etc/system */ uint_t ipcl_conn_hash_size = 0; uint_t ipcl_conn_hash_memfactor = 8192; uint_t ipcl_conn_hash_maxsize = 82500; ! /* bind/udp fanout table size */ uint_t ipcl_bind_fanout_size = 512; uint_t ipcl_udp_fanout_size = 16384; /* Raw socket fanout size. Must be a power of 2. */ uint_t ipcl_raw_fanout_size = 256; --- 280,292 ---- /* New value. Zero means choose automatically. Setable in /etc/system */ uint_t ipcl_conn_hash_size = 0; uint_t ipcl_conn_hash_memfactor = 8192; uint_t ipcl_conn_hash_maxsize = 82500; ! /* bind/dccp/udp fanout table size */ uint_t ipcl_bind_fanout_size = 512; + uint_t ipcl_dccp_fanout_size = 512; uint_t ipcl_udp_fanout_size = 16384; /* Raw socket fanout size. Must be a power of 2. */ uint_t ipcl_raw_fanout_size = 256;
*** 317,326 **** --- 320,330 ---- struct kmem_cache *ip_conn_cache; extern struct kmem_cache *sctp_conn_cache; struct kmem_cache *udp_conn_cache; struct kmem_cache *rawip_conn_cache; struct kmem_cache *rts_conn_cache; + struct kmem_cache *dccp_conn_cache; extern void tcp_timermp_free(tcp_t *); extern mblk_t *tcp_timermp_alloc(int); static int ip_conn_constructor(void *, void *, int);
*** 336,345 **** --- 340,352 ---- static void rawip_conn_destructor(void *, void *); static int rts_conn_constructor(void *, void *, int); static void rts_conn_destructor(void *, void *); + static int dccp_conn_constructor(void *, void *, int); + static void dccp_conn_destructor(void *, void *); + /* * Global (for all stack instances) init routine */ void ipcl_g_init(void)
*** 366,375 **** --- 373,388 ---- rts_conn_cache = kmem_cache_create("rts_conn_cache", sizeof (itc_t) + sizeof (rts_t), CACHE_ALIGN_SIZE, rts_conn_constructor, rts_conn_destructor, NULL, NULL, NULL, 0); + + /* XXX:DCCP reclaim */ + dccp_conn_cache = kmem_cache_create("dccp_conn_cache", + sizeof (itc_t) + sizeof (dccp_t), CACHE_ALIGN_SIZE, + dccp_conn_constructor, dccp_conn_destructor, + NULL, NULL, NULL, 0); } /* * ipclassifier intialization routine, sets up hash tables. */
*** 408,417 **** --- 421,431 ---- ipst->ips_ipcl_conn_fanout_size = sizes[16]; } /* Take values from /etc/system */ ipst->ips_ipcl_bind_fanout_size = ipcl_bind_fanout_size; + ipst->ips_ipcl_dccp_fanout_size = ipcl_dccp_fanout_size; ipst->ips_ipcl_udp_fanout_size = ipcl_udp_fanout_size; ipst->ips_ipcl_raw_fanout_size = ipcl_raw_fanout_size; ipst->ips_ipcl_iptun_fanout_size = ipcl_iptun_fanout_size; ASSERT(ipst->ips_ipcl_conn_fanout == NULL);
*** 475,494 **** --- 489,516 ---- sizeof (connf_t) * CONN_G_HASH_SIZE, KM_SLEEP); for (i = 0; i < CONN_G_HASH_SIZE; i++) { mutex_init(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock, NULL, MUTEX_DEFAULT, NULL); } + + ipst->ips_ipcl_dccp_fanout = kmem_zalloc( + ipst->ips_ipcl_dccp_fanout_size * sizeof (connf_t), KM_SLEEP); + for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) { + mutex_init(&ipst->ips_ipcl_dccp_fanout[i].connf_lock, NULL, + MUTEX_DEFAULT, NULL); + } } void ipcl_g_destroy(void) { kmem_cache_destroy(ip_conn_cache); kmem_cache_destroy(tcp_conn_cache); kmem_cache_destroy(udp_conn_cache); kmem_cache_destroy(rawip_conn_cache); kmem_cache_destroy(rts_conn_cache); + kmem_cache_destroy(dccp_conn_cache); } /* * All user-level and kernel use of the stack must be gone * by now.
*** 560,569 **** --- 582,599 ---- } kmem_free(ipst->ips_ipcl_globalhash_fanout, sizeof (connf_t) * CONN_G_HASH_SIZE); ipst->ips_ipcl_globalhash_fanout = NULL; + for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) { + ASSERT(ipst->ips_ipcl_dccp_fanout[i].connf_head == NULL); + mutex_destroy(&ipst->ips_ipcl_dccp_fanout[i].connf_lock); + } + kmem_free(ipst->ips_ipcl_dccp_fanout, ipst->ips_ipcl_dccp_fanout_size * + sizeof (connf_t)); + ipst->ips_ipcl_dccp_fanout = NULL; + ASSERT(ipst->ips_rts_clients->connf_head == NULL); mutex_destroy(&ipst->ips_rts_clients->connf_lock); kmem_free(ipst->ips_rts_clients, sizeof (connf_t)); ipst->ips_rts_clients = NULL; }
*** 608,617 **** --- 638,651 ---- case IPCL_IPCCONN: conn_cache = ip_conn_cache; break; + case IPCL_DCCPCONN: + conn_cache = dccp_conn_cache; + break; + default: connp = NULL; ASSERT(0); }
*** 718,727 **** --- 752,778 ---- ASSERT(ns != NULL); sctp_free(connp); return; } + if (connp->conn_flags & IPCL_DCCPCONN) { + dccp_t *dccp = connp->conn_dccp; + + cmn_err(CE_NOTE, "ipclassifier: conn_flags DCCP cache_free"); + + /* XXX:DCCP */ + /* Crash bug here: udp_conn_cache and dccp_conn_cache */ + /* + ipcl_conn_cleanup(connp); + connp->conn_flags = IPCL_DCCPCONN; + bzero(dccp, sizeof (dccp_t)); + dccp->dccp_connp = connp; + kmem_cache_free(dccp_conn_cache, connp); + return; + */ + } + ipcl_conn_cleanup(connp); if (ns != NULL) { connp->conn_netstack = NULL; connp->conn_ixa->ixa_ipst = NULL; netstack_rele(ns);
*** 1234,1245 **** --- 1285,1310 ---- break; case IPPROTO_SCTP: ret = ipcl_sctp_hash_insert(connp, lport); break; + + case IPPROTO_DCCP: + cmn_err(CE_NOTE, "ipcl_bind_insert_v4"); + ASSERT(connp->conn_zoneid != ALL_ZONES); + connfp = &ipst->ips_ipcl_dccp_fanout[ + IPCL_DCCP_HASH(lport, ipst)]; + if (connp->conn_laddr_v4 != INADDR_ANY) { + IPCL_HASH_INSERT_BOUND(connfp, connp); + } else { + IPCL_HASH_INSERT_WILDCARD(connfp, connp); + } + /* XXX:DCCP */ + break; } + return (ret); } int ipcl_bind_insert_v6(conn_t *connp)
*** 1307,1316 **** --- 1372,1385 ---- break; case IPPROTO_SCTP: ret = ipcl_sctp_hash_insert(connp, lport); break; + + case IPPROTO_DCCP: + /* XXX:DCCP */ + break; } return (ret); }
*** 1391,1400 **** --- 1460,1481 ---- */ IPCL_HASH_REMOVE(connp); ret = ipcl_sctp_hash_insert(connp, lport); break; + case IPPROTO_DCCP: + cmn_err(CE_NOTE, "insert v4"); + + connfp = &ipst->ips_ipcl_conn_fanout[ + IPCL_CONN_HASH(connp->conn_faddr_v4, + connp->conn_ports, ipst)]; + mutex_enter(&connfp->connf_lock); + IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp); + mutex_exit(&connfp->connf_lock); + /* XXX:DCCP */ + break; + default: /* * Check for conflicts among MAC exempt bindings. For * transports with port numbers, this is done by the upper * level per-transport binding logic. For all others, it's
*** 1486,1495 **** --- 1567,1580 ---- case IPPROTO_SCTP: IPCL_HASH_REMOVE(connp); ret = ipcl_sctp_hash_insert(connp, lport); break; + case IPPROTO_DCCP: + /* XXX:DCCP */ + break; + default: if (is_system_labeled() && check_exempt_conflict_v6(connp, ipst)) return (EADDRINUSE); /* FALLTHROUGH */
*** 1653,1662 **** --- 1738,1772 ---- */ mutex_exit(&connfp->connf_lock); break; + case IPPROTO_DCCP: + fport = up[0]; + lport = up[1]; + connfp = &ipst->ips_ipcl_dccp_fanout[IPCL_DCCP_HASH( + lport, ipst)]; + mutex_enter(&connfp->connf_lock); + for (connp = connfp->connf_head; connp != NULL; + connp = connp->conn_next) { + cmn_err(CE_NOTE, "connfp found"); + /* XXX:DCCP */ + if (IPCL_UDP_MATCH(connp, lport, ipha->ipha_dst, + fport, ipha->ipha_src)) { + break; + } + } + + if (connp != NULL) { + CONN_INC_REF(connp); + mutex_exit(&connfp->connf_lock); + return (connp); + } + + mutex_exit(&connfp->connf_lock); + break; + case IPPROTO_ENCAP: case IPPROTO_IPV6: return (ipcl_iptun_classify_v4(&ipha->ipha_src, &ipha->ipha_dst, ipst)); }
*** 2173,2182 **** --- 2283,2346 ---- ASSERT(connp->conn_ixa->ixa_nce == NULL); ixa_refrele(connp->conn_ixa); } } + /* ARGSUSED */ + static int + dccp_conn_constructor(void *buf, void *cdrarg, int kmflags) + { + itc_t *itc = (itc_t *)buf; + conn_t *connp = &itc->itc_conn; + dccp_t *dccp = (dccp_t *)&itc[1]; + + bzero(connp, sizeof (conn_t)); + bzero(dccp, sizeof (dccp_t)); + + mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL); + rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL); + + connp->conn_dccp = dccp; + connp->conn_flags = IPCL_DCCPCONN; + connp->conn_proto = IPPROTO_DCCP; + dccp->dccp_connp = connp; + connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags); + if (connp->conn_ixa == NULL) + return (NULL); + connp->conn_ixa->ixa_refcnt = 1; + connp->conn_ixa->ixa_protocol = connp->conn_proto; + connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp); + + return (0); + } + + /* ARGSUSED */ + static void + dccp_conn_destructor(void *buf, void *cdrarg) + { + itc_t *itc = (itc_t *)buf; + conn_t *connp = &itc->itc_conn; + dccp_t *dccp = (dccp_t *)&itc[1]; + + ASSERT(connp->conn_flags & IPCL_DCCPCONN); + ASSERT(dccp->dccp_connp == connp); + ASSERT(connp->conn_dccp == dccp); + + mutex_destroy(&connp->conn_lock); + cv_destroy(&connp->conn_cv); + rw_destroy(&connp->conn_ilg_lock); + + if (connp->conn_ixa != NULL) { + ASSERT(connp->conn_ixa->ixa_refcnt == 1); + ASSERT(connp->conn_ixa->ixa_ire == NULL); + ASSERT(connp->conn_ixa->ixa_nce == NULL); + + ixa_refrele(connp->conn_ixa); + } + } + /* * Called as part of ipcl_conn_destroy to assert and clear any pointers * in the conn_t. * * Below we list all the pointers in the conn_t as a documentation aid.