17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f4b3ec61Sdh155122 * Common Development and Distribution License (the "License"). 6f4b3ec61Sdh155122 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d3d50737SRafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _INET_NCA_H 277c478bd9Sstevel@tonic-gate #define _INET_NCA_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #ifdef __cplusplus 307c478bd9Sstevel@tonic-gate extern "C" { 317c478bd9Sstevel@tonic-gate #endif 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <sys/thread.h> 347c478bd9Sstevel@tonic-gate #include <sys/door.h> 357c478bd9Sstevel@tonic-gate #include <sys/disp.h> 367c478bd9Sstevel@tonic-gate #include <sys/systm.h> 377c478bd9Sstevel@tonic-gate #include <sys/processor.h> 387c478bd9Sstevel@tonic-gate #include <sys/socket.h> 397c478bd9Sstevel@tonic-gate #include <inet/common.h> 407c478bd9Sstevel@tonic-gate #include <inet/ip.h> 417c478bd9Sstevel@tonic-gate #include <inet/tcp.h> 427c478bd9Sstevel@tonic-gate #include <inet/nca/ncadoorhdr.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 457c478bd9Sstevel@tonic-gate * The NCA debugging facilities provided via ADB and MDB depend on a 467c478bd9Sstevel@tonic-gate * number of NCA implementation details. In particular, note that: 477c478bd9Sstevel@tonic-gate * 487c478bd9Sstevel@tonic-gate * * ADB macros *must* be revised whenever members are added or 497c478bd9Sstevel@tonic-gate * removed from the following structures: 507c478bd9Sstevel@tonic-gate * 517c478bd9Sstevel@tonic-gate * nca_conn_t connf_t nca_cpu_t dcb_t hcb_t nca_if_t nca_io2_t 527c478bd9Sstevel@tonic-gate * node_t nodef_t sqfan_t nca_squeue_t tb_t te_t ti_t tw_t 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * * ADB macros should be added when new core data structures are 557c478bd9Sstevel@tonic-gate * added to NCA. Generally, if you had to put it in here, you 567c478bd9Sstevel@tonic-gate * need to write a macro for it. 577c478bd9Sstevel@tonic-gate * 587c478bd9Sstevel@tonic-gate * * MDB has many dependencies on the way core data structures 597c478bd9Sstevel@tonic-gate * are connected. In general, if you break these dependencies, 607c478bd9Sstevel@tonic-gate * the MDB NCA module will fail to build. However, breakage 617c478bd9Sstevel@tonic-gate * may go undetected (for instance, changing a linked list 627c478bd9Sstevel@tonic-gate * into a circularly linked list). If you have any doubts, 637c478bd9Sstevel@tonic-gate * inspect the NCA module source before committing your changes. 647c478bd9Sstevel@tonic-gate * 657c478bd9Sstevel@tonic-gate * * MDB depends on the following variables (and their current 667c478bd9Sstevel@tonic-gate * semantics) in order to function correctly: 677c478bd9Sstevel@tonic-gate * 687c478bd9Sstevel@tonic-gate * nca_conn_fanout nca_conn_fanout_size nca_gv nca_lru 697c478bd9Sstevel@tonic-gate * urihash filehash 707c478bd9Sstevel@tonic-gate * 717c478bd9Sstevel@tonic-gate * If you change the names or *semantics* of these variables, 727c478bd9Sstevel@tonic-gate * you must modify the MDB module accordingly. 737c478bd9Sstevel@tonic-gate * 747c478bd9Sstevel@tonic-gate * In addition, you should consider whether the changes you've 757c478bd9Sstevel@tonic-gate * made should be reflected in the MDB dcmds themselves. 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* The queue to make upcall on for NCAfs */ 797c478bd9Sstevel@tonic-gate extern queue_t *ncaupcallq; 807c478bd9Sstevel@tonic-gate extern kmutex_t ncaupcallq_lock; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate extern int nca_logging_on; 837c478bd9Sstevel@tonic-gate extern int nca_conn_fanout_size; 847c478bd9Sstevel@tonic-gate extern boolean_t nca_deferred_oq_if; 857c478bd9Sstevel@tonic-gate extern boolean_t nca_fanout_iq_if; 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /* Checksum pointer for no checksum */ 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate #define NO_CKSUM (void *)-1 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate /* undef any tcp.h:tcp_t members overloaded by the Solaris 8 tcp.h */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate #undef tcp_last_rcv_lbolt 947c478bd9Sstevel@tonic-gate #undef tcp_state 957c478bd9Sstevel@tonic-gate #undef tcp_rto 967c478bd9Sstevel@tonic-gate #undef tcp_snd_ts_ok 977c478bd9Sstevel@tonic-gate #undef tcp_snd_ws_ok 987c478bd9Sstevel@tonic-gate #undef tcp_snxt 997c478bd9Sstevel@tonic-gate #undef tcp_swnd 1007c478bd9Sstevel@tonic-gate #undef tcp_mss 1017c478bd9Sstevel@tonic-gate #undef tcp_iss 1027c478bd9Sstevel@tonic-gate #undef tcp_rnxt 1037c478bd9Sstevel@tonic-gate #undef tcp_rwnd 1047c478bd9Sstevel@tonic-gate #undef tcp_lport 1057c478bd9Sstevel@tonic-gate #undef tcp_fport 1067c478bd9Sstevel@tonic-gate #undef tcp_ports 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate /* the iph_t is no longer defined in ip.h for Solaris 8 ? */ 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* Unaligned IP header */ 1117c478bd9Sstevel@tonic-gate typedef struct iph_s { 1127c478bd9Sstevel@tonic-gate uchar_t iph_version_and_hdr_length; 1137c478bd9Sstevel@tonic-gate uchar_t iph_type_of_service; 1147c478bd9Sstevel@tonic-gate uchar_t iph_length[2]; 1157c478bd9Sstevel@tonic-gate uchar_t iph_ident[2]; 1167c478bd9Sstevel@tonic-gate uchar_t iph_fragment_offset_and_flags[2]; 1177c478bd9Sstevel@tonic-gate uchar_t iph_ttl; 1187c478bd9Sstevel@tonic-gate uchar_t iph_protocol; 1197c478bd9Sstevel@tonic-gate uchar_t iph_hdr_checksum[2]; 1207c478bd9Sstevel@tonic-gate uchar_t iph_src[4]; 1217c478bd9Sstevel@tonic-gate uchar_t iph_dst[4]; 1227c478bd9Sstevel@tonic-gate } iph_t; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate #define true B_TRUE /* used with type boolean_t */ 1267c478bd9Sstevel@tonic-gate #define false B_FALSE /* used with type boolean_t */ 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * Power of 2^N Primes useful for hashing for N of 0-28, 1307c478bd9Sstevel@tonic-gate * these primes are the nearest prime <= 2^N - 2^(N-2). 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate #define P2Ps() {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 761, 1531, 3067, \ 1347c478bd9Sstevel@tonic-gate 6143, 12281, 24571, 49139, 98299, 196597, 393209, \ 1357c478bd9Sstevel@tonic-gate 786431, 1572853, 3145721, 6291449, 12582893, 25165813, \ 1367c478bd9Sstevel@tonic-gate 50331599, 100663291, 201326557, 0} 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * Serialization queue type (move to strsubr.h (stream.h?) as a general 1407c478bd9Sstevel@tonic-gate * purpose lightweight mechanism for mblk_t serialization ?). 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate typedef struct nca_squeue_s { 1437c478bd9Sstevel@tonic-gate uint16_t sq_state; /* state flags */ 1447c478bd9Sstevel@tonic-gate uint16_t sq_count; /* message count */ 1457c478bd9Sstevel@tonic-gate uint32_t sq_type; /* type flags */ 1467c478bd9Sstevel@tonic-gate processorid_t sq_bind; /* processor to bind to */ 1477c478bd9Sstevel@tonic-gate ddi_softintr_t sq_softid; /* softintr() id */ 1487c478bd9Sstevel@tonic-gate void (*sq_init)(); /* initialize function */ 1497c478bd9Sstevel@tonic-gate void *sq_init_arg; /* initialize argument */ 1507c478bd9Sstevel@tonic-gate void (*sq_proc)(); /* process function */ 1517c478bd9Sstevel@tonic-gate mblk_t *sq_first; /* first mblk chain or NULL */ 1527c478bd9Sstevel@tonic-gate mblk_t *sq_last; /* last mblk chain or NULL */ 1537c478bd9Sstevel@tonic-gate clock_t sq_wait; /* lbolts to wait after a fill() */ 1547c478bd9Sstevel@tonic-gate clock_t sq_iwait; /* lbolt after nointr() */ 1557c478bd9Sstevel@tonic-gate clock_t sq_pwait; /* lbolt after pause() */ 1567c478bd9Sstevel@tonic-gate int sq_isintr; /* is being or was serviced by */ 1577c478bd9Sstevel@tonic-gate timeout_id_t sq_tid; /* timer id of pending timeout() */ 1587c478bd9Sstevel@tonic-gate kcondvar_t sq_async; /* async thread blocks on */ 1597c478bd9Sstevel@tonic-gate kmutex_t sq_lock; /* lock before using any member */ 1607c478bd9Sstevel@tonic-gate clock_t sq_awaken; /* time async thread was awakened */ 1617c478bd9Sstevel@tonic-gate void *sq_priv; /* user defined private */ 1627c478bd9Sstevel@tonic-gate kt_did_t sq_ktid; /* kernel thread id */ 1637c478bd9Sstevel@tonic-gate } nca_squeue_t; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* 1667c478bd9Sstevel@tonic-gate * State flags and message count (i.e. properties that change) 1677c478bd9Sstevel@tonic-gate * Note: The MDB NCA module depends on the values of these flags. 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate #define SQS_CNT_TOOMANY 0x8000 /* message count toomany */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* nca_squeue_t state flags now only 16 bits */ 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate #define SQS_PROC 0x0001 /* being processed */ 1757c478bd9Sstevel@tonic-gate #define SQS_WORKER 0x0002 /* worker thread */ 1767c478bd9Sstevel@tonic-gate #define SQS_ENTER 0x0004 /* enter thread */ 1777c478bd9Sstevel@tonic-gate #define SQS_FAST 0x0008 /* enter-fast thread */ 1787c478bd9Sstevel@tonic-gate #define SQS_PROXY 0x0010 /* proxy thread */ 1797c478bd9Sstevel@tonic-gate #define SQS_SOFTINTR 0x0020 /* softint thread */ 1807c478bd9Sstevel@tonic-gate /* 0x00C0 bits not used */ 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate #define SQS_NOINTR 0x0100 /* no interrupt processing */ 1837c478bd9Sstevel@tonic-gate #define SQS_PAUSE 0x0200 /* paused */ 1847c478bd9Sstevel@tonic-gate #define SQS_INTRWAIT 0x0400 /* interrupt waiting */ 1857c478bd9Sstevel@tonic-gate #define SQS_NOPROC 0x0800 /* no processing */ 1867c478bd9Sstevel@tonic-gate /* 0x7000 bits not used */ 1877c478bd9Sstevel@tonic-gate #define SQS_EXIT 0x8000 /* worker(s) exit */ 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /* 1907c478bd9Sstevel@tonic-gate * Type flags (i.e. properties that don't change). 1917c478bd9Sstevel@tonic-gate * Note: The MDB NCA module depends on the values of these flags. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate #define SQT_BIND_MASK 0xFF000000 /* bind flags mask */ 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate #define SQT_KMEM 0x00000001 /* was kmem_alloc()ed */ 1977c478bd9Sstevel@tonic-gate #define SQT_DEFERRED 0x00000002 /* deferred processing */ 1987c478bd9Sstevel@tonic-gate #define SQT_SOFTINTR 0x00000004 /* use softintr() */ 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate #define SQT_BIND_ANY 0x01000000 /* bind worker thread to any CPU */ 2017c478bd9Sstevel@tonic-gate #define SQT_BIND_TO 0x02000000 /* bind worker thread to speced CPU */ 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate #define SQ_STATE_IS(sqp, flags) ((sqp)->sq_state & (flags)) 2047c478bd9Sstevel@tonic-gate #define SQ_TYPE_IS(sqp, flags) ((sqp)->sq_type & (flags)) 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate typedef struct sqfan_s { 2087c478bd9Sstevel@tonic-gate uint32_t flg; /* flags only */ 2097c478bd9Sstevel@tonic-gate uint32_t cnt; /* vector count */ 2107c478bd9Sstevel@tonic-gate uint32_t ix; /* next sqv[] to process */ 2117c478bd9Sstevel@tonic-gate uint32_t drain; /* max mblk(s) draind per */ 2127c478bd9Sstevel@tonic-gate nca_squeue_t **sqv; /* pointer to nca_squeue_t pointer vector */ 2137c478bd9Sstevel@tonic-gate } sqfan_t; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate #define SQF_DIST_CNT 0x0001 /* sqfan_t dist by queue count */ 2167c478bd9Sstevel@tonic-gate #define SQF_DIST_IPv4 0x0002 /* sqfan_t dist by IPv4 src addr */ 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* 2197c478bd9Sstevel@tonic-gate * A multiphase timer is implemented using the te_t, tb_t, and ti_t structs. 2207c478bd9Sstevel@tonic-gate * 2217c478bd9Sstevel@tonic-gate * The multiple phases of timer entry execution are: 2227c478bd9Sstevel@tonic-gate * 2237c478bd9Sstevel@tonic-gate * 1) resource, execution is done from resource reclaim when the timer event 2247c478bd9Sstevel@tonic-gate * is the freeing of the timed resource. 2257c478bd9Sstevel@tonic-gate * 2267c478bd9Sstevel@tonic-gate * 2) process, execution is done from process thread yield (idle/return). 2277c478bd9Sstevel@tonic-gate * 2287c478bd9Sstevel@tonic-gate * 3) time, execution is done from a timeout callback thread. 2297c478bd9Sstevel@tonic-gate * 2307c478bd9Sstevel@tonic-gate * Each of the phases have a seperate timer fire time represented by the 2317c478bd9Sstevel@tonic-gate * the ti_t members lbolt1, lbolt2, and lbolt3. Each lbolt is an absolute 2327c478bd9Sstevel@tonic-gate * lbolt value with lbolt1 <= lbolt2 <= lbolt3. 2337c478bd9Sstevel@tonic-gate */ 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * te_t - timer entry. 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate typedef struct te_s { 2407c478bd9Sstevel@tonic-gate struct te_s *prev; /* prev te_t */ 2417c478bd9Sstevel@tonic-gate struct te_s *next; /* next te_t */ 2427c478bd9Sstevel@tonic-gate struct tb_s *tbp; /* pointer to timer bucket */ 2437c478bd9Sstevel@tonic-gate void *ep; /* pointer to encapsulating struct */ 2447c478bd9Sstevel@tonic-gate } te_t; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * tb_t - timer bucket. 2487c478bd9Sstevel@tonic-gate */ 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate typedef struct tb_s { 2517c478bd9Sstevel@tonic-gate struct tb_s *next; /* next tb_t in ascending time order */ 2527c478bd9Sstevel@tonic-gate clock_t exec; /* te_t lbolt exec value for bucket */ 2537c478bd9Sstevel@tonic-gate te_t *head; /* head of te_t list (first timer) */ 2547c478bd9Sstevel@tonic-gate te_t *tail; /* tail of te_t list (last timer) */ 2557c478bd9Sstevel@tonic-gate } tb_t; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* 2587c478bd9Sstevel@tonic-gate * ti_t - timer state. 2597c478bd9Sstevel@tonic-gate */ 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate typedef struct ti_s { 2627c478bd9Sstevel@tonic-gate clock_t exec; /* next te_t exec value (0 = NONE) */ 2637c478bd9Sstevel@tonic-gate clock_t lbolt1; /* phase1 lbolt1 (0 = NONE) */ 2647c478bd9Sstevel@tonic-gate clock_t lbolt2; /* phase2 lbolt2 (0 = NONE) */ 2657c478bd9Sstevel@tonic-gate clock_t lbolt3; /* phase3 lbolt3 (0 = NONE) */ 2667c478bd9Sstevel@tonic-gate tb_t *head; /* head of tb_t list (first timer bucket) */ 2677c478bd9Sstevel@tonic-gate tb_t *tail; /* tail of tb_t list (last timer bucket) */ 2687c478bd9Sstevel@tonic-gate timeout_id_t tid; /* timer id of pending timeout() (0 = NONE) */ 2697c478bd9Sstevel@tonic-gate void *ep; /* pointer to encapsulating struct */ 2707c478bd9Sstevel@tonic-gate } ti_t; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate #define NCA_TI_INPROC -1 /* Processing going on */ 2737c478bd9Sstevel@tonic-gate #define NCA_TI_NONE 0 /* no lbolt */ 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * TIME_WAIT grounded doubly linked list of nca_conn_t's awaiting TIME_WAIT 2777c478bd9Sstevel@tonic-gate * expiration for. This list is used for reclaim, reap, and timer based 2787c478bd9Sstevel@tonic-gate * processing. 2797c478bd9Sstevel@tonic-gate * 2807c478bd9Sstevel@tonic-gate * A multiphase timer is used: 2817c478bd9Sstevel@tonic-gate * 2827c478bd9Sstevel@tonic-gate * phase 1) reclaim of connections during connection allocation 2837c478bd9Sstevel@tonic-gate * 2847c478bd9Sstevel@tonic-gate * phase 2) reaping of connections during nca_squeue_t inq thread unwind 2857c478bd9Sstevel@tonic-gate * 2867c478bd9Sstevel@tonic-gate * phase 3) timeout of connections as a result of a timeout(). 2877c478bd9Sstevel@tonic-gate * 2887c478bd9Sstevel@tonic-gate * Each of the phases have a seperate timer fire lbolt represented by the 2897c478bd9Sstevel@tonic-gate * the members lbolt1, lbolt2, and lbolt3, each is an absolute lbolt value 2907c478bd9Sstevel@tonic-gate * with lbolt1 <= lbolt2 <= lbolt3. 2917c478bd9Sstevel@tonic-gate */ 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate typedef struct tw_s { 2947c478bd9Sstevel@tonic-gate clock_t lbolt1; /* phase1 lbolt value (0 = NONE) */ 2957c478bd9Sstevel@tonic-gate clock_t lbolt2; /* phase2 lbolt value */ 2967c478bd9Sstevel@tonic-gate clock_t lbolt3; /* phase3 lbolt value */ 2978793b36bSNick Todd struct nca_conn_s *head; /* Head of nca_conn_t list */ 2988793b36bSNick Todd struct nca_conn_s *tail; /* Tail of nca_conn_t list */ 2997c478bd9Sstevel@tonic-gate timeout_id_t tid; /* Timer id of pending timeout() (0 = NONE) */ 3007c478bd9Sstevel@tonic-gate void *ep; /* pointer to encapsulating struct */ 3017c478bd9Sstevel@tonic-gate } tw_t; 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate #define NCA_TW_NONE 0 /* no lbolt */ 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate #define NCA_TW_MS 1000 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate #define NCA_TW_LBOLT MSEC_TO_TICK(NCA_TW_MS) 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate #define NCA_TW_LBOLTS(twp, future) { \ 3107c478bd9Sstevel@tonic-gate clock_t _lbolt = (future); \ 3117c478bd9Sstevel@tonic-gate clock_t _mod = _lbolt % NCA_TW_LBOLT; \ 3127c478bd9Sstevel@tonic-gate \ 3137c478bd9Sstevel@tonic-gate if (_mod) { \ 3147c478bd9Sstevel@tonic-gate /* Roundup to next TIME_WAIT bucket */ \ 3157c478bd9Sstevel@tonic-gate _lbolt += NCA_TW_LBOLT - _mod; \ 3167c478bd9Sstevel@tonic-gate } \ 3177c478bd9Sstevel@tonic-gate if ((twp)->lbolt1 != _lbolt) { \ 3187c478bd9Sstevel@tonic-gate (twp)->lbolt1 = _lbolt; \ 3197c478bd9Sstevel@tonic-gate _lbolt += NCA_TW_LBOLT; \ 3207c478bd9Sstevel@tonic-gate (twp)->lbolt2 = _lbolt; \ 3217c478bd9Sstevel@tonic-gate _lbolt += NCA_TW_LBOLT; \ 3227c478bd9Sstevel@tonic-gate (twp)->lbolt3 = _lbolt; \ 3237c478bd9Sstevel@tonic-gate if ((twp)->tid != 0) { \ 3247c478bd9Sstevel@tonic-gate (void) untimeout((twp)->tid); \ 3257c478bd9Sstevel@tonic-gate (twp)->tid = 0; \ 3267c478bd9Sstevel@tonic-gate } \ 3277c478bd9Sstevel@tonic-gate if ((_lbolt) != NCA_TW_NONE) { \ 3287c478bd9Sstevel@tonic-gate (twp)->tid = timeout((pfv_t)nca_tw_fire, (twp), \ 329d3d50737SRafael Vanoni (twp)->lbolt3 - ddi_get_lbolt()); \ 3307c478bd9Sstevel@tonic-gate } \ 3317c478bd9Sstevel@tonic-gate } \ 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate /* 3357c478bd9Sstevel@tonic-gate * The Node Fanout structure. 3367c478bd9Sstevel@tonic-gate * 3377c478bd9Sstevel@tonic-gate * The hash tables and their linkage (hashnext) are protected by the 3387c478bd9Sstevel@tonic-gate * per-bucket lock. Each node_t inserted in the list points back at 3397c478bd9Sstevel@tonic-gate * the nodef_t that heads the bucket (hashfanout). 3407c478bd9Sstevel@tonic-gate */ 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate typedef struct nodef_s { 3437c478bd9Sstevel@tonic-gate struct node_s *head; 3447c478bd9Sstevel@tonic-gate kmutex_t lock; 3457c478bd9Sstevel@tonic-gate } nodef_t; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* 3487c478bd9Sstevel@tonic-gate * A node_t is used to represent a cached byte-stream object. A node_t is 3497c478bd9Sstevel@tonic-gate * in one of four active states: 3507c478bd9Sstevel@tonic-gate * 3517c478bd9Sstevel@tonic-gate * 1) path != NULL, member of a node_t hash list with an object description 3527c478bd9Sstevel@tonic-gate * (hashnext, size, path, pathsz members valid). 3537c478bd9Sstevel@tonic-gate * 3547c478bd9Sstevel@tonic-gate * 2) pp != NULL, 1) + phys pages allocated (pp, plrupn, plrunn members valid). 3557c478bd9Sstevel@tonic-gate * 3567c478bd9Sstevel@tonic-gate * 3) data != NULL, 2) + virt mapping allocated (data, datasz, vlrupn, vlrunn 3577c478bd9Sstevel@tonic-gate * members valid). 3587c478bd9Sstevel@tonic-gate * 3597c478bd9Sstevel@tonic-gate * 4) cksum != NULL 3) + checksum mapping allocated 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate typedef struct node_s { 3637c478bd9Sstevel@tonic-gate uint32_t ref; /* ref (see below) state */ 3647c478bd9Sstevel@tonic-gate uint32_t cnt; /* ref count */ 3657c478bd9Sstevel@tonic-gate int32_t size; /* object size (-1 = UNKNOWN) */ 3667c478bd9Sstevel@tonic-gate uint32_t mss; /* mblk(s) in size mss */ 3677c478bd9Sstevel@tonic-gate uint64_t ctag; /* usr defined cache tag, 0 => no tag */ 3687c478bd9Sstevel@tonic-gate ipaddr_t laddr; /* local IP, for virtual hosting */ 3697c478bd9Sstevel@tonic-gate uint16_t lport; /* local port, for virtual hosting */ 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate struct node_s *plrunn; /* Phys LRU list next node_t */ 3727c478bd9Sstevel@tonic-gate struct node_s *plrupn; /* Phys LRU list previous node_t */ 3737c478bd9Sstevel@tonic-gate struct node_s *vlrunn; /* Virt LRU list next node_t */ 3747c478bd9Sstevel@tonic-gate struct node_s *vlrupn; /* Virt LRU list previous node_t */ 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate nodef_t *hashfanout; /* hash bucket we're part of */ 3777c478bd9Sstevel@tonic-gate nodef_t *ctaghashfanout; /* ctaghash bucket we're part off */ 3787c478bd9Sstevel@tonic-gate struct node_s *hashnext; /* hash list next node_t */ 3797c478bd9Sstevel@tonic-gate struct node_s *ctaghashnext; /* ctaghash list next node_t */ 3808793b36bSNick Todd struct nca_conn_s *connhead; /* head of list of conn(s) in miss */ 3818793b36bSNick Todd struct nca_conn_s *conntail; /* tail of list of conn(s) in miss */ 3827c478bd9Sstevel@tonic-gate struct node_s *next; /* needed if data is in chunks */ 3837c478bd9Sstevel@tonic-gate struct node_s *back; /* needed if data is in chunks */ 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate clock_t expire; /* lbolt node_t expires (0 = NOW, -1 = NEVER) */ 3867c478bd9Sstevel@tonic-gate time_t lastmod; /* HTTP "Last-Modified:" value */ 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate mblk_t *req; /* whole HTTP request (including headers) */ 3897c478bd9Sstevel@tonic-gate int reqsz; /* size of above */ 3907c478bd9Sstevel@tonic-gate int reqcontl; /* HTTP "Content-Length:" value */ 3917c478bd9Sstevel@tonic-gate uint32_t rcv_cnt; /* rcv_list byte count */ 3927c478bd9Sstevel@tonic-gate mblk_t *rcv_head; /* rcv_list head */ 3937c478bd9Sstevel@tonic-gate mblk_t *rcv_tail; /* rcv_list tail */ 3947c478bd9Sstevel@tonic-gate mblk_t *rcv_ptr; /* rcv_list pointer */ 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate nca_squeue_t *sqp; /* squeue node_t is being processed from */ 3977c478bd9Sstevel@tonic-gate char *path; /* URI path component */ 3987c478bd9Sstevel@tonic-gate int pathsz; /* size of above */ 3997c478bd9Sstevel@tonic-gate uint_t method; /* HTTP request method */ 4007c478bd9Sstevel@tonic-gate uint_t version; /* HTTP request version */ 4017c478bd9Sstevel@tonic-gate char *reqhdr; /* HTTP request header(s) */ 4027c478bd9Sstevel@tonic-gate int reqhdrsz; /* size of above */ 4037c478bd9Sstevel@tonic-gate char *reqhost; /* HTTP "Host:" string */ 4047c478bd9Sstevel@tonic-gate int reqhostsz; /* size of above */ 4057c478bd9Sstevel@tonic-gate char *reqaccept; /* HTTP "Accept:" string */ 4067c478bd9Sstevel@tonic-gate int reqacceptsz; /* size of above */ 4077c478bd9Sstevel@tonic-gate char *reqacceptl; /* HTTP "Accept-Language:" string */ 4087c478bd9Sstevel@tonic-gate int reqacceptlsz; /* size of above */ 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate page_t **pp; /* page pointer vector for data */ 4117c478bd9Sstevel@tonic-gate char *data; /* data buffer */ 4127c478bd9Sstevel@tonic-gate int datasz; /* size of above */ 4137c478bd9Sstevel@tonic-gate uint16_t *cksum; /* cksum() vector for data by mss */ 4147c478bd9Sstevel@tonic-gate size_t cksumlen; /* length of memory block for above vector */ 4157c478bd9Sstevel@tonic-gate uint_t resbody; /* HTTP response body at &data[resbody] */ 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate int hlen; /* data buffer split header len */ 4187c478bd9Sstevel@tonic-gate int fileoff; /* file include offset */ 4197c478bd9Sstevel@tonic-gate int filelen; /* length of file */ 4207c478bd9Sstevel@tonic-gate struct node_s *fileback; /* head node_t of a file list (-1 for death) */ 4217c478bd9Sstevel@tonic-gate struct node_s *filenext; /* next node_t of a file list */ 4227c478bd9Sstevel@tonic-gate struct node_s *ctagback; /* head node_t of a ctag list */ 4237c478bd9Sstevel@tonic-gate struct node_s *ctagnext; /* next node_t of a ctag list */ 4247c478bd9Sstevel@tonic-gate vnode_t *filevp; /* vnode for the file */ 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate kmutex_t lock; /* serializes access to node_t */ 4277c478bd9Sstevel@tonic-gate frtn_t frtn; /* STREAMS free routine; always node_freeb() */ 4287c478bd9Sstevel@tonic-gate boolean_t headchunk; /* true if this node is the head chunk */ 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate /* 4317c478bd9Sstevel@tonic-gate * The following 4 fields are used to record node states when 43263360950Smp204432 * upcalls are preempted. When preempted upcalls are not relevant, 4337c478bd9Sstevel@tonic-gate * these fields should have default value 0. 4347c478bd9Sstevel@tonic-gate */ 4357c478bd9Sstevel@tonic-gate uint8_t advise; /* an interpreted advise from http */ 4367c478bd9Sstevel@tonic-gate boolean_t last_advisory; /* preempted upcall state -- advisory bit */ 4377c478bd9Sstevel@tonic-gate boolean_t advisory; /* need advisory from httpd before use */ 4387c478bd9Sstevel@tonic-gate boolean_t first_upcall; /* node in first upcall, a internal state */ 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate kcondvar_t cv; /* sync upcall/downcall process on a node */ 4417c478bd9Sstevel@tonic-gate int onqueue; /* == 1 if on miss_queue, debug aid */ 4427c478bd9Sstevel@tonic-gate } node_t; 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* Note: The MDB NCA module depends on the values of these flags. */ 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate #define REF_URI 0x80000000 /* & ref = node_t URI hashed */ 4477c478bd9Sstevel@tonic-gate #define REF_PHYS 0x40000000 /* & ref = phys mapping in-use */ 4487c478bd9Sstevel@tonic-gate #define REF_VIRT 0x20000000 /* & ref = virt mapping in-use */ 4497c478bd9Sstevel@tonic-gate #define REF_CKSUM 0x10000000 /* & ref = checksum mapping in-use */ 4507c478bd9Sstevel@tonic-gate #define REF_KMEM 0x08000000 /* & ref = kmem mapped (PHYS|VIRT) */ 4517c478bd9Sstevel@tonic-gate #define REF_DONE 0x04000000 /* & ref = node_t fill is done */ 4527c478bd9Sstevel@tonic-gate #define REF_SAFED 0x02000000 /* & ref = node_t not safe for use */ 4537c478bd9Sstevel@tonic-gate #define REF_FILE 0x01000000 /* & ref = node_t filename hashed */ 4547c478bd9Sstevel@tonic-gate #define REF_RESP 0x00800000 /* & ref = node_t response header parsed */ 4557c478bd9Sstevel@tonic-gate #define REF_NOLRU 0x00400000 /* & ref = node_t not safe for lru reclaim */ 4567c478bd9Sstevel@tonic-gate #define REF_MISS 0x00200000 /* & ref = node_t is/will missed() proc */ 4577c478bd9Sstevel@tonic-gate #define REF_ONPLRU 0x00100000 /* & ref = node_t is on Phys LRU */ 4587c478bd9Sstevel@tonic-gate #define REF_ONVLRU 0x00080000 /* & ref = node_t is on Virt LRU */ 4597c478bd9Sstevel@tonic-gate #define REF_PREEMPT 0x00040000 /* & ref = node_t processing preempted */ 4607c478bd9Sstevel@tonic-gate #define REF_CTAG 0x00020000 /* & ref = node_t CTAG hashed */ 4617c478bd9Sstevel@tonic-gate #define REF_UPCALL 0x00010000 /* & ref = node_t upcall not yet complete */ 4627c478bd9Sstevel@tonic-gate #define REF_OWNED 0x00008000 /* & ref = node_t owned (won't be freed) */ 4637c478bd9Sstevel@tonic-gate #define REF_ERROR 0x00004000 /* & ref = node_t errored */ 4647c478bd9Sstevel@tonic-gate #define REF_VNODE 0x00002000 /* & ref = node_t vnode hashed */ 4657c478bd9Sstevel@tonic-gate #define REF_NCAFS 0x00001000 /* & ref = node_t is NCAfs required */ 4667c478bd9Sstevel@tonic-gate #define REF_SEGMAP 0x00000800 /* & ref = segmapped (PHYS|VIRT) */ 4677c478bd9Sstevel@tonic-gate #define REF_UNUSED 0x000007FF /* & ref = UNUSED */ 4687c478bd9Sstevel@tonic-gate /* 4697c478bd9Sstevel@tonic-gate * Mappings where no seperate PHYS and VIRT, i.e. single mapping with a 4707c478bd9Sstevel@tonic-gate * virtual address e.g. REF_KMEM and REF_SEGMAP. 4717c478bd9Sstevel@tonic-gate */ 4727c478bd9Sstevel@tonic-gate #define REF_NOVIRT (REF_KMEM | REF_SEGMAP) 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* Is this node safe for reclaim ? */ 4757c478bd9Sstevel@tonic-gate #define REF_RECLAIM (REF_SAFED | REF_NOLRU | REF_MISS) 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate /* 4787c478bd9Sstevel@tonic-gate * NCA node_t reference counting is more complicated than nca_conn_t reference 4797c478bd9Sstevel@tonic-gate * counting because we pass parts of node_t's (masquerading as dblk 4807c478bd9Sstevel@tonic-gate * buffers) into the STREAMS subsystem which eventually get freed by 4817c478bd9Sstevel@tonic-gate * network drivers just like regular dblk buffers. Also, unlike nca_conn_t's, 4827c478bd9Sstevel@tonic-gate * we may wish to keep a node_t around even after there are no outstanding 4837c478bd9Sstevel@tonic-gate * references, since it's possible that it will be requested again. 4847c478bd9Sstevel@tonic-gate * 4857c478bd9Sstevel@tonic-gate * Thus, the node_t reference count reflects the number of active codepaths 4867c478bd9Sstevel@tonic-gate * in Solaris making use of a given node_t -- each codepath that requires 4877c478bd9Sstevel@tonic-gate * that the node_t stick around once it drops the node_t lock must acquire 4887c478bd9Sstevel@tonic-gate * a reference via NODE_REFHOLD and drop that reference via NODE_REFRELE 4897c478bd9Sstevel@tonic-gate * when done. Note that following a NODE_REFRELE the node that was 4907c478bd9Sstevel@tonic-gate * released may no longer exist and thus it should not be referenced unless 4917c478bd9Sstevel@tonic-gate * the codepath has another outstanding reference. When a node_t is passed 4927c478bd9Sstevel@tonic-gate * into the STREAMS subsystem via desballoc() and related interfaces, a 4937c478bd9Sstevel@tonic-gate * NODE_REFHOLD should be placed on the node_t and the free routine should 4947c478bd9Sstevel@tonic-gate * be set to node_freeb(), which will in turn call NODE_REFRELE. 4957c478bd9Sstevel@tonic-gate * 4967c478bd9Sstevel@tonic-gate * The concept of node ownership allows NCA to express that it would like 4977c478bd9Sstevel@tonic-gate * this node to hang around, even if there are no "explicit" references to 4987c478bd9Sstevel@tonic-gate * it (the ownership counts as an implicit reference). All "headchunk" 4997c478bd9Sstevel@tonic-gate * hashed nodes are owned when they are created. If they subsequently 5007c478bd9Sstevel@tonic-gate * become disowned (currently via nca_node_del() or nca_reclaim_vlru()), 5017c478bd9Sstevel@tonic-gate * they may have some or all their resources freed (via node_fr()) as soon 5027c478bd9Sstevel@tonic-gate * as the last reference to them is removed. Note that it's possible that 5037c478bd9Sstevel@tonic-gate * a disowned node may become of interest again before some or all of its 5047c478bd9Sstevel@tonic-gate * resources were reclaimed -- in this case, it must be reowned via 5057c478bd9Sstevel@tonic-gate * NODE_OWN. Note that an unhashed node should never be owned, though it 5067c478bd9Sstevel@tonic-gate * of course may be held and released; this is because there is no sense 5077c478bd9Sstevel@tonic-gate * in owning a node which is merely temporary (i.e., not hashed somewhere). 5087c478bd9Sstevel@tonic-gate * Note that the corollary of this statement is not true -- that is, just 5097c478bd9Sstevel@tonic-gate * because a node is hashed does not mean it is owned (it may have been 5107c478bd9Sstevel@tonic-gate * disowned via nca_reclaim_vlru()) -- this is why code must always reown 5117c478bd9Sstevel@tonic-gate * hashed nodes if it's desirable to have them stick around. 5127c478bd9Sstevel@tonic-gate * 5137c478bd9Sstevel@tonic-gate * All four macros *must* be called with the node lock held. However, 5147c478bd9Sstevel@tonic-gate * NODE_DISOWN and NODE_REFRELE return with the lock unlocked (if there is 5157c478bd9Sstevel@tonic-gate * still a lock at all), because the operation may have just removed the 5167c478bd9Sstevel@tonic-gate * final reference to a node and it may no longer exist. 5177c478bd9Sstevel@tonic-gate * 5187c478bd9Sstevel@tonic-gate * A version of NODE_REFRELE is provided which doesn't unlock the lock but 5197c478bd9Sstevel@tonic-gate * can only be used when the caller can gaurantee that it's not the last ref 5207c478bd9Sstevel@tonic-gate * (e.g. the caller has another outstanding reference) as if it's the last 5217c478bd9Sstevel@tonic-gate * ref the node_t may no longer exist. The new macro is NODE_REFRELE_LOCKED. 5227c478bd9Sstevel@tonic-gate */ 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate #define NODE_DISOWN(np) { \ 5257c478bd9Sstevel@tonic-gate \ 5267c478bd9Sstevel@tonic-gate NODE_T_TRACE((np), NODE_T_TRACE_DISOWN); \ 5277c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&(np)->lock)); \ 5287c478bd9Sstevel@tonic-gate \ 5297c478bd9Sstevel@tonic-gate if ((np)->ref & REF_OWNED) { \ 5307c478bd9Sstevel@tonic-gate if ((np)->cnt == 0) { \ 5317c478bd9Sstevel@tonic-gate panic("nca NODE_DISOWN: %p has no references", \ 5327c478bd9Sstevel@tonic-gate (void *)(np)); \ 5337c478bd9Sstevel@tonic-gate } \ 5347c478bd9Sstevel@tonic-gate (np)->ref &= ~REF_OWNED; \ 5357c478bd9Sstevel@tonic-gate NODE_REFRELE(np); \ 5367c478bd9Sstevel@tonic-gate } else { \ 5377c478bd9Sstevel@tonic-gate mutex_exit(&(np)->lock); \ 5387c478bd9Sstevel@tonic-gate } \ 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate #define NODE_OWN(np) { \ 5427c478bd9Sstevel@tonic-gate \ 5437c478bd9Sstevel@tonic-gate NODE_T_TRACE((np), NODE_T_TRACE_OWN); \ 5447c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&(np)->lock)); \ 5457c478bd9Sstevel@tonic-gate \ 5467c478bd9Sstevel@tonic-gate if (!((np)->ref & REF_OWNED)) { \ 5477c478bd9Sstevel@tonic-gate if ((np)->cnt == UINT_MAX) \ 5487c478bd9Sstevel@tonic-gate panic( \ 5497c478bd9Sstevel@tonic-gate "nca NODE_OWN: %p has too many references", \ 5507c478bd9Sstevel@tonic-gate (void *)(np)); \ 5517c478bd9Sstevel@tonic-gate (np)->ref |= REF_OWNED; \ 5527c478bd9Sstevel@tonic-gate (np)->cnt++; \ 5537c478bd9Sstevel@tonic-gate } \ 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate #define NODE_REFHOLD(np) { \ 5577c478bd9Sstevel@tonic-gate \ 5587c478bd9Sstevel@tonic-gate NODE_T_TRACE((np), NODE_T_TRACE_REFHOLD | ((np)->cnt + 1)); \ 5597c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&(np)->lock)); \ 5607c478bd9Sstevel@tonic-gate \ 5617c478bd9Sstevel@tonic-gate if ((np)->cnt == UINT_MAX) \ 5627c478bd9Sstevel@tonic-gate panic("nca NODE_REFHOLD: %p has too many references", \ 5637c478bd9Sstevel@tonic-gate (void *)(np)); \ 5647c478bd9Sstevel@tonic-gate (np)->cnt++; \ 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate #define NODE_REFRELE(np) { \ 5687c478bd9Sstevel@tonic-gate \ 5697c478bd9Sstevel@tonic-gate NODE_T_TRACE((np), NODE_T_TRACE_REFRELE | ((np)->cnt - 1)); \ 5707c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&(np)->lock)); \ 5717c478bd9Sstevel@tonic-gate \ 5727c478bd9Sstevel@tonic-gate if (((np)->ref & REF_OWNED) && (np)->cnt == 1) \ 5737c478bd9Sstevel@tonic-gate panic( \ 5747c478bd9Sstevel@tonic-gate "nca NODE_REFRELE: %p has only OWNED reference", \ 5757c478bd9Sstevel@tonic-gate (void *)(np)); \ 5767c478bd9Sstevel@tonic-gate if ((np)->cnt == 0) \ 5777c478bd9Sstevel@tonic-gate panic("nca NODE_REFRELE: %p has no references", \ 5787c478bd9Sstevel@tonic-gate (void *)(np)); \ 5797c478bd9Sstevel@tonic-gate (np)->cnt--; \ 5807c478bd9Sstevel@tonic-gate if ((np)->cnt == 0) { \ 5817c478bd9Sstevel@tonic-gate ASSERT(((np)->ref & REF_OWNED) == 0); \ 5827c478bd9Sstevel@tonic-gate node_fr(np); /* node_fr unlocks the lock */ \ 5837c478bd9Sstevel@tonic-gate } else { \ 5847c478bd9Sstevel@tonic-gate mutex_exit(&(np)->lock); \ 5857c478bd9Sstevel@tonic-gate } \ 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate #define NODE_REFRELE_LOCKED(np) { \ 5897c478bd9Sstevel@tonic-gate uint_t _cnt = (np)->cnt; \ 5907c478bd9Sstevel@tonic-gate \ 5917c478bd9Sstevel@tonic-gate NODE_T_TRACE((np), NODE_T_TRACE_REFRELE | (_cnt - 1)); \ 5927c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&(np)->lock)); \ 5937c478bd9Sstevel@tonic-gate \ 5947c478bd9Sstevel@tonic-gate if ((np)->ref & REF_OWNED) \ 5957c478bd9Sstevel@tonic-gate _cnt--; \ 5967c478bd9Sstevel@tonic-gate if (((np)->ref & REF_OWNED) && _cnt == 0) \ 5977c478bd9Sstevel@tonic-gate panic("nca NODE_REFRELE_LOCKED: " \ 5987c478bd9Sstevel@tonic-gate "%p has only OWNED reference", (void *)(np)); \ 5997c478bd9Sstevel@tonic-gate if (_cnt == 0) \ 6007c478bd9Sstevel@tonic-gate panic("nca NODE_REFRELEL_LOCKED: " \ 6017c478bd9Sstevel@tonic-gate "%p has no references", (void *)(np)); \ 6027c478bd9Sstevel@tonic-gate if (_cnt == 1) \ 6037c478bd9Sstevel@tonic-gate panic("nca NODE_REFRELEL_LOCKED: " \ 6047c478bd9Sstevel@tonic-gate "%p has only one reference", (void *)(np)); \ 6057c478bd9Sstevel@tonic-gate (np)->cnt--; \ 6067c478bd9Sstevel@tonic-gate } 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate /* 6107c478bd9Sstevel@tonic-gate * NODE_T_TRACE - trace node_t events. 6117c478bd9Sstevel@tonic-gate * 6127c478bd9Sstevel@tonic-gate * adb: 6137c478bd9Sstevel@tonic-gate * 32 bit 6147c478bd9Sstevel@tonic-gate * *node_tp,0t8192-(((*node_tp)-node_tv)%0t48)/PXXDDnPnPnPnPnPnPnPnn 6157c478bd9Sstevel@tonic-gate * node_tv,((*node_tp)-node_tv)%0t48/PXXDDnPnPnPnPnPnPnPnn 6167c478bd9Sstevel@tonic-gate * 6177c478bd9Sstevel@tonic-gate * 64 bit 6187c478bd9Sstevel@tonic-gate * *node_tp,0t8192-(((*node_tp)-node_tv)%0t56)/PXXDDnXnXnXnXnXnXnXnn 6197c478bd9Sstevel@tonic-gate * node_tv,((*node_tp)-node_tv)%0t56/PXXDDnXnXnXnXnXnXnXnn 6207c478bd9Sstevel@tonic-gate * 6217c478bd9Sstevel@tonic-gate * For incremental node tracing, note the value of node_tp (node_tp/X) after 6227c478bd9Sstevel@tonic-gate * a run, then replace that in the 2nd line for node_tv. 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate #define NODE_T_STK_DEPTH 6 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate struct node_ts { 6287c478bd9Sstevel@tonic-gate node_t *node; 6297c478bd9Sstevel@tonic-gate unsigned action; 6307c478bd9Sstevel@tonic-gate unsigned ref; 6317c478bd9Sstevel@tonic-gate unsigned cnt; 6327c478bd9Sstevel@tonic-gate int cpu; 6337c478bd9Sstevel@tonic-gate pc_t stk[NODE_T_STK_DEPTH + 1]; 6347c478bd9Sstevel@tonic-gate }; 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate #undef NODE_T_TRACE_ON 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate #ifdef NODE_T_TRACE_ON 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_ALLOC 0xFF000000 /* kmem_alloc() of */ 6417c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_ADD 0xFE000000 /* node_add() */ 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_OWN 0xEF000000 /* node has been owned */ 6447c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DISOWN 0xEE000000 /* node has been disowned */ 6457c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DESBALLOC 0xED000000 /* desballoc() */ 6467c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_REFRELE 0xEC000000 /* refrele */ 6477c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_REFHOLD 0xEB000000 /* refhold */ 6487c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_NODE_FR 0xEA000000 /* node_fr() */ 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_TEMPNODE 0xDF000000 /* node_temp() */ 6517c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_REPLACE 0xDE000000 /* node_replace() */ 6527c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_FLUSH 0xDD000000 /* node_flush() */ 6537c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DOWNCALL 0xDC000000 /* downcall_service() */ 6547c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DOWNCALL_2 0xDB000000 /* dcall_service->httpd_data */ 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DATA 0xCF000000 /* httpd_data() */ 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_LRU 0xAF000000 /* nca_lru insert */ 6597c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_HTTPD 0xAE000000 /* call nca_httpd() */ 6607c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_MISS 0xAD000000 /* http_miss() */ 6617c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_TEMP 0xAC000000 /* np != *npp */ 6627c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_XMIT 0xAB000000 /* tcp_xmit() */ 6637c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_MISSED 0xAA000000 /* nca_missed() */ 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_DEL 0x00000000 /* node_del() */ 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 6687c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_STK() { \ 6697c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[0], NODE_T_STK_DEPTH + 1); \ 6707c478bd9Sstevel@tonic-gate if (_ix < NODE_T_STK_DEPTH + 1) { \ 6717c478bd9Sstevel@tonic-gate _p->stk[_ix + 1] = 0; \ 6727c478bd9Sstevel@tonic-gate } \ 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate #else 6757c478bd9Sstevel@tonic-gate #define NODE_T_TRACE_STK() { \ 6767c478bd9Sstevel@tonic-gate _p->stk[0] = (pc_t)callee(); \ 6777c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[1], NODE_T_STK_DEPTH); \ 6787c478bd9Sstevel@tonic-gate if (_ix < NODE_T_STK_DEPTH) { \ 6797c478bd9Sstevel@tonic-gate _p->stk[_ix + 1] = 0; \ 6807c478bd9Sstevel@tonic-gate } \ 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate #endif 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate #define NODE_TV_SZ 8192 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate extern struct node_ts node_tv[NODE_TV_SZ]; 6877c478bd9Sstevel@tonic-gate extern struct node_ts *node_tp; 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate #define NODE_T_TRACE(p, a) { \ 6907c478bd9Sstevel@tonic-gate struct node_ts *_p; \ 6917c478bd9Sstevel@tonic-gate struct node_ts *_np; \ 6927c478bd9Sstevel@tonic-gate int _ix; \ 6937c478bd9Sstevel@tonic-gate \ 6947c478bd9Sstevel@tonic-gate do { \ 6957c478bd9Sstevel@tonic-gate _p = node_tp; \ 6967c478bd9Sstevel@tonic-gate if ((_np = _p + 1) == &node_tv[NODE_TV_SZ]) \ 6977c478bd9Sstevel@tonic-gate _np = node_tv; \ 69875d94465SJosef 'Jeff' Sipek } while (atomic_cas_ptr(&node_tp, _p, _np) != _p); \ 6997c478bd9Sstevel@tonic-gate _p->node = (p); \ 7007c478bd9Sstevel@tonic-gate _p->action = (a); \ 7017c478bd9Sstevel@tonic-gate _p->ref = (p) ? (p)->ref : 0; \ 7027c478bd9Sstevel@tonic-gate _p->cnt = (p) ? (p)->cnt : 0; \ 7037c478bd9Sstevel@tonic-gate _p->cpu = CPU->cpu_seqid; \ 7047c478bd9Sstevel@tonic-gate NODE_T_TRACE_STK(); \ 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate #else /* NODE_T_TRACE_ON */ 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate #define NODE_T_TRACE(p, a) 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate #endif /* NODE_T_TRACE_ON */ 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate /* 7147c478bd9Sstevel@tonic-gate * DOOR_TRACE - trace door node_t events. 7157c478bd9Sstevel@tonic-gate * 7167c478bd9Sstevel@tonic-gate * adb: 7177c478bd9Sstevel@tonic-gate * 32 bit 7187c478bd9Sstevel@tonic-gate * *door_tp,0t8192-(((*door_tp)-door_tv)%0t112)/5XnPnPnPnPnPnPnPn64cnn 7197c478bd9Sstevel@tonic-gate * door_tv,((*door_tp)-door_tv)%0t112/5XnPnPnPnPnPnPnPn64cnn 7207c478bd9Sstevel@tonic-gate * 64 bit 7217c478bd9Sstevel@tonic-gate * *door_tp,0t8192-(((*door_tp)-door_tv)%0t128)/PXPXXnXnXnXnXnXnXnXn64cnn 7227c478bd9Sstevel@tonic-gate * door_tv,((*door_tp)-door_tv)%0t128/PXPXXnXnXnXnXnXnXnXn64cnn 7237c478bd9Sstevel@tonic-gate */ 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate #define DOOR_STK_DEPTH 6 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate struct door_ts { 7288793b36bSNick Todd struct nca_conn_s *cp; 7297c478bd9Sstevel@tonic-gate unsigned action; 7307c478bd9Sstevel@tonic-gate node_t *np; 7317c478bd9Sstevel@tonic-gate int ref; 7327c478bd9Sstevel@tonic-gate unsigned state; 7337c478bd9Sstevel@tonic-gate pc_t stk[DOOR_STK_DEPTH + 1]; 7347c478bd9Sstevel@tonic-gate char data[64]; 7357c478bd9Sstevel@tonic-gate }; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate #undef DOOR_TRACE_ON 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate #ifdef DOOR_TRACE_ON 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate #define DOOR_TRACE_UPCALL 0xF0000000 /* upcall() */ 7427c478bd9Sstevel@tonic-gate #define DOOR_TRACE_UPCALL_RAW 0xF1000000 /* upcall() RAW ? */ 7437c478bd9Sstevel@tonic-gate #define DOOR_TRACE_UPCALL_RET 0xFF000000 /* upcall() return */ 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate #define DOOR_TRACE_DOWNCALL 0xE0000000 /* downcall() */ 7467c478bd9Sstevel@tonic-gate #define DOOR_TRACE_CONNECT 0xE1000000 /* connect() */ 7477c478bd9Sstevel@tonic-gate #define DOOR_TRACE_CONNECT_DATA 0xE2000000 /* connect() */ 7487c478bd9Sstevel@tonic-gate #define DOOR_TRACE_DIRECTFROM 0xE3000000 /* tee_splice() from */ 7497c478bd9Sstevel@tonic-gate #define DOOR_TRACE_DIRECTTO 0xE4000000 /* tee_splice() to */ 7507c478bd9Sstevel@tonic-gate #define DOOR_TRACE_DOWNCALL_RET 0xEF000000 /* downcall() return */ 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate #define DOOR_TRACE_INIT 0x80000000 /* doorcall_init() */ 7537c478bd9Sstevel@tonic-gate #define DOOR_TRACE_INIT_RET 0x88000000 /* doorcall_init() return */ 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 7567c478bd9Sstevel@tonic-gate #define DOOR_TRACE_STK() { \ 7577c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[0], DOOR_STK_DEPTH + 1); \ 7587c478bd9Sstevel@tonic-gate if (_ix < DOOR_STK_DEPTH + 1) { \ 7597c478bd9Sstevel@tonic-gate _p->stk[_ix] = 0; \ 7607c478bd9Sstevel@tonic-gate } \ 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate #else 7637c478bd9Sstevel@tonic-gate #define DOOR_TRACE_STK() { \ 7647c478bd9Sstevel@tonic-gate _p->stk[0] = (pc_t)callee(); \ 7657c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[1], DOOR_STK_DEPTH); \ 7667c478bd9Sstevel@tonic-gate if (_ix < DOOR_STK_DEPTH) { \ 7677c478bd9Sstevel@tonic-gate _p->stk[_ix + 1] = 0; \ 7687c478bd9Sstevel@tonic-gate } \ 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate #endif 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate #define DOOR_TV_SZ 8192 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate extern struct door_ts door_tv[DOOR_TV_SZ]; 7757c478bd9Sstevel@tonic-gate extern struct door_ts *door_tp; 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate #define DOOR_TRACE(io, d, d_sz, a) { \ 7787c478bd9Sstevel@tonic-gate nca_conn_t *_cp = (io) ? (nca_conn_t *)(io)->cid : (nca_conn_t *)NULL; \ 7797c478bd9Sstevel@tonic-gate node_t *_req_np = _cp ? _cp->req_np : (node_t *)NULL; \ 7807c478bd9Sstevel@tonic-gate struct door_ts *_p; \ 7817c478bd9Sstevel@tonic-gate struct door_ts *_np; \ 7827c478bd9Sstevel@tonic-gate int _ix; \ 7837c478bd9Sstevel@tonic-gate \ 7847c478bd9Sstevel@tonic-gate do { \ 7857c478bd9Sstevel@tonic-gate _p = door_tp; \ 7867c478bd9Sstevel@tonic-gate if ((_np = _p + 1) == &door_tv[DOOR_TV_SZ]) \ 7877c478bd9Sstevel@tonic-gate _np = door_tv; \ 78875d94465SJosef 'Jeff' Sipek } while (atomic_cas_ptr(&door_tp, _p, _np) != _p); \ 7897c478bd9Sstevel@tonic-gate _p->cp = _cp; \ 7907c478bd9Sstevel@tonic-gate _p->np = _req_np; \ 7917c478bd9Sstevel@tonic-gate _p->action = (a); \ 7927c478bd9Sstevel@tonic-gate _p->ref = _req_np ? _req_np->ref : 0; \ 7937c478bd9Sstevel@tonic-gate if ((io)) { \ 7947c478bd9Sstevel@tonic-gate _p->state = ((io)->op == http_op ? 0x80000000 : 0) | \ 7957c478bd9Sstevel@tonic-gate ((io)->more ? 0x40000000 : 0) | \ 7967c478bd9Sstevel@tonic-gate ((io)->first ? 0x20000000 : 0) | \ 7977c478bd9Sstevel@tonic-gate ((io)->advisory ? 0x10000000 : 0) | \ 7987c478bd9Sstevel@tonic-gate ((io)->nocache ? 0x08000000 : 0) | \ 7997c478bd9Sstevel@tonic-gate ((io)->preempt ? 0x04000000 : 0) | \ 8007c478bd9Sstevel@tonic-gate ((io)->peer_len ? 0x02000000 : 0) | \ 8017c478bd9Sstevel@tonic-gate ((io)->local_len ? 0x01000000 : 0) | \ 8027c478bd9Sstevel@tonic-gate ((io)->data_len ? 0x00800000 : 0) | \ 8037c478bd9Sstevel@tonic-gate (((io)->direct_type << 20) & 0x00700000) | \ 8047c478bd9Sstevel@tonic-gate ((io)->direct_len ? 0x00080000 : 0) | \ 8057c478bd9Sstevel@tonic-gate ((io)->trailer_len ? 0x00040000 : 0) | \ 8067c478bd9Sstevel@tonic-gate (((io)->peer_len + (io)->local_len + \ 8077c478bd9Sstevel@tonic-gate (io)->data_len + (io)->direct_len + \ 8087c478bd9Sstevel@tonic-gate (io)->trailer_len) & 0x3FFFF); \ 8097c478bd9Sstevel@tonic-gate } else { \ 8107c478bd9Sstevel@tonic-gate _p->state = 0; \ 8117c478bd9Sstevel@tonic-gate } \ 8127c478bd9Sstevel@tonic-gate if ((d_sz)) { \ 8137c478bd9Sstevel@tonic-gate int _n = MIN((d_sz), 63); \ 8147c478bd9Sstevel@tonic-gate \ 8157c478bd9Sstevel@tonic-gate bcopy((d), _p->data, _n); \ 8167c478bd9Sstevel@tonic-gate bzero(&_p->data[_n], 64 - _n); \ 8177c478bd9Sstevel@tonic-gate } else { \ 8187c478bd9Sstevel@tonic-gate bzero(_p->data, 64); \ 8197c478bd9Sstevel@tonic-gate } \ 8207c478bd9Sstevel@tonic-gate DOOR_TRACE_STK(); \ 8217c478bd9Sstevel@tonic-gate } 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate #else /* DOOR_TRACE_ON */ 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate #define DOOR_TRACE(io, d, d_sz, a) 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate #endif /* DOOR_TRACE_ON */ 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate /* 8307c478bd9Sstevel@tonic-gate * NCA node LRU cache. Defined here so that the NCA mdb module can use it. 8317c478bd9Sstevel@tonic-gate */ 8327c478bd9Sstevel@tonic-gate typedef struct lru_s { 8337c478bd9Sstevel@tonic-gate node_t *phead; /* Phys LRU list head (MRU) */ 8347c478bd9Sstevel@tonic-gate node_t *ptail; /* Phys LRU list tail (LRU) */ 8357c478bd9Sstevel@tonic-gate node_t *vhead; /* Virt LRU list head (MRU) */ 8367c478bd9Sstevel@tonic-gate node_t *vtail; /* Virt LRU list tail (LRU) */ 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate uint32_t pcount; /* Phys count of node_t members */ 8397c478bd9Sstevel@tonic-gate uint32_t vcount; /* Virt count of node_t members */ 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate kmutex_t lock; /* Guarantee atomic access of above */ 8427c478bd9Sstevel@tonic-gate } lru_t; 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate /* 8457c478bd9Sstevel@tonic-gate * Per CPU instance structure. 8467c478bd9Sstevel@tonic-gate * 8477c478bd9Sstevel@tonic-gate * 32-bit adb: XXXnnDnnXXnnXXnnXDnnXXnn228+na 8487c478bd9Sstevel@tonic-gate * 64-bit adb: PPPnnD4+nnPPnnPPnnJDnnJ180+na 8497c478bd9Sstevel@tonic-gate */ 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate typedef struct nca_cpu_s { 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate node_t *persist_hdr_none; 8547c478bd9Sstevel@tonic-gate node_t *persist_hdr_close; 8557c478bd9Sstevel@tonic-gate node_t *persist_hdr_ka; 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate uint32_t dcb_readers; /* count of dcb_list readers for this CPU */ 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate nca_squeue_t *if_inq; /* if_t input nca_squeue_t */ 8607c478bd9Sstevel@tonic-gate nca_squeue_t *if_ouq; /* if_t output nca_squeue_t */ 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate ti_t *tcp_ti; /* TCP TIMER list */ 8637c478bd9Sstevel@tonic-gate tw_t *tcp_tw; /* TCP TIME_WAIT list */ 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate ddi_softintr_t soft_id; /* soft interrupt id for if_inq worker */ 8667c478bd9Sstevel@tonic-gate int if_inq_cnt; /* count of if_t.inq references */ 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate char pad[256 - sizeof (node_t *) - sizeof (node_t *) - 8697c478bd9Sstevel@tonic-gate sizeof (node_t *) - sizeof (uint32_t) - 8707c478bd9Sstevel@tonic-gate sizeof (nca_squeue_t *) - sizeof (nca_squeue_t *) - 8717c478bd9Sstevel@tonic-gate sizeof (ti_t *) - sizeof (tw_t *) - 8727c478bd9Sstevel@tonic-gate sizeof (ddi_softintr_t) - sizeof (int)]; 8737c478bd9Sstevel@tonic-gate } nca_cpu_t; 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate extern nca_cpu_t *nca_gv; /* global per CPU state indexed by cpu_seqid */ 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate /* 8787c478bd9Sstevel@tonic-gate * hcb_t - host control block. 8797c478bd9Sstevel@tonic-gate * 8807c478bd9Sstevel@tonic-gate * Used early on in packet switching to select packets to be serviced by NCA 8817c478bd9Sstevel@tonic-gate * and optionally later on by the HTTP protocol layer to further select HTTP 8827c478bd9Sstevel@tonic-gate * request to be serviced. 8837c478bd9Sstevel@tonic-gate * 8847c478bd9Sstevel@tonic-gate * dcb_t - door control block. 8857c478bd9Sstevel@tonic-gate * 8867c478bd9Sstevel@tonic-gate * Used to associate one or more hcb_t(s) with a given httpd door instance. 8877c478bd9Sstevel@tonic-gate * 8887c478bd9Sstevel@tonic-gate * dcb_list - dcb_t global list, a singly linked grounded list of dcb_t's. 8897c478bd9Sstevel@tonic-gate * 8907c478bd9Sstevel@tonic-gate * Used to search for a hcb_t match, currently a singly linked grounded list 8917c478bd9Sstevel@tonic-gate * of dcb_t's with a linear walk of the list. While this is adequate for the 8927c478bd9Sstevel@tonic-gate * current httpd support (i.e. a single door) a move to either a hash or tree 8937c478bd9Sstevel@tonic-gate * will be required for multiple httpd instance support (i.e. multiple doors). 8947c478bd9Sstevel@tonic-gate * 8957c478bd9Sstevel@tonic-gate * The dcb_list is protected by a custom reader/writer lock, the motivation 8967c478bd9Sstevel@tonic-gate * for using a custom lock instead of a krwlock_t is that this lock is the 8977c478bd9Sstevel@tonic-gate * single hot spot in NCA (i.e. all in-bound packets must acquire this lock) 8987c478bd9Sstevel@tonic-gate * and a nonlocking atomic readers count scheme is used in the common case 8997c478bd9Sstevel@tonic-gate * (i.e. reader lock) with a fall-back to a conventional kmutex_t for writer 9007c478bd9Sstevel@tonic-gate * (i.e. ndd list add/delete). 9017c478bd9Sstevel@tonic-gate */ 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate typedef struct hcb_s { 9047c478bd9Sstevel@tonic-gate struct hcb_s *next; /* Next hcb_t (none: NULL) */ 9057c478bd9Sstevel@tonic-gate ipaddr_t addr; /* IP address (any: INADDR_ANY or 0) */ 9067c478bd9Sstevel@tonic-gate uint16_t port; /* TCP port number */ 9077c478bd9Sstevel@tonic-gate char *host; /* Host: name (any: NULL) */ 9087c478bd9Sstevel@tonic-gate ssize_t hostsz; /* Size of above */ 9097c478bd9Sstevel@tonic-gate char *root; /* Document root ("/": NULL) */ 9107c478bd9Sstevel@tonic-gate ssize_t rootsz; /* Size of above */ 9117c478bd9Sstevel@tonic-gate } hcb_t; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate typedef struct dcb_s { 9147c478bd9Sstevel@tonic-gate struct dcb_s *next; /* Next dcb_t (none: NULL) */ 9157c478bd9Sstevel@tonic-gate char *door; /* Door file (default: NULL) */ 9167c478bd9Sstevel@tonic-gate ssize_t doorsz; /* Size of above */ 9177c478bd9Sstevel@tonic-gate door_handle_t hand; /* Door handle (default: NULL) */ 9187c478bd9Sstevel@tonic-gate hcb_t list; /* Head of a hcb_t list (any: NULL) */ 9197c478bd9Sstevel@tonic-gate } dcb_t; 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate extern dcb_t dcb_list; 9227c478bd9Sstevel@tonic-gate extern kmutex_t nca_dcb_lock; 9237c478bd9Sstevel@tonic-gate extern kcondvar_t nca_dcb_wait; 9247c478bd9Sstevel@tonic-gate extern kmutex_t nca_dcb_readers; 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate #define NOHANDLE ((door_handle_t)-1) 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate #define DCB_COUNT_USELOCK 0x80000000 9297c478bd9Sstevel@tonic-gate #define DCB_COUNT_MASK 0x3FFFFFFF 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate #define DCB_RD_ENTER(cpu) { \ 9327c478bd9Sstevel@tonic-gate uint32_t *rp; \ 9337c478bd9Sstevel@tonic-gate \ 9347c478bd9Sstevel@tonic-gate cpu = CPU->cpu_seqid; \ 9357c478bd9Sstevel@tonic-gate rp = &nca_gv[cpu].dcb_readers; \ 9367c478bd9Sstevel@tonic-gate while (atomic_add_32_nv(rp, 1) & DCB_COUNT_USELOCK) { \ 9377c478bd9Sstevel@tonic-gate /* Need to use the lock, so do the dance */ \ 9387c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_lock); \ 9397c478bd9Sstevel@tonic-gate if (atomic_add_32_nv(rp, -1) == DCB_COUNT_USELOCK && \ 9407c478bd9Sstevel@tonic-gate CV_HAS_WAITERS(&nca_dcb_wait)) { \ 9417c478bd9Sstevel@tonic-gate /* May be the last reader for this CPU */ \ 9427c478bd9Sstevel@tonic-gate cv_signal(&nca_dcb_wait); \ 9437c478bd9Sstevel@tonic-gate } \ 9447c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_lock); \ 9457c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_readers); \ 9467c478bd9Sstevel@tonic-gate /* \ 9477c478bd9Sstevel@tonic-gate * We block above waiting for the writer to exit the \ 9487c478bd9Sstevel@tonic-gate * readers lock, if we didn't block then while we were \ 9497c478bd9Sstevel@tonic-gate * away in the nca_dcb_lock enter the writer exited, \ 9507c478bd9Sstevel@tonic-gate * we could optimize for this case by checking USELOCK \ 9517c478bd9Sstevel@tonic-gate * after the decrement, but as this is an exceptional \ 9527c478bd9Sstevel@tonic-gate * case not in the fast-path we'll just take the hit \ 9537c478bd9Sstevel@tonic-gate * of a needless readers enter/exit. \ 9547c478bd9Sstevel@tonic-gate */ \ 9557c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_readers); \ 9567c478bd9Sstevel@tonic-gate } \ 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate #define DCB_RD_EXIT(cpu) { \ 9607c478bd9Sstevel@tonic-gate uint32_t *rp = &nca_gv[cpu].dcb_readers; \ 9617c478bd9Sstevel@tonic-gate \ 962*1a5e258fSJosef 'Jeff' Sipek if (atomic_dec_32_nv(rp) == DCB_COUNT_USELOCK) { \ 9637c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_lock); \ 9647c478bd9Sstevel@tonic-gate if (CV_HAS_WAITERS(&nca_dcb_wait)) { \ 9657c478bd9Sstevel@tonic-gate /* May be the last reader for this CPU */ \ 9667c478bd9Sstevel@tonic-gate cv_signal(&nca_dcb_wait); \ 9677c478bd9Sstevel@tonic-gate } \ 9687c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_lock); \ 9697c478bd9Sstevel@tonic-gate } \ 9707c478bd9Sstevel@tonic-gate } 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate #define DCB_WR_ENTER() { \ 9737c478bd9Sstevel@tonic-gate int cpu; \ 9747c478bd9Sstevel@tonic-gate int readers; \ 9757c478bd9Sstevel@tonic-gate \ 9767c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_readers); \ 9777c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_lock); \ 9787c478bd9Sstevel@tonic-gate for (;;) { \ 9797c478bd9Sstevel@tonic-gate readers = 0; \ 9807c478bd9Sstevel@tonic-gate for (cpu = 0; cpu < max_ncpus; cpu++) { \ 9817c478bd9Sstevel@tonic-gate int new; \ 9827c478bd9Sstevel@tonic-gate uint32_t *rp = &nca_gv[cpu].dcb_readers; \ 9837c478bd9Sstevel@tonic-gate int old = *rp; \ 9847c478bd9Sstevel@tonic-gate \ 9857c478bd9Sstevel@tonic-gate if (old & DCB_COUNT_USELOCK) { \ 9867c478bd9Sstevel@tonic-gate readers += old & DCB_COUNT_MASK; \ 9877c478bd9Sstevel@tonic-gate continue; \ 9887c478bd9Sstevel@tonic-gate } \ 9897c478bd9Sstevel@tonic-gate new = old | DCB_COUNT_USELOCK; \ 99075d94465SJosef 'Jeff' Sipek while (atomic_cas_32(rp, old, new) != old) { \ 9917c478bd9Sstevel@tonic-gate old = *rp; \ 9927c478bd9Sstevel@tonic-gate new = old | DCB_COUNT_USELOCK; \ 9937c478bd9Sstevel@tonic-gate } \ 9947c478bd9Sstevel@tonic-gate readers += (new & DCB_COUNT_MASK); \ 9957c478bd9Sstevel@tonic-gate } \ 9967c478bd9Sstevel@tonic-gate if (readers == 0) \ 9977c478bd9Sstevel@tonic-gate break; \ 9987c478bd9Sstevel@tonic-gate cv_wait(&nca_dcb_wait, &nca_dcb_lock); \ 9997c478bd9Sstevel@tonic-gate } \ 10007c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_lock); \ 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate #define DCB_WR_EXIT() { \ 10047c478bd9Sstevel@tonic-gate int cpu; \ 10057c478bd9Sstevel@tonic-gate \ 10067c478bd9Sstevel@tonic-gate mutex_enter(&nca_dcb_lock); \ 10077c478bd9Sstevel@tonic-gate for (cpu = 0; cpu < max_ncpus; cpu++) { \ 10087c478bd9Sstevel@tonic-gate int new; \ 10097c478bd9Sstevel@tonic-gate uint32_t *rp = &nca_gv[cpu].dcb_readers; \ 10107c478bd9Sstevel@tonic-gate int old = *rp; \ 10117c478bd9Sstevel@tonic-gate \ 10127c478bd9Sstevel@tonic-gate new = old & ~DCB_COUNT_USELOCK; \ 101375d94465SJosef 'Jeff' Sipek while (atomic_cas_32(rp, old, new) != old) { \ 10147c478bd9Sstevel@tonic-gate old = *rp; \ 10157c478bd9Sstevel@tonic-gate new = old & ~DCB_COUNT_USELOCK; \ 10167c478bd9Sstevel@tonic-gate } \ 10177c478bd9Sstevel@tonic-gate } \ 10187c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_lock); \ 10197c478bd9Sstevel@tonic-gate mutex_exit(&nca_dcb_readers); \ 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate typedef struct nca_door_s { 10237c478bd9Sstevel@tonic-gate door_handle_t handle; /* The door handle */ 10247c478bd9Sstevel@tonic-gate char *name; /* The door name */ 10257c478bd9Sstevel@tonic-gate kmutex_t lock; /* The door lock */ 10267c478bd9Sstevel@tonic-gate kcondvar_t cv_writer; /* condvar for thread waiting */ 10277c478bd9Sstevel@tonic-gate /* to do door_init */ 10287c478bd9Sstevel@tonic-gate kcondvar_t cv_reader; /* condvar for thread waiting */ 10297c478bd9Sstevel@tonic-gate /* for a door_init to finish */ 10307c478bd9Sstevel@tonic-gate uint32_t upcalls; /* Number of upcalls in progress */ 10317c478bd9Sstevel@tonic-gate boolean_t init_waiting; /* door_init thread wanting to */ 10327c478bd9Sstevel@tonic-gate /* be exclusive */ 10337c478bd9Sstevel@tonic-gate } nca_door_t; 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate /* 10367c478bd9Sstevel@tonic-gate * if_t - interface per instance data. 10377c478bd9Sstevel@tonic-gate */ 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate typedef struct if_s { 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate boolean_t dev; /* is a device instance */ 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate queue_t *rqp; /* our read-side STREAMS queue */ 10447c478bd9Sstevel@tonic-gate queue_t *wqp; /* our write-side STREAMS queue */ 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate /* DLPI M_DATA IP fastpath template */ 10477c478bd9Sstevel@tonic-gate size_t mac_length; 10487c478bd9Sstevel@tonic-gate mblk_t *mac_mp; 10497c478bd9Sstevel@tonic-gate int32_t mac_mtu; 10507c478bd9Sstevel@tonic-gate int32_t mac_addr_len; 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate uint32_t ip_ident; /* our IP ident value */ 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate boolean_t hwcksum; /* underlying NIC supports checksum offload */ 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate nca_squeue_t *inq; /* in-bound nca_squeue_t */ 10577c478bd9Sstevel@tonic-gate nca_squeue_t *ouq; /* out-bound nca_squeue_t */ 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate /* 10607c478bd9Sstevel@tonic-gate * All if_t are associated with a CPU and have a default 10617c478bd9Sstevel@tonic-gate * router on link are chained in a circular linked list. 10627c478bd9Sstevel@tonic-gate */ 10637c478bd9Sstevel@tonic-gate struct if_s *next_if; 10647c478bd9Sstevel@tonic-gate struct if_s *prev_if; 10657c478bd9Sstevel@tonic-gate ipaddr_t local_addr; /* This interface's IP address. */ 10667c478bd9Sstevel@tonic-gate uchar_t router_ether_addr[6]; 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate uint_t hdr_ioc_id; /* id of DL_IOC_HDR_INFO M_IOCTL sent down */ 10697c478bd9Sstevel@tonic-gate boolean_t info_req_pending; 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate int32_t capab_state; /* Capability probe state */ 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate /* Bound local address of a NCAfs instance. */ 10747c478bd9Sstevel@tonic-gate struct sockaddr_in bound_addr; 10757c478bd9Sstevel@tonic-gate } if_t; 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate /* 10787c478bd9Sstevel@tonic-gate * connf_t - connection fanout data. 10797c478bd9Sstevel@tonic-gate * 10807c478bd9Sstevel@tonic-gate * The hash tables and their linkage (hashnextp, hashprevp) are protected 10817c478bd9Sstevel@tonic-gate * by the per-bucket lock. Each nca_conn_t inserted in the list points back at 10827c478bd9Sstevel@tonic-gate * the connf_t that heads the bucket. 10837c478bd9Sstevel@tonic-gate */ 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate typedef struct connf_s { 10867c478bd9Sstevel@tonic-gate uint32_t max; 10878793b36bSNick Todd struct nca_conn_s *head; 10887c478bd9Sstevel@tonic-gate kmutex_t lock; 10897c478bd9Sstevel@tonic-gate } connf_t; 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate #ifdef CONNP_T_TRACE_ON 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate #define CONNP_TV_SZ 32 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate /* 10967c478bd9Sstevel@tonic-gate * Per nca_conn_t packet tracing. 10977c478bd9Sstevel@tonic-gate */ 10987c478bd9Sstevel@tonic-gate typedef struct connp_s { 10997c478bd9Sstevel@tonic-gate clock_t lbolt; 11007c478bd9Sstevel@tonic-gate clock_t tcp_ti; 11017c478bd9Sstevel@tonic-gate int32_t len : 16, 11027c478bd9Sstevel@tonic-gate dir : 1, 11037c478bd9Sstevel@tonic-gate state : 4, 11047c478bd9Sstevel@tonic-gate flags : 6, 11057c478bd9Sstevel@tonic-gate xmit_np : 1, 11067c478bd9Sstevel@tonic-gate xmit_head : 1, 11077c478bd9Sstevel@tonic-gate unsent : 1, 11087c478bd9Sstevel@tonic-gate tail_unsent : 1, 11097c478bd9Sstevel@tonic-gate direct : 1; 11107c478bd9Sstevel@tonic-gate uint32_t state1; 11117c478bd9Sstevel@tonic-gate uint32_t state2; 11127c478bd9Sstevel@tonic-gate uint32_t seq; 11137c478bd9Sstevel@tonic-gate uint32_t ack; 11147c478bd9Sstevel@tonic-gate uint32_t snxt; 11157c478bd9Sstevel@tonic-gate uint32_t swnd; 11167c478bd9Sstevel@tonic-gate } connp_t; 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate #endif /* CONNP_T_TRACE_ON */ 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate /* 11217c478bd9Sstevel@tonic-gate * nca_conn_t - connection per instance data. 11227c478bd9Sstevel@tonic-gate * 11237c478bd9Sstevel@tonic-gate * Note: hashlock is used to provide atomic access to all nca_conn_t members 11247c478bd9Sstevel@tonic-gate * above it. All other members are protected by the per CPU inq nca_squeue_t 11257c478bd9Sstevel@tonic-gate * which is used to serialize access to all nca_conn_t's per interface. 11267c478bd9Sstevel@tonic-gate * 11277c478bd9Sstevel@tonic-gate * Note: the nca_conn_t can have up to 3 NODE_REFHOLDs: 11287c478bd9Sstevel@tonic-gate * 11297c478bd9Sstevel@tonic-gate * 1) if req_np != NULL then a NODE_REFHOLD(req_np) was done: 11307c478bd9Sstevel@tonic-gate * 11317c478bd9Sstevel@tonic-gate * 1.1) if http_refed then a NODE_REFHOLD(req_np) was done 11327c478bd9Sstevel@tonic-gate * 11337c478bd9Sstevel@tonic-gate * 1.2) if http_frefed then a NODE_REFHOLD(req_np->fileback) was done 11347c478bd9Sstevel@tonic-gate * 11357c478bd9Sstevel@tonic-gate * 11367c478bd9Sstevel@tonic-gate * TODO: reorder elements in fast-path code access order. 11377c478bd9Sstevel@tonic-gate * 11387c478bd9Sstevel@tonic-gate * Dnn4XnXXDnnDnnXXXnnXXXnnUXnnXXXnnXXnnDDXXXDXDXDXnnDnnXXDDnXXXDDnnXXXDDnn 11397c478bd9Sstevel@tonic-gate * XXXDDnnXXXDDnnXXXDDnnXXnnDXXnn 11407c478bd9Sstevel@tonic-gate * b+++DDnAnDDDDDnnDnnUnnUUDXDUnnDnn20xnnXnnddnnUUUnnXXUnXXnnUUUnn 11417c478bd9Sstevel@tonic-gate * DDDDDDnnUUnnXXUXUnn4UD4Unn4UnUUnn 11427c478bd9Sstevel@tonic-gate * 64-bit: Xnn4+4pnnppEnEnn3pnn3pnnEJnnXXnnuunn4+ppnnXX3pD4+pD4+pD4+pnnEnnppnnD 11437c478bd9Sstevel@tonic-gate */ 11447c478bd9Sstevel@tonic-gate 11457c478bd9Sstevel@tonic-gate #define TCP_XMIT_MAX_IX 5 /* Max xmit descriptors */ 11467c478bd9Sstevel@tonic-gate 11478793b36bSNick Todd typedef struct nca_conn_s { 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate int32_t ref; /* Reference counter */ 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate te_t tcp_ti; /* TCP TIMER timer entry */ 11527c478bd9Sstevel@tonic-gate 11538793b36bSNick Todd struct nca_conn_s *twnext; /* TIME_WAIT next */ 11548793b36bSNick Todd struct nca_conn_s *twprev; /* TIME_WAIT prev */ 11557c478bd9Sstevel@tonic-gate clock_t twlbolt; /* TIME_WAIT lbolt */ 11567c478bd9Sstevel@tonic-gate 11577c478bd9Sstevel@tonic-gate clock_t create; /* Create lbolt time */ 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate connf_t *hashfanout; /* Hash bucket we're part of */ 11608793b36bSNick Todd struct nca_conn_s *hashnext; /* Hash chain next */ 11618793b36bSNick Todd struct nca_conn_s *hashprev; /* Hash chain prev */ 11627c478bd9Sstevel@tonic-gate 11638793b36bSNick Todd struct nca_conn_s *bindnext; /* Next conn_s in bind list. */ 11648793b36bSNick Todd struct nca_conn_s *bindprev; /* Prev conn_s in bind list. */ 11657c478bd9Sstevel@tonic-gate void *tbf; /* Pointer to bind hash list struct. */ 11667c478bd9Sstevel@tonic-gate /* 11677c478bd9Sstevel@tonic-gate * Note: atomic access of memebers above is guaranteed by the 11687c478bd9Sstevel@tonic-gate * hashfanout->lock of the hash bucket that the nca_conn_t is in. 11697c478bd9Sstevel@tonic-gate */ 11707c478bd9Sstevel@tonic-gate 11717c478bd9Sstevel@tonic-gate size_t mac_length; /* MAC prepend length */ 11727c478bd9Sstevel@tonic-gate mblk_t *mac_mp; /* MAC prepend data */ 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate ipaddr_t laddr; /* Local address */ 11757c478bd9Sstevel@tonic-gate ipaddr_t faddr; /* Remote address. 0 => not connected */ 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate union { 11787c478bd9Sstevel@tonic-gate struct { 11797c478bd9Sstevel@tonic-gate uint16_t u_fport; /* Remote port */ 11807c478bd9Sstevel@tonic-gate uint16_t u_lport; /* Local port */ 11817c478bd9Sstevel@tonic-gate } u_ports1; 11827c478bd9Sstevel@tonic-gate uint32_t u_ports2; /* Rem port, local port */ 11837c478bd9Sstevel@tonic-gate /* Used for TCP_MATCH performance */ 11847c478bd9Sstevel@tonic-gate } u_port; 11857c478bd9Sstevel@tonic-gate #define conn_lport u_port.u_ports1.u_lport 11867c478bd9Sstevel@tonic-gate #define conn_fport u_port.u_ports1.u_fport 11877c478bd9Sstevel@tonic-gate #define conn_ports u_port.u_ports2 11887c478bd9Sstevel@tonic-gate 11897c478bd9Sstevel@tonic-gate if_t *ifp; /* Interface for this connection */ 11907c478bd9Sstevel@tonic-gate nca_squeue_t *inq; /* Per CPU inq for this connection */ 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate uint32_t req_tag; /* nca_io_t request tag (0 == NONE) */ 11937c478bd9Sstevel@tonic-gate int req_parse; /* HTTP request parse state */ 11947c478bd9Sstevel@tonic-gate node_t *req_np; /* HTTP request node_t */ 11957c478bd9Sstevel@tonic-gate mblk_t *req_mp; /* HTTP request mblk_t */ 11967c478bd9Sstevel@tonic-gate char *reqpath; /* HTTP request URI path component */ 11977c478bd9Sstevel@tonic-gate int reqpathsz; /* size of above */ 11987c478bd9Sstevel@tonic-gate char *reqrefer; /* HTTP "Referer:" string */ 11997c478bd9Sstevel@tonic-gate int reqrefersz; /* size of above */ 12007c478bd9Sstevel@tonic-gate char *requagent; /* HTTP "User-Agent:" string */ 12017c478bd9Sstevel@tonic-gate int requagentsz; /* size of above */ 12028793b36bSNick Todd struct nca_conn_s *nodenext; /* Node_t nca_conn_t list */ 12037c478bd9Sstevel@tonic-gate 12047c478bd9Sstevel@tonic-gate clock_t http_count; /* HTTP Keep-Alive request count */ 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate /* 12077c478bd9Sstevel@tonic-gate * req_np xmit state used accross calls to tcp_xmit(). A reference 12087c478bd9Sstevel@tonic-gate * to the req_np and to any inderect node_t (i.e. file/ctag) ... 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate node_t *xmit_refed; /* have a ref to the uri node_t */ 12117c478bd9Sstevel@tonic-gate node_t *xmit_cur; /* current node to transmit */ 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate int xmit_ix; /* current xmit[] index */ 12147c478bd9Sstevel@tonic-gate int xmit_pix; /* past end xmit[] index */ 12157c478bd9Sstevel@tonic-gate 12167c478bd9Sstevel@tonic-gate struct { 12177c478bd9Sstevel@tonic-gate node_t *np; /* node_t pointer for ref */ 12187c478bd9Sstevel@tonic-gate char *dp; /* data pointer */ 12197c478bd9Sstevel@tonic-gate uint16_t *cp; /* cksum array */ 12207c478bd9Sstevel@tonic-gate int sz; /* remaining data to xmit */ 12217c478bd9Sstevel@tonic-gate int iso; /* initial segment offset (if any) */ 12227c478bd9Sstevel@tonic-gate node_t *refed; /* have a ref to the node_t */ 12237c478bd9Sstevel@tonic-gate int dsz; /* remaining data for current segment */ 12247c478bd9Sstevel@tonic-gate caddr_t *dvp; /* data segment virtual pointer */ 12257c478bd9Sstevel@tonic-gate } xmit[TCP_XMIT_MAX_IX]; 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate /* 12287c478bd9Sstevel@tonic-gate * Connection NCA_IO_DIRECT_SPLICE & NCA_IO_DIRECT_TEE reference, 12297c478bd9Sstevel@tonic-gate * see direct_splice and direct_tee below for type of send too. 12307c478bd9Sstevel@tonic-gate */ 12318793b36bSNick Todd struct nca_conn_s *direct; /* nca_conn_t to send recv data too */ 12327c478bd9Sstevel@tonic-gate mblk_t *direct_mp; /* mblk_t to use for tcp_close() */ 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate /* 12357c478bd9Sstevel@tonic-gate * nca_conn_t state. 12367c478bd9Sstevel@tonic-gate */ 12377c478bd9Sstevel@tonic-gate 12387c478bd9Sstevel@tonic-gate int32_t tcp_state; 12397c478bd9Sstevel@tonic-gate 12407c478bd9Sstevel@tonic-gate uint32_t 12417c478bd9Sstevel@tonic-gate tcp_urp_last_valid : 1, /* Is tcp_urp_last valid? */ 12427c478bd9Sstevel@tonic-gate tcp_hard_binding : 1, /* If we've started a full bind */ 12437c478bd9Sstevel@tonic-gate tcp_hard_bound : 1, /* If we've done a full bind with IP */ 12447c478bd9Sstevel@tonic-gate tcp_fin_acked : 1, /* Has our FIN been acked? */ 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate tcp_fin_rcvd : 1, /* Have we seen a FIN? */ 12477c478bd9Sstevel@tonic-gate tcp_fin_sent : 1, /* Have we sent our FIN yet? */ 12487c478bd9Sstevel@tonic-gate tcp_ordrel_done : 1, /* Have we sent the ord_rel upstream? */ 12497c478bd9Sstevel@tonic-gate tcp_flow_stopped : 1, /* Have we flow controlled xmitter? */ 12507c478bd9Sstevel@tonic-gate 12517c478bd9Sstevel@tonic-gate tcp_debug : 1, /* SO_DEBUG "socket" option. */ 12527c478bd9Sstevel@tonic-gate tcp_dontroute : 1, /* SO_DONTROUTE "socket" option. */ 12537c478bd9Sstevel@tonic-gate tcp_broadcast : 1, /* SO_BROADCAST "socket" option. */ 12547c478bd9Sstevel@tonic-gate tcp_useloopback : 1, /* SO_USELOOPBACK "socket" option. */ 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate tcp_oobinline : 1, /* SO_OOBINLINE "socket" option. */ 12577c478bd9Sstevel@tonic-gate tcp_dgram_errind : 1, /* SO_DGRAM_ERRIND option */ 12587c478bd9Sstevel@tonic-gate tcp_detached : 1, /* If we're detached from a stream */ 12597c478bd9Sstevel@tonic-gate tcp_bind_pending : 1, /* Client is waiting for bind ack */ 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate tcp_unbind_pending : 1, /* Client sent T_UNBIND_REQ */ 12627c478bd9Sstevel@tonic-gate tcp_deferred_clean_death : 1, 12637c478bd9Sstevel@tonic-gate /* defer tcp endpoint cleanup etc. */ 12647c478bd9Sstevel@tonic-gate tcp_co_wakeq_done : 1, /* A strwakeq() has been done */ 12657c478bd9Sstevel@tonic-gate tcp_co_wakeq_force : 1, /* A strwakeq() must be done */ 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate tcp_co_norm : 1, /* In normal mode, putnext() done */ 12687c478bd9Sstevel@tonic-gate tcp_co_wakeq_need : 1, /* A strwakeq() needs to be done */ 12697c478bd9Sstevel@tonic-gate tcp_snd_ws_ok : 1, /* Received WSCALE from peer */ 12707c478bd9Sstevel@tonic-gate tcp_snd_ts_ok : 1, /* Received TSTAMP from peer */ 12717c478bd9Sstevel@tonic-gate 12727c478bd9Sstevel@tonic-gate tcp_linger : 1, /* SO_LINGER turned on */ 12737c478bd9Sstevel@tonic-gate tcp_zero_win_probe: 1, /* Zero win probing is in progress */ 12747c478bd9Sstevel@tonic-gate tcp_loopback: 1, /* src and dst are the same machine */ 12757c478bd9Sstevel@tonic-gate tcp_localnet: 1, /* src and dst are on the same subnet */ 12767c478bd9Sstevel@tonic-gate 12777c478bd9Sstevel@tonic-gate tcp_syn_defense: 1, /* For defense against SYN attack */ 12787c478bd9Sstevel@tonic-gate #define tcp_dontdrop tcp_syn_defense 12797c478bd9Sstevel@tonic-gate tcp_set_timer : 1, 12807c478bd9Sstevel@tonic-gate tcp_1_junk_fill_thru_bit_31 : 2; 12817c478bd9Sstevel@tonic-gate 12827c478bd9Sstevel@tonic-gate uint32_t 12837c478bd9Sstevel@tonic-gate tcp_active_open: 1, /* This is a active open */ 12847c478bd9Sstevel@tonic-gate tcp_timeout : 1, /* qbufcall failed, qtimeout pending */ 12857c478bd9Sstevel@tonic-gate tcp_rexmit : 1, /* TCP is retransmitting */ 12867c478bd9Sstevel@tonic-gate tcp_snd_sack_ok : 1, /* Can use SACK for this connection */ 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate tcp_bind_proxy_addr : 1, /* proxy addr is being used */ 12897c478bd9Sstevel@tonic-gate tcp_recvdstaddr : 1, /* return T_EXTCONN_IND with dst addr */ 12907c478bd9Sstevel@tonic-gate tcp_refed : 1, /* nca_conn_t refed by TCP */ 12917c478bd9Sstevel@tonic-gate tcp_time_wait_comp : 1, /* TIME_WAIT compressed nca_conn_t */ 12927c478bd9Sstevel@tonic-gate 12937c478bd9Sstevel@tonic-gate tcp_close : 1, /* nca_conn_t close */ 12947c478bd9Sstevel@tonic-gate http_persist : 3, /* HTTP persistent connection state */ 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate deferred_xmit_end : 1, /* xmit_end() deferred to xmit() */ 12977c478bd9Sstevel@tonic-gate http_direct_splice : 1, /* have a connection to splice too */ 12987c478bd9Sstevel@tonic-gate http_direct_tee : 1, /* have a connection to tee too */ 12997c478bd9Sstevel@tonic-gate 13007c478bd9Sstevel@tonic-gate tcp_2_junk_fill_thru_bit_31 : 17; 13017c478bd9Sstevel@tonic-gate /* 13027c478bd9Sstevel@tonic-gate * Note: all nca_conn_t members to be accessed by a tcp_time_wait_comp 13037c478bd9Sstevel@tonic-gate * nca_conn_t must be above this point !!! 13047c478bd9Sstevel@tonic-gate */ 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate uchar_t tcp_timer_backoff; /* Backoff shift count. */ 13077c478bd9Sstevel@tonic-gate clock_t tcp_last_recv_time; /* Last time we receive a segment. */ 13087c478bd9Sstevel@tonic-gate clock_t tcp_dack_set_time; /* When delayed ACK timer is set. */ 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate int tcp_ip_hdr_len; /* Byte len of our current IP header */ 13117c478bd9Sstevel@tonic-gate clock_t tcp_first_timer_threshold; /* When to prod IP */ 13127c478bd9Sstevel@tonic-gate clock_t tcp_second_timer_threshold; /* When to give up completely */ 13137c478bd9Sstevel@tonic-gate clock_t tcp_first_ctimer_threshold; /* 1st threshold while connecting */ 13147c478bd9Sstevel@tonic-gate clock_t tcp_second_ctimer_threshold; /* 2nd ... while connecting */ 13157c478bd9Sstevel@tonic-gate 13167c478bd9Sstevel@tonic-gate clock_t tcp_last_rcv_lbolt; /* lbolt on last packet, used for PAWS */ 13177c478bd9Sstevel@tonic-gate 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate uint32_t tcp_obsegs; /* Outbound segments on this stream */ 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate uint32_t tcp_mss; /* Max segment size */ 13227c478bd9Sstevel@tonic-gate uint32_t tcp_naglim; /* Tunable nagle limit */ 13237c478bd9Sstevel@tonic-gate int32_t tcp_hdr_len; /* Byte len of combined TCP/IP hdr */ 13247c478bd9Sstevel@tonic-gate tcph_t *tcp_tcph; /* tcp header within combined hdr */ 13257c478bd9Sstevel@tonic-gate int32_t tcp_tcp_hdr_len; /* tcp header len within combined */ 13267c478bd9Sstevel@tonic-gate uint32_t tcp_valid_bits; 13277c478bd9Sstevel@tonic-gate #define TCP_ISS_VALID 0x1 /* Is the tcp_iss seq num active? */ 13287c478bd9Sstevel@tonic-gate #define TCP_FSS_VALID 0x2 /* Is the tcp_fss seq num active? */ 13297c478bd9Sstevel@tonic-gate #define TCP_URG_VALID 0x4 /* If the tcp_urg seq num active? */ 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate int32_t tcp_xmit_hiwater; /* Send buffer high water mark. */ 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate union { /* template ip header */ 13347c478bd9Sstevel@tonic-gate ipha_t tcp_u_ipha; 13357c478bd9Sstevel@tonic-gate char tcp_u_buf[IP_SIMPLE_HDR_LENGTH+TCP_MIN_HEADER_LENGTH]; 13367c478bd9Sstevel@tonic-gate double tcp_u_aligner; 13377c478bd9Sstevel@tonic-gate } tcp_u; 13387c478bd9Sstevel@tonic-gate #define tcp_ipha tcp_u.tcp_u_ipha 13397c478bd9Sstevel@tonic-gate #define tcp_iphc tcp_u.tcp_u_buf 13407c478bd9Sstevel@tonic-gate 13417c478bd9Sstevel@tonic-gate uint32_t tcp_sum; /* checksum to compensate for source */ 13427c478bd9Sstevel@tonic-gate /* routed packets. Host byte order */ 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate uint16_t tcp_last_sent_len; /* Record length for nagle */ 13457c478bd9Sstevel@tonic-gate uint16_t tcp_dupack_cnt; /* # of consequtive duplicate acks */ 13467c478bd9Sstevel@tonic-gate 13477c478bd9Sstevel@tonic-gate uint32_t tcp_rnxt; /* Seq we expect to recv next */ 13487c478bd9Sstevel@tonic-gate uint32_t tcp_rwnd; /* Current receive window */ 13497c478bd9Sstevel@tonic-gate uint32_t tcp_rwnd_max; /* Maximum receive window */ 13507c478bd9Sstevel@tonic-gate 13517c478bd9Sstevel@tonic-gate mblk_t *tcp_rcv_head; /* Queued until push, urgent data or */ 13527c478bd9Sstevel@tonic-gate mblk_t *tcp_rcv_tail; /* the count exceeds */ 13537c478bd9Sstevel@tonic-gate uint32_t tcp_rcv_cnt; /* tcp_rcv_push_wait. */ 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate mblk_t *tcp_reass_head; /* Out of order reassembly list head */ 13567c478bd9Sstevel@tonic-gate mblk_t *tcp_reass_tail; /* Out of order reassembly list tail */ 13577c478bd9Sstevel@tonic-gate 13587c478bd9Sstevel@tonic-gate uint32_t tcp_cwnd_ssthresh; /* Congestion window */ 13597c478bd9Sstevel@tonic-gate uint32_t tcp_cwnd_max; 13607c478bd9Sstevel@tonic-gate uint32_t tcp_csuna; /* Clear (no rexmits in window) suna */ 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate int tcp_rttv_updates; 13637c478bd9Sstevel@tonic-gate clock_t tcp_rto; /* Round trip timeout */ 13647c478bd9Sstevel@tonic-gate clock_t tcp_rtt_sa; /* Round trip smoothed average */ 13657c478bd9Sstevel@tonic-gate clock_t tcp_rtt_sd; /* Round trip smoothed deviation */ 13667c478bd9Sstevel@tonic-gate clock_t tcp_rtt_update; /* Round trip update(s) */ 13677c478bd9Sstevel@tonic-gate clock_t tcp_ms_we_have_waited; /* Total retrans time */ 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate uint32_t tcp_swl1; /* These help us avoid using stale */ 13707c478bd9Sstevel@tonic-gate uint32_t tcp_swl2; /* packets to update state */ 13717c478bd9Sstevel@tonic-gate 13727c478bd9Sstevel@tonic-gate mblk_t *tcp_xmit_head; /* Head of rexmit list */ 13737c478bd9Sstevel@tonic-gate mblk_t *tcp_xmit_last; /* last valid data seen by tcp_wput */ 13747c478bd9Sstevel@tonic-gate uint32_t tcp_unsent; /* # of bytes in hand that are unsent */ 13757c478bd9Sstevel@tonic-gate mblk_t *tcp_xmit_tail; /* Last rexmit data sent */ 13767c478bd9Sstevel@tonic-gate uint32_t tcp_xmit_tail_unsent; /* # of unsent bytes in xmit_tail */ 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate uint32_t tcp_snxt; /* Senders next seq num */ 13797c478bd9Sstevel@tonic-gate uint32_t tcp_suna; /* Sender unacknowledged */ 13807c478bd9Sstevel@tonic-gate uint32_t tcp_rexmit_nxt; /* Next rexmit seq num */ 13817c478bd9Sstevel@tonic-gate uint32_t tcp_rexmit_max; /* Max retran seq num */ 13827c478bd9Sstevel@tonic-gate int32_t tcp_snd_burst; /* Send burst factor */ 13837c478bd9Sstevel@tonic-gate uint32_t tcp_swnd; /* Senders window (relative to suna) */ 13847c478bd9Sstevel@tonic-gate uint32_t tcp_cwnd; /* Congestion window */ 13857c478bd9Sstevel@tonic-gate int32_t tcp_cwnd_cnt; /* cwnd cnt in congestion avoidance */ 13867c478bd9Sstevel@tonic-gate uint32_t tcp_ackonly; /* Senders last ack seq num */ 13877c478bd9Sstevel@tonic-gate 13887c478bd9Sstevel@tonic-gate uint32_t tcp_irs; /* Initial recv seq num */ 13897c478bd9Sstevel@tonic-gate uint32_t tcp_iss; /* Initial send seq num */ 13907c478bd9Sstevel@tonic-gate uint32_t tcp_fss; /* Final/fin send seq num */ 13917c478bd9Sstevel@tonic-gate uint32_t tcp_urg; /* Urgent data seq num */ 13927c478bd9Sstevel@tonic-gate 13937c478bd9Sstevel@tonic-gate uint32_t tcp_rack; /* Seq # we have acked */ 13947c478bd9Sstevel@tonic-gate uint32_t tcp_rack_cnt; /* # of bytes we have deferred ack */ 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate uint32_t tcp_max_swnd; /* Maximum swnd we have seen */ 13977c478bd9Sstevel@tonic-gate int64_t tcp_rexmit_fire_time; 13987c478bd9Sstevel@tonic-gate int64_t tcp_dack_fire_time; 13997c478bd9Sstevel@tonic-gate int64_t tcp_ka_fire_time; 14007c478bd9Sstevel@tonic-gate int64_t tcp_http_ka_fire_time; 14017c478bd9Sstevel@tonic-gate 14027c478bd9Sstevel@tonic-gate int32_t tcp_keepalive_intrvl; /* Zero means don't bother */ 14037c478bd9Sstevel@tonic-gate int32_t tcp_ka_probe_sent; 14047c478bd9Sstevel@tonic-gate int32_t tcp_ka_last_intrvl; 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate #define TCP_DACK_TIMER 0x1 14077c478bd9Sstevel@tonic-gate #define TCP_REXMIT_TIMER 0x2 14087c478bd9Sstevel@tonic-gate #define TCP_KA_TIMER 0x4 14097c478bd9Sstevel@tonic-gate #define TCP_HTTP_KA_TIMER 0x8 14107c478bd9Sstevel@tonic-gate int16_t tcp_running_timer; 14117c478bd9Sstevel@tonic-gate int16_t tcp_pending_timer; 14127c478bd9Sstevel@tonic-gate 14137c478bd9Sstevel@tonic-gate #ifdef CONNP_T_TRACE_ON 14147c478bd9Sstevel@tonic-gate connp_t *pkt_tp; /* Packet tracing pointer */ 14157c478bd9Sstevel@tonic-gate connp_t pkt_tv[CONNP_TV_SZ]; /* Packet tracing vector */ 14167c478bd9Sstevel@tonic-gate #endif /* CONNP_T_TRACE_ON */ 14177c478bd9Sstevel@tonic-gate 14187c478bd9Sstevel@tonic-gate } nca_conn_t; 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate /* 14217c478bd9Sstevel@tonic-gate * Active stack support parameters to control what ports NCA can use. 14227c478bd9Sstevel@tonic-gate * They are declared in ncaproto.c 14237c478bd9Sstevel@tonic-gate */ 14247c478bd9Sstevel@tonic-gate extern struct nca_tbf_s *nca_tcp_port; 14257c478bd9Sstevel@tonic-gate extern in_port_t tcp_lo_port; 14267c478bd9Sstevel@tonic-gate extern in_port_t tcp_hi_port; 14277c478bd9Sstevel@tonic-gate 14287c478bd9Sstevel@tonic-gate /* 14297c478bd9Sstevel@tonic-gate * nca_conn_t.http_persist values and corresponding HTTP header strings are 14307c478bd9Sstevel@tonic-gate * used to determine the connection persistent state of a connection and 14317c478bd9Sstevel@tonic-gate * any HTTP header which needs to be sent. 14327c478bd9Sstevel@tonic-gate */ 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate #define PERSIST_NONE 0 /* Not persistent */ 14357c478bd9Sstevel@tonic-gate 14367c478bd9Sstevel@tonic-gate #define PERSIST_CLOSE 1 /* Was persistent, send close header */ 14377c478bd9Sstevel@tonic-gate #define PERSIST_TRUE 2 /* Connection is HTTP persistent */ 14387c478bd9Sstevel@tonic-gate #define PERSIST_KA 3 /* Persistent, send Keep-Alive header */ 14397c478bd9Sstevel@tonic-gate #define PERSIST_UPCALL 4 /* Insert "Connection: close" on */ 14407c478bd9Sstevel@tonic-gate /* upcall and clear flag */ 14417c478bd9Sstevel@tonic-gate 14427c478bd9Sstevel@tonic-gate #define PERSIST_HDR_NONE "\r\n" 14437c478bd9Sstevel@tonic-gate #define PERSIST_HDR_CLOSE "Connection: close\r\n\r\n" 14447c478bd9Sstevel@tonic-gate #define PERSIST_HDR_KA "Connection: Keep-Alive\r\n\r\n" 14457c478bd9Sstevel@tonic-gate 14467c478bd9Sstevel@tonic-gate /* 14477c478bd9Sstevel@tonic-gate * nca_conn_t nca_squeue_ctl() flag values: 14487c478bd9Sstevel@tonic-gate */ 14497c478bd9Sstevel@tonic-gate 14507c478bd9Sstevel@tonic-gate #define CONN_MISS_DONE 0x0001 /* The conn miss processing is done */ 14517c478bd9Sstevel@tonic-gate #define IF_TIME_WAIT 0x0002 /* A TIME_WAIT has fired */ 14527c478bd9Sstevel@tonic-gate #define IF_TCP_TIMER 0x0003 /* A TCP TIMER has fired */ 14537c478bd9Sstevel@tonic-gate #define NCA_CONN_TCP_TIMER 0x0004 /* A TCP TIMER needs to be execed */ 14547c478bd9Sstevel@tonic-gate #define IF_TCP_CONNECT 0x0005 /* TCP connection request */ 14557c478bd9Sstevel@tonic-gate #define IF_TCP_SEND 0x0006 /* A new send request. */ 14567c478bd9Sstevel@tonic-gate 14577c478bd9Sstevel@tonic-gate #define IF_TCP_DIRECT_TO 0x0010 /* A TCP direct i/o, step 1 */ 14587c478bd9Sstevel@tonic-gate #define IF_TCP_DIRECT_FROM 0x0012 /* A TCP direct i/o, step 2 */ 14597c478bd9Sstevel@tonic-gate #define IF_TCP_DIRECT_TEE 0x0001 /* If a tee else a splice */ 14607c478bd9Sstevel@tonic-gate #define IF_TCP_DIRECT_CLOSE 0x001F /* A TCP direct i/o close */ 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate #define NCA_CONN_T_STK_DEPTH 7 /* max stack backtrace depth */ 14637c478bd9Sstevel@tonic-gate 14647c478bd9Sstevel@tonic-gate struct conn_ts { 14657c478bd9Sstevel@tonic-gate nca_conn_t *conn; 14667c478bd9Sstevel@tonic-gate unsigned action; 14677c478bd9Sstevel@tonic-gate int ref; 14687c478bd9Sstevel@tonic-gate int cpu; 14697c478bd9Sstevel@tonic-gate pc_t stk[NCA_CONN_T_STK_DEPTH + 1]; 14707c478bd9Sstevel@tonic-gate }; 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate #undef NCA_CONN_T_TRACE_ON 14737c478bd9Sstevel@tonic-gate 14747c478bd9Sstevel@tonic-gate #ifdef NCA_CONN_T_TRACE_ON 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate /* 14777c478bd9Sstevel@tonic-gate * adb: 14787c478bd9Sstevel@tonic-gate * 32 bit 14797c478bd9Sstevel@tonic-gate * *conn_tp,0t4096-(((*conn_tp)-con_tv)%0t48)/PXDDnPnPnPnPnPnPnPnPnn 14807c478bd9Sstevel@tonic-gate * con_tv,((*conn_tp)-con_tv)%0t48/PXDDnPnPnPnPnPnPnPnPnn 14817c478bd9Sstevel@tonic-gate * 64 bit 14827c478bd9Sstevel@tonic-gate * *conn_tp,0t4096-(((*conn_tp)-con_tv)%0t56)/PXDDnXnXnXnXnXnXnXnXnn 14837c478bd9Sstevel@tonic-gate * con_tv,((*conn_tp)-con_tv)%0t56/PXDDnXnXnXnXnXnXnXnXnn 14847c478bd9Sstevel@tonic-gate */ 14857c478bd9Sstevel@tonic-gate 14867c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFINIT 0x10000000 /* CONN_REF init() |ref value */ 14877c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFINIT1 0x11000000 /* CONN_REF init() |ref value */ 14887c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFINIT2 0x12000000 /* CONN_REF init() |ref value */ 14897c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFNOTCP 0x13000000 /* CONN_REF no longer tcp_refed */ 14907c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFHOLD 0x1A000000 /* CONN_REFHOLD() | ref value */ 14917c478bd9Sstevel@tonic-gate #define NCA_CONN_T_REFRELE 0x1F000000 /* CONN_REFRELE() | ref value */ 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate #define NCA_CONN_T_HTTPCALL 0x20000000 /* call http() | rbytes */ 14947c478bd9Sstevel@tonic-gate #define NCA_CONN_T_HTTPRET1 0x21000000 /* return http() */ 14957c478bd9Sstevel@tonic-gate #define NCA_CONN_T_HTTPRET2 0x22000000 /* return ! http() */ 14967c478bd9Sstevel@tonic-gate 14977c478bd9Sstevel@tonic-gate #define NCA_CONN_T_MISSDONE 0x30000000 /* CONN_MISS_DONE */ 14987c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TCPTIMER 0x31000000 /* NCA_CONN_TCP_TIMER */ 14997c478bd9Sstevel@tonic-gate #define NCA_CONN_T_XMIT_END 0x32000000 /* xmit_end() | tcp_unsent */ 15007c478bd9Sstevel@tonic-gate #define NCA_CONN_T_XMIT_BAD 0x33000000 /* xmit_end() bad state |tcp_state */ 15017c478bd9Sstevel@tonic-gate #define NCA_CONN_T_XMIT_DEF 0x34000000 /* xmit_end() deferred */ 15027c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TIME_WAIT 0x35000000 /* done: tcp_state == TCPS_TIME_WAIT */ 15037c478bd9Sstevel@tonic-gate #define NCA_CONN_T_PKT_IN 0x36000000 /* tcp_input() | flags */ 15047c478bd9Sstevel@tonic-gate #define NCA_CONN_T_PKT_OUT 0x37000000 /* tcp_input() | flags */ 15057c478bd9Sstevel@tonic-gate 15067c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT 0x40000000 /* tcp_direct() from conn_t */ 15077c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT1 0x41000000 /* tcp_direct() to conn_t */ 15087c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT2 0x42000000 /* IF_TCP_DIRECT_TO | TEE */ 15097c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT3 0x43000000 /* IF_TCP_DIRECT_FROM | TEE */ 15107c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT4 0x44000000 /* tcp_close() */ 15117c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT5 0x45000000 /* IF_TCP_DIRECT_CLOSE */ 15127c478bd9Sstevel@tonic-gate /* from|tcp_state */ 15137c478bd9Sstevel@tonic-gate #define NCA_CONN_T_DIRECT6 0x46000000 /* IF_TCP_DIRECT_CLOSE to */ 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 15167c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TRACE_STK() { \ 15177c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[0], NCA_CONN_T_STK_DEPTH + 1); \ 15187c478bd9Sstevel@tonic-gate if (_ix < NCA_CONN_T_STK_DEPTH + 1) { \ 15197c478bd9Sstevel@tonic-gate _p->stk[_ix + 1] = 0; \ 15207c478bd9Sstevel@tonic-gate } \ 15217c478bd9Sstevel@tonic-gate } 15227c478bd9Sstevel@tonic-gate #else 15237c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TRACE_STK() { \ 15247c478bd9Sstevel@tonic-gate _p->stk[0] = (pc_t)callee(); \ 15257c478bd9Sstevel@tonic-gate _ix = getpcstack(&_p->stk[1], NCA_CONN_T_STK_DEPTH); \ 15267c478bd9Sstevel@tonic-gate if (_ix < NCA_CONN_T_STK_DEPTH) { \ 15277c478bd9Sstevel@tonic-gate _p->stk[_ix + 1] = 0; \ 15287c478bd9Sstevel@tonic-gate } \ 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate #endif 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate #define CON_TV_SZ 4096 15337c478bd9Sstevel@tonic-gate 15347c478bd9Sstevel@tonic-gate extern struct conn_ts con_tv[CON_TV_SZ]; 15357c478bd9Sstevel@tonic-gate extern struct conn_ts *conn_tp; 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TRACE(p, a) { \ 15387c478bd9Sstevel@tonic-gate struct conn_ts *_p; \ 15397c478bd9Sstevel@tonic-gate struct conn_ts *_np; \ 15407c478bd9Sstevel@tonic-gate int _ix; \ 15417c478bd9Sstevel@tonic-gate \ 15427c478bd9Sstevel@tonic-gate do { \ 15437c478bd9Sstevel@tonic-gate _p = conn_tp; \ 15447c478bd9Sstevel@tonic-gate if ((_np = _p + 1) == &con_tv[CON_TV_SZ]) \ 15457c478bd9Sstevel@tonic-gate _np = con_tv; \ 154675d94465SJosef 'Jeff' Sipek } while (atomic_cas_ptr(&conn_tp, _p, _np) != _p); \ 15477c478bd9Sstevel@tonic-gate _p->conn = (p); \ 15487c478bd9Sstevel@tonic-gate _p->action = (a); \ 15497c478bd9Sstevel@tonic-gate _p->ref = (p)->ref; \ 15507c478bd9Sstevel@tonic-gate _p->cpu = CPU->cpu_seqid; \ 15517c478bd9Sstevel@tonic-gate NCA_CONN_T_TRACE_STK(); \ 15527c478bd9Sstevel@tonic-gate } 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate #else /* NCA_CONN_T_TRACE_ON */ 15557c478bd9Sstevel@tonic-gate 15567c478bd9Sstevel@tonic-gate #define NCA_CONN_T_TRACE(p, a) 15577c478bd9Sstevel@tonic-gate 15587c478bd9Sstevel@tonic-gate #endif /* NCA_CONN_T_TRACE_ON */ 15597c478bd9Sstevel@tonic-gate 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate #define CONN_REFHOLD(connp) { \ 15627c478bd9Sstevel@tonic-gate \ 15637c478bd9Sstevel@tonic-gate NCA_CONN_T_TRACE((connp), NCA_CONN_T_REFHOLD | ((connp)->ref + 1)); \ 15647c478bd9Sstevel@tonic-gate \ 15657c478bd9Sstevel@tonic-gate if ((connp)->ref <= 0) \ 15667c478bd9Sstevel@tonic-gate panic("nca CONN_REFHOLD: %p has no references", \ 15677c478bd9Sstevel@tonic-gate (void *)(connp)); \ 15687c478bd9Sstevel@tonic-gate (connp)->ref++; \ 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate 15717c478bd9Sstevel@tonic-gate #define CONN_REFRELE(connp) { \ 15727c478bd9Sstevel@tonic-gate \ 15737c478bd9Sstevel@tonic-gate NCA_CONN_T_TRACE((connp), NCA_CONN_T_REFRELE | ((connp)->ref - 1)); \ 15747c478bd9Sstevel@tonic-gate \ 15757c478bd9Sstevel@tonic-gate if ((connp)->tcp_refed) { \ 15767c478bd9Sstevel@tonic-gate if ((connp)->ref == 1) \ 15777c478bd9Sstevel@tonic-gate panic("nca CONN_REFRELE: %p " \ 15787c478bd9Sstevel@tonic-gate "has only tcp_refed reference", \ 15797c478bd9Sstevel@tonic-gate (void *)(connp)); \ 15807c478bd9Sstevel@tonic-gate if ((connp)->ref < 1) \ 15817c478bd9Sstevel@tonic-gate panic("nca CONN_REFRELE: %p has no references", \ 15827c478bd9Sstevel@tonic-gate (void *)(connp)); \ 15837c478bd9Sstevel@tonic-gate } else { \ 15847c478bd9Sstevel@tonic-gate if ((connp)->ref <= 0) \ 15857c478bd9Sstevel@tonic-gate panic("nca CONN_REFRELE: %p has no references", \ 15867c478bd9Sstevel@tonic-gate (void *)(connp)); \ 15877c478bd9Sstevel@tonic-gate } \ 15887c478bd9Sstevel@tonic-gate (connp)->ref--; \ 15897c478bd9Sstevel@tonic-gate if ((connp)->ref == 0) { \ 15907c478bd9Sstevel@tonic-gate /* Last ref of a nca_conn_t, so free it */ \ 15917c478bd9Sstevel@tonic-gate kmutex_t *lock = &(connp)->hashfanout->lock; \ 15927c478bd9Sstevel@tonic-gate mutex_enter(lock); \ 15937c478bd9Sstevel@tonic-gate nca_conn_free(connp); \ 15947c478bd9Sstevel@tonic-gate /* Note: nca_conn_free exits lock */ \ 15957c478bd9Sstevel@tonic-gate } \ 15967c478bd9Sstevel@tonic-gate } 15977c478bd9Sstevel@tonic-gate 15987c478bd9Sstevel@tonic-gate /* 15997c478bd9Sstevel@tonic-gate * The nca_io2_shadow_t is used by the kernel to contian a copy of a user- 16007c478bd9Sstevel@tonic-gate * land nca_io2_t and the the user-land nca_io2_t address and size. 16017c478bd9Sstevel@tonic-gate */ 16027c478bd9Sstevel@tonic-gate 16037c478bd9Sstevel@tonic-gate typedef struct nca_io2_shadow_s { 16047c478bd9Sstevel@tonic-gate nca_io2_t io; /* copy of user-land nca_io2_t */ 16057c478bd9Sstevel@tonic-gate void *data_ptr; /* copy of door_arg_t.data_ptr */ 16067c478bd9Sstevel@tonic-gate size_t data_size; /* copy of door_arg_t.data_size */ 16077c478bd9Sstevel@tonic-gate } nca_io2_shadow_t; 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate #define SHADOW_NONE 0x00 /* nca_io2_t.shadow NONE */ 16107c478bd9Sstevel@tonic-gate #define SHADOW_DOORSRV 0x01 /* nca_io2_t.shadow door_srv() */ 16117c478bd9Sstevel@tonic-gate #define SHADOW_NCAFS 0x02 /* nca_io2_t.shadow NCAfs */ 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate 16147c478bd9Sstevel@tonic-gate /* 16157c478bd9Sstevel@tonic-gate * Given a ptr to a nca_io2_t, a field and the field_length, write data 16167c478bd9Sstevel@tonic-gate * into buffer (Note: word aligned offsets). 16177c478bd9Sstevel@tonic-gate */ 16187c478bd9Sstevel@tonic-gate #define NCA_IO_WDATA(val, vsize, p, n_used, len, off) \ 16197c478bd9Sstevel@tonic-gate /*CONSTCOND*/ \ 16207c478bd9Sstevel@tonic-gate if ((val) == NULL) { \ 16217c478bd9Sstevel@tonic-gate (p)->len = vsize; \ 16227c478bd9Sstevel@tonic-gate (p)->off = 0; \ 16237c478bd9Sstevel@tonic-gate } else { \ 16247c478bd9Sstevel@tonic-gate (p)->len = (vsize); \ 16257c478bd9Sstevel@tonic-gate (p)->off = ((n_used) + sizeof (uint32_t) - 1) & \ 16267c478bd9Sstevel@tonic-gate (~(sizeof (uint32_t) - 1)); \ 16277c478bd9Sstevel@tonic-gate bcopy((char *)(val), \ 16287c478bd9Sstevel@tonic-gate ((char *)(p) + (p)->off), (vsize)); \ 16297c478bd9Sstevel@tonic-gate (n_used) = (p)->off + (p)->len; \ 16307c478bd9Sstevel@tonic-gate } 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate /* 16337c478bd9Sstevel@tonic-gate * Given a ptr to an nca_io2_t, a field length member name, append data to 16347c478bd9Sstevel@tonic-gate * it in the buffer. Note: must be the last field a WDATA() was done for. 16357c478bd9Sstevel@tonic-gate * 16367c478bd9Sstevel@tonic-gate * Note: a NULL NCA_IO_WDATA() can be followed by a NCA_IO_ADATA() only if 16377c478bd9Sstevel@tonic-gate * vsize was == -1. 16387c478bd9Sstevel@tonic-gate * 16397c478bd9Sstevel@tonic-gate */ 16407c478bd9Sstevel@tonic-gate #define NCA_IO_ADATA(val, vsize, p, n_used, len, off) \ 16417c478bd9Sstevel@tonic-gate if ((p)->len == -1) { \ 16427c478bd9Sstevel@tonic-gate (p)->len = 0; \ 16437c478bd9Sstevel@tonic-gate (p)->off = ((n_used) + sizeof (uint32_t) - 1) & \ 16447c478bd9Sstevel@tonic-gate (~(sizeof (uint32_t) - 1)); \ 16457c478bd9Sstevel@tonic-gate } \ 16467c478bd9Sstevel@tonic-gate bcopy((char *)(val), ((char *)(p) + \ 16477c478bd9Sstevel@tonic-gate (p)->off + (p)->len), (vsize)); \ 16487c478bd9Sstevel@tonic-gate (p)->len += (vsize); \ 16497c478bd9Sstevel@tonic-gate (n_used) += (vsize); 16507c478bd9Sstevel@tonic-gate 16517c478bd9Sstevel@tonic-gate /* 16527c478bd9Sstevel@tonic-gate * Given a ptr to a nca_io2_t and a field construct a pointer. 16537c478bd9Sstevel@tonic-gate */ 16547c478bd9Sstevel@tonic-gate #define NCA_IO_PDATA(p, off) ((char *)(p) + (p)->off) 16557c478bd9Sstevel@tonic-gate 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate #ifndef isdigit 16587c478bd9Sstevel@tonic-gate #define isdigit(c) ((c) >= '0' && (c) <= '9') 16597c478bd9Sstevel@tonic-gate #endif 16607c478bd9Sstevel@tonic-gate 16617c478bd9Sstevel@tonic-gate #ifndef tolower 16627c478bd9Sstevel@tonic-gate #define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) | 0x20 : (c)) 16637c478bd9Sstevel@tonic-gate #endif 16647c478bd9Sstevel@tonic-gate 16657c478bd9Sstevel@tonic-gate #ifndef isalpha 16667c478bd9Sstevel@tonic-gate #define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) 16677c478bd9Sstevel@tonic-gate #endif 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate #ifndef isspace 16707c478bd9Sstevel@tonic-gate #define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \ 16717c478bd9Sstevel@tonic-gate (c) == '\r' || (c) == '\f' || (c) == '\013') 16727c478bd9Sstevel@tonic-gate #endif 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate extern char *strnchr(const char *, int, size_t); 16757c478bd9Sstevel@tonic-gate extern char *strnstr(const char *, const char *, size_t); 16767c478bd9Sstevel@tonic-gate extern char *strncasestr(const char *, const char *, size_t); 16777c478bd9Sstevel@tonic-gate extern char *strrncasestr(const char *, const char *, size_t); 16787c478bd9Sstevel@tonic-gate extern int atoin(const char *, size_t); 16797c478bd9Sstevel@tonic-gate extern int digits(int); 16807c478bd9Sstevel@tonic-gate 16817c478bd9Sstevel@tonic-gate extern void nca_conn_free(nca_conn_t *); 16827c478bd9Sstevel@tonic-gate extern void nca_logit_off(void); 16837c478bd9Sstevel@tonic-gate extern void node_fr(node_t *); 16847c478bd9Sstevel@tonic-gate 16857c478bd9Sstevel@tonic-gate extern nca_squeue_t *nca_squeue_init(nca_squeue_t *, uint32_t, 16867c478bd9Sstevel@tonic-gate processorid_t, void (*)(), void *, void (*)(), clock_t, pri_t); 16877c478bd9Sstevel@tonic-gate extern void nca_squeue_fini(nca_squeue_t *); 16887c478bd9Sstevel@tonic-gate extern void nca_squeue_enter(nca_squeue_t *, mblk_t *, void *); 16897c478bd9Sstevel@tonic-gate extern void nca_squeue_fill(nca_squeue_t *, mblk_t *, void *); 16907c478bd9Sstevel@tonic-gate extern mblk_t *nca_squeue_remove(nca_squeue_t *); 16917c478bd9Sstevel@tonic-gate extern void nca_squeue_worker(nca_squeue_t *); 16927c478bd9Sstevel@tonic-gate extern mblk_t *nca_squeue_ctl(mblk_t *, void *, unsigned short); 16937c478bd9Sstevel@tonic-gate extern void nca_squeue_signal(nca_squeue_t *); 16947c478bd9Sstevel@tonic-gate extern void nca_squeue_exit(nca_squeue_t *); 16957c478bd9Sstevel@tonic-gate extern void sqfan_init(sqfan_t *, uint32_t, uint32_t, uint32_t); 16967c478bd9Sstevel@tonic-gate extern nca_squeue_t *sqfan_ixinit(sqfan_t *, uint32_t, nca_squeue_t *, uint32_t, 16977c478bd9Sstevel@tonic-gate processorid_t, void (*)(), void *, void (*)(), clock_t, pri_t); 16987c478bd9Sstevel@tonic-gate extern void sqfan_fini(sqfan_t *); 16997c478bd9Sstevel@tonic-gate extern void sqfan_fill(sqfan_t *, mblk_t *, void *); 17007c478bd9Sstevel@tonic-gate extern mblk_t *sqfan_remove(sqfan_t *); 17017c478bd9Sstevel@tonic-gate extern void nca_squeue_nointr(nca_squeue_t *, mblk_t *, void *, int); 17027c478bd9Sstevel@tonic-gate extern void nca_squeue_pause(nca_squeue_t *, mblk_t *, void *, int, boolean_t); 17037c478bd9Sstevel@tonic-gate extern void nca_squeue_willproxy(nca_squeue_t *); 17047c478bd9Sstevel@tonic-gate extern void nca_squeue_proxy(nca_squeue_t *, nca_squeue_t *); 17057c478bd9Sstevel@tonic-gate extern void nca_squeue_bind(nca_squeue_t *, uint32_t, processorid_t); 17067c478bd9Sstevel@tonic-gate 17077c478bd9Sstevel@tonic-gate extern int nca_tcp_clean_death(nca_conn_t *, int); 17087c478bd9Sstevel@tonic-gate extern nca_conn_t *nca_tcp_connect(ipaddr_t, in_port_t, boolean_t); 17097c478bd9Sstevel@tonic-gate extern void nca_tcp_send(nca_conn_t *, mblk_t *); 17107c478bd9Sstevel@tonic-gate extern void nca_tcp_direct(nca_conn_t *, nca_conn_t *, uint32_t); 17117c478bd9Sstevel@tonic-gate 17127c478bd9Sstevel@tonic-gate /* Functions prototypes from ncadoorsrv.c */ 17137c478bd9Sstevel@tonic-gate extern node_t *nca_node_flush(node_t *); 17147c478bd9Sstevel@tonic-gate extern void nca_downcall_service(void *, door_arg_t *, void (**)(void *, 17157c478bd9Sstevel@tonic-gate void *), void **, int *); 17167c478bd9Sstevel@tonic-gate extern node_t *ctag_lookup(uint64_t, unsigned *); 17177c478bd9Sstevel@tonic-gate extern node_t *node_replace(node_t *, nca_conn_t *); 17187c478bd9Sstevel@tonic-gate extern node_t *node_temp(node_t *, nca_conn_t *); 17197c478bd9Sstevel@tonic-gate extern void find_ctags(node_t *, nca_io2_t *, int *); 17207c478bd9Sstevel@tonic-gate extern void nca_ncafs_srv(nca_io2_t *, struct uio *, queue_t *); 17217c478bd9Sstevel@tonic-gate extern boolean_t nca_reclaim_vlru(void); 17227c478bd9Sstevel@tonic-gate extern boolean_t nca_reclaim_plru(boolean_t, boolean_t); 17237c478bd9Sstevel@tonic-gate 17247c478bd9Sstevel@tonic-gate /* 17257c478bd9Sstevel@tonic-gate * NCA_COUNTER() is used to add a signed long value to a unsigned long 17267c478bd9Sstevel@tonic-gate * counter, in general these counters are used to maintain NCA state. 17277c478bd9Sstevel@tonic-gate * 17287c478bd9Sstevel@tonic-gate * NCA_DEBUG_COUNTER() is used like NCA_COUNTER() but for counters used 17297c478bd9Sstevel@tonic-gate * to maintain additional debug state, by default these counters aren't 17307c478bd9Sstevel@tonic-gate * updated unless the global value nca_debug_counter is set to a value 17317c478bd9Sstevel@tonic-gate * other then zero. 17327c478bd9Sstevel@tonic-gate * 17337c478bd9Sstevel@tonic-gate * Also, if NCA_COUNTER_TRACE is defined a time ordered wrapping trace 17347c478bd9Sstevel@tonic-gate * buffer is maintained with hrtime_t stamps, counter address, value to 17357c478bd9Sstevel@tonic-gate * add, and new value entries for all NCA_COUNTER() and NCA_DEBUG_COUNTER() 17367c478bd9Sstevel@tonic-gate * use. 17377c478bd9Sstevel@tonic-gate */ 17387c478bd9Sstevel@tonic-gate 17397c478bd9Sstevel@tonic-gate #undef NCA_COUNTER_TRACE 17407c478bd9Sstevel@tonic-gate 17417c478bd9Sstevel@tonic-gate #ifdef NCA_COUNTER_TRACE 17427c478bd9Sstevel@tonic-gate 17437c478bd9Sstevel@tonic-gate #define NCA_COUNTER_TRACE_SZ 1024 17447c478bd9Sstevel@tonic-gate 17457c478bd9Sstevel@tonic-gate typedef struct nca_counter_s { 17467c478bd9Sstevel@tonic-gate hrtime_t t; 17477c478bd9Sstevel@tonic-gate unsigned long *p; 17487c478bd9Sstevel@tonic-gate unsigned long v; 17497c478bd9Sstevel@tonic-gate unsigned long nv; 17507c478bd9Sstevel@tonic-gate } nca_counter_t; 17517c478bd9Sstevel@tonic-gate 17527c478bd9Sstevel@tonic-gate extern nca_counter_t nca_counter_tv[]; 17537c478bd9Sstevel@tonic-gate extern nca_counter_t *nca_counter_tp; 17547c478bd9Sstevel@tonic-gate 17557c478bd9Sstevel@tonic-gate #define NCA_COUNTER(_p, _v) { \ 17567c478bd9Sstevel@tonic-gate unsigned long *p = _p; \ 17577c478bd9Sstevel@tonic-gate long v = _v; \ 17587c478bd9Sstevel@tonic-gate unsigned long _nv; \ 17597c478bd9Sstevel@tonic-gate nca_counter_t *_otp; \ 17607c478bd9Sstevel@tonic-gate nca_counter_t *_ntp; \ 17617c478bd9Sstevel@tonic-gate \ 17627c478bd9Sstevel@tonic-gate _nv = atomic_add_long_nv(p, v); \ 17637c478bd9Sstevel@tonic-gate do { \ 17647c478bd9Sstevel@tonic-gate _otp = nca_counter_tp; \ 17657c478bd9Sstevel@tonic-gate _ntp = _otp + 1; \ 17667c478bd9Sstevel@tonic-gate if (_ntp == &nca_counter_tv[NCA_COUNTER_TRACE_SZ]) \ 17677c478bd9Sstevel@tonic-gate _ntp = nca_counter_tv; \ 176875d94465SJosef 'Jeff' Sipek } while (atomic_cas_ptr((void *)&nca_counter_tp, (void *)_otp, \ 17697c478bd9Sstevel@tonic-gate (void *)_ntp) != (void *)_otp); \ 17707c478bd9Sstevel@tonic-gate _ntp->t = gethrtime(); \ 17717c478bd9Sstevel@tonic-gate _ntp->p = p; \ 17727c478bd9Sstevel@tonic-gate _ntp->v = v; \ 17737c478bd9Sstevel@tonic-gate _ntp->nv = _nv; \ 17747c478bd9Sstevel@tonic-gate } 17757c478bd9Sstevel@tonic-gate 17767c478bd9Sstevel@tonic-gate #else /* NCA_COUNTER_TRACE */ 17777c478bd9Sstevel@tonic-gate 17787c478bd9Sstevel@tonic-gate #define NCA_COUNTER(p, v) atomic_add_long((p), (v)) 17797c478bd9Sstevel@tonic-gate 17807c478bd9Sstevel@tonic-gate #endif /* NCA_COUNTER_TRACE */ 17817c478bd9Sstevel@tonic-gate 17827c478bd9Sstevel@tonic-gate 17837c478bd9Sstevel@tonic-gate /* 17847c478bd9Sstevel@tonic-gate * This is the buf used in upcall to httpd. 17857c478bd9Sstevel@tonic-gate */ 17867c478bd9Sstevel@tonic-gate typedef struct { 17877c478bd9Sstevel@tonic-gate uintptr_t tid; 17887c478bd9Sstevel@tonic-gate char *buf; 17897c478bd9Sstevel@tonic-gate } http_buf_table_t; 17907c478bd9Sstevel@tonic-gate 17917c478bd9Sstevel@tonic-gate /* 17927c478bd9Sstevel@tonic-gate * URI and filename hash, a simple static hash bucket array of singly 17937c478bd9Sstevel@tonic-gate * linked grounded lists is used with a hashing algorithm which has 17947c478bd9Sstevel@tonic-gate * proven to have good distribution properities for strings of ... 17957c478bd9Sstevel@tonic-gate * 17967c478bd9Sstevel@tonic-gate * Note: NCA_HASH_SZ must be a prime number. 17977c478bd9Sstevel@tonic-gate */ 17987c478bd9Sstevel@tonic-gate 17997c478bd9Sstevel@tonic-gate #define NCA_HASH_SZ 8053 18007c478bd9Sstevel@tonic-gate #define NCA_HASH_MASK 0xFFFFFF 18017c478bd9Sstevel@tonic-gate #define HASH_IX(s, l, hix, hsz) { \ 18027c478bd9Sstevel@tonic-gate char *cp = (s); \ 18037c478bd9Sstevel@tonic-gate int len = (l); \ 18047c478bd9Sstevel@tonic-gate \ 18057c478bd9Sstevel@tonic-gate (hix) = 0; \ 18067c478bd9Sstevel@tonic-gate while (len-- > 0) { \ 18077c478bd9Sstevel@tonic-gate (hix) = (hix) * 33 + *cp++; \ 18087c478bd9Sstevel@tonic-gate (hix) &= NCA_HASH_MASK; \ 18097c478bd9Sstevel@tonic-gate } \ 18107c478bd9Sstevel@tonic-gate (hix) %= (hsz); \ 18117c478bd9Sstevel@tonic-gate } 18127c478bd9Sstevel@tonic-gate 18137c478bd9Sstevel@tonic-gate /* 18147c478bd9Sstevel@tonic-gate * CTAG hash. 18157c478bd9Sstevel@tonic-gate */ 18167c478bd9Sstevel@tonic-gate #define NCA_CTAGHASH_SZ 4096 18177c478bd9Sstevel@tonic-gate #define CTAGHASH_IX(t, ix) ((ix) = (t) % NCA_CTAGHASH_SZ) 18187c478bd9Sstevel@tonic-gate 18197c478bd9Sstevel@tonic-gate /* 18207c478bd9Sstevel@tonic-gate * VNODE hash. 18217c478bd9Sstevel@tonic-gate * 18227c478bd9Sstevel@tonic-gate * Note: NCA_VNODEHASH_SZ must be a P2Ps() value. 18237c478bd9Sstevel@tonic-gate */ 18247c478bd9Sstevel@tonic-gate #define NCA_VNODEHASH_SZ 12281 18257c478bd9Sstevel@tonic-gate #define VNODEHASH_IX(p, ix) ((ix) = (((uintptr_t)p >> 27) ^ \ 18267c478bd9Sstevel@tonic-gate ((uintptr_t)p >> 17) ^ ((uintptr_t)p >> 11) ^ (uintptr_t)p) % \ 18277c478bd9Sstevel@tonic-gate ncavnodehash_sz) 18287c478bd9Sstevel@tonic-gate 18297c478bd9Sstevel@tonic-gate extern pgcnt_t nca_ppmax; 18307c478bd9Sstevel@tonic-gate extern pgcnt_t nca_vpmax; 18317c478bd9Sstevel@tonic-gate extern pgcnt_t nca_pplim; 18327c478bd9Sstevel@tonic-gate extern pgcnt_t nca_vplim; 18337c478bd9Sstevel@tonic-gate extern pgcnt_t nca_ppmem; 18347c478bd9Sstevel@tonic-gate extern pgcnt_t nca_vpmem; 18357c478bd9Sstevel@tonic-gate extern ssize_t nca_kbmem; 18367c478bd9Sstevel@tonic-gate extern ssize_t nca_spmem; 18377c478bd9Sstevel@tonic-gate extern ssize_t nca_ckmem; 18387c478bd9Sstevel@tonic-gate extern ssize_t nca_mbmem; 18397c478bd9Sstevel@tonic-gate extern ssize_t nca_cbmem; 18407c478bd9Sstevel@tonic-gate extern ssize_t nca_lbmem; 18417c478bd9Sstevel@tonic-gate extern size_t nca_maxkmem; 18427c478bd9Sstevel@tonic-gate extern uint32_t nca_use_segmap; 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate extern ulong_t nca_hits; 18457c478bd9Sstevel@tonic-gate extern ulong_t nca_file; 18467c478bd9Sstevel@tonic-gate extern ulong_t nca_ctag; 18477c478bd9Sstevel@tonic-gate extern ulong_t nca_miss; 18487c478bd9Sstevel@tonic-gate 18497c478bd9Sstevel@tonic-gate extern ulong_t nca_hit304; 18507c478bd9Sstevel@tonic-gate extern ulong_t nca_hitnoV; 18517c478bd9Sstevel@tonic-gate extern ulong_t nca_hitnoVfast; 18527c478bd9Sstevel@tonic-gate extern ulong_t nca_hitnoVtemp; 18537c478bd9Sstevel@tonic-gate 18547c478bd9Sstevel@tonic-gate extern ulong_t nca_filehits; 18557c478bd9Sstevel@tonic-gate extern ulong_t nca_filenoV; 18567c478bd9Sstevel@tonic-gate extern ulong_t nca_filenoVfast; 18577c478bd9Sstevel@tonic-gate extern ulong_t nca_filemiss; 18587c478bd9Sstevel@tonic-gate 18597c478bd9Sstevel@tonic-gate extern ulong_t nca_missURI; 18607c478bd9Sstevel@tonic-gate extern ulong_t nca_missQ; 18617c478bd9Sstevel@tonic-gate extern ulong_t nca_missSAFE; 18627c478bd9Sstevel@tonic-gate extern ulong_t nca_missnoV; 18637c478bd9Sstevel@tonic-gate extern ulong_t nca_missnotcp; 18647c478bd9Sstevel@tonic-gate extern ulong_t nca_missfail; 18657c478bd9Sstevel@tonic-gate extern ulong_t nca_misstemp; 18667c478bd9Sstevel@tonic-gate extern ulong_t nca_missnohash; 18677c478bd9Sstevel@tonic-gate extern ulong_t nca_missclean; 18687c478bd9Sstevel@tonic-gate extern ulong_t nca_missadvisory; 18697c478bd9Sstevel@tonic-gate extern ulong_t nca_missadvNoA; 18707c478bd9Sstevel@tonic-gate extern ulong_t nca_missERROR; 18717c478bd9Sstevel@tonic-gate 18727c478bd9Sstevel@tonic-gate extern ulong_t nca_ERROR; 18737c478bd9Sstevel@tonic-gate extern ulong_t nca_flushnode; 18747c478bd9Sstevel@tonic-gate extern ulong_t nca_replacenode; 18757c478bd9Sstevel@tonic-gate extern ulong_t nca_tempnode; 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate extern ulong_t nca_fail304; 18787c478bd9Sstevel@tonic-gate 18797c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache1; 18807c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache2; 18817c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache3; 18827c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache4; 18837c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache5; 18847c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache6; 18857c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache6nomp; 18867c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache7; 18877c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache8; 18887c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache9; 18897c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache10; 18907c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache11; 18917c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache12; 18927c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache13; 18937c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache14; 18947c478bd9Sstevel@tonic-gate extern ulong_t nca_nocache15; 18957c478bd9Sstevel@tonic-gate extern ulong_t nca_nodes; 18967c478bd9Sstevel@tonic-gate extern ulong_t nca_desballoc; 18977c478bd9Sstevel@tonic-gate 18987c478bd9Sstevel@tonic-gate extern ulong_t nca_plrucnt; 18997c478bd9Sstevel@tonic-gate extern ulong_t nca_vlrucnt; 19007c478bd9Sstevel@tonic-gate extern ulong_t nca_rpcall; 19017c478bd9Sstevel@tonic-gate extern ulong_t nca_rvcall; 19027c478bd9Sstevel@tonic-gate extern ulong_t nca_rpbusy; 19037c478bd9Sstevel@tonic-gate extern ulong_t nca_rvbusy; 19047c478bd9Sstevel@tonic-gate extern ulong_t nca_rpfail; 19057c478bd9Sstevel@tonic-gate extern ulong_t nca_rpempty; 19067c478bd9Sstevel@tonic-gate extern ulong_t nca_rvempty; 19077c478bd9Sstevel@tonic-gate extern ulong_t nca_rpdone; 19087c478bd9Sstevel@tonic-gate extern ulong_t nca_rvdone; 19097c478bd9Sstevel@tonic-gate extern ulong_t nca_rmdone; 19107c478bd9Sstevel@tonic-gate extern ulong_t nca_rkdone; 19117c478bd9Sstevel@tonic-gate extern ulong_t nca_rsdone; 19127c478bd9Sstevel@tonic-gate extern ulong_t nca_rndone; 19137c478bd9Sstevel@tonic-gate extern ulong_t nca_rpnone; 19147c478bd9Sstevel@tonic-gate extern ulong_t nca_rvnone; 19157c478bd9Sstevel@tonic-gate extern ulong_t nca_rmnone; 19167c478bd9Sstevel@tonic-gate extern ulong_t nca_rknone; 19177c478bd9Sstevel@tonic-gate extern ulong_t nca_rsnone; 19187c478bd9Sstevel@tonic-gate extern ulong_t nca_rnh; 19197c478bd9Sstevel@tonic-gate extern ulong_t nca_ref[]; 19207c478bd9Sstevel@tonic-gate extern ulong_t nca_vmap_rpcall; 19217c478bd9Sstevel@tonic-gate 19227c478bd9Sstevel@tonic-gate extern ulong_t nca_node_kmem_fail1; 19237c478bd9Sstevel@tonic-gate extern ulong_t nca_node_kmem_fail2; 19247c478bd9Sstevel@tonic-gate 19257c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_nopreempt; 19267c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_badconnect; 19277c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_invaladvise; 19287c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_notupcall; 19297c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_badadvise; 19307c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_cksum; 19317c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_error; 19327c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_op; 19337c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_badtee; 19347c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_badio; 19357c478bd9Sstevel@tonic-gate extern ulong_t doorsrv_sz; 19367c478bd9Sstevel@tonic-gate 19377c478bd9Sstevel@tonic-gate extern ulong_t nca_allocfail; 19387c478bd9Sstevel@tonic-gate extern ulong_t nca_mapinfail; 19397c478bd9Sstevel@tonic-gate extern ulong_t nca_mapinfail1; 19407c478bd9Sstevel@tonic-gate extern ulong_t nca_mapinfail2; 19417c478bd9Sstevel@tonic-gate extern ulong_t nca_mapinfail3; 19427c478bd9Sstevel@tonic-gate 19437c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_http; 19447c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_badsz; 19457c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_nosz; 19467c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_filename; 19477c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_filename1; 19487c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_filename2; 19497c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_trailer; 19507c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_preempt; 19517c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_downcall; 19527c478bd9Sstevel@tonic-gate extern ulong_t nca_early_downcall; 19537c478bd9Sstevel@tonic-gate extern ulong_t nca_httpd_more; 19547c478bd9Sstevel@tonic-gate 19557c478bd9Sstevel@tonic-gate ulong_t nca_logit_noupcall; 19567c478bd9Sstevel@tonic-gate 19577c478bd9Sstevel@tonic-gate ulong_t nca_logit; 19587c478bd9Sstevel@tonic-gate ulong_t nca_logit_nomp; 19597c478bd9Sstevel@tonic-gate ulong_t nca_logit_no; 19607c478bd9Sstevel@tonic-gate ulong_t nca_logit_NULL; 19617c478bd9Sstevel@tonic-gate ulong_t nca_logit_fail; 19627c478bd9Sstevel@tonic-gate 19637c478bd9Sstevel@tonic-gate ulong_t nca_logit_flush_NULL1; 19647c478bd9Sstevel@tonic-gate ulong_t nca_logit_flush_NULL2; 19657c478bd9Sstevel@tonic-gate 19667c478bd9Sstevel@tonic-gate ulong_t nca_logger_NULL1; 19677c478bd9Sstevel@tonic-gate ulong_t nca_logger_NULL2; 19687c478bd9Sstevel@tonic-gate 19697c478bd9Sstevel@tonic-gate ulong_t nca_log_buf_alloc_NULL; 19707c478bd9Sstevel@tonic-gate ulong_t nca_log_buf_alloc_fail; 19717c478bd9Sstevel@tonic-gate ulong_t nca_log_buf_alloc_part; 19727c478bd9Sstevel@tonic-gate 19737c478bd9Sstevel@tonic-gate ulong_t nca_log_buf_dup; 19747c478bd9Sstevel@tonic-gate 19757c478bd9Sstevel@tonic-gate extern ulong_t nca_upcalls; 19767c478bd9Sstevel@tonic-gate extern ulong_t nca_ncafs_upcalls; 19777c478bd9Sstevel@tonic-gate 19787c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_count; 19797c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_kmem; 19807c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_kmem_fail; 19817c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_allocb_fail; 19827c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_tw; 19837c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_tw1; 19847c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_tw2; 19857c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_reinit_cnt; 19867c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_NULL1; 19877c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_Q0; 19887c478bd9Sstevel@tonic-gate extern ulong_t nca_conn_FLAGS; 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate extern ulong_t tcpwronginq; 19917c478bd9Sstevel@tonic-gate extern ulong_t ipsendup; 19927c478bd9Sstevel@tonic-gate extern ulong_t ipwrongcpu; 19937c478bd9Sstevel@tonic-gate extern ulong_t iponcpu; 19947c478bd9Sstevel@tonic-gate 19957c478bd9Sstevel@tonic-gate extern ulong_t nca_tcp_xmit_null; 19967c478bd9Sstevel@tonic-gate extern ulong_t nca_tcp_xmit_null1; 19977c478bd9Sstevel@tonic-gate 19987c478bd9Sstevel@tonic-gate extern ulong_t tw_on; 19997c478bd9Sstevel@tonic-gate extern ulong_t tw_fire; 20007c478bd9Sstevel@tonic-gate extern ulong_t tw_fire1; 20017c478bd9Sstevel@tonic-gate extern ulong_t tw_fire2; 20027c478bd9Sstevel@tonic-gate extern ulong_t tw_fire3; 20037c478bd9Sstevel@tonic-gate extern ulong_t tw_add; 20047c478bd9Sstevel@tonic-gate extern ulong_t tw_add1; 20057c478bd9Sstevel@tonic-gate extern ulong_t tw_delete; 20067c478bd9Sstevel@tonic-gate extern ulong_t tw_reclaim; 20077c478bd9Sstevel@tonic-gate extern ulong_t tw_reap; 20087c478bd9Sstevel@tonic-gate extern ulong_t tw_reap1; 20097c478bd9Sstevel@tonic-gate extern ulong_t tw_reap2; 20107c478bd9Sstevel@tonic-gate extern ulong_t tw_reap3; 20117c478bd9Sstevel@tonic-gate extern ulong_t tw_reap4; 20127c478bd9Sstevel@tonic-gate extern ulong_t tw_reap5; 20137c478bd9Sstevel@tonic-gate extern ulong_t tw_timer; 20147c478bd9Sstevel@tonic-gate extern ulong_t tw_timer1; 20157c478bd9Sstevel@tonic-gate extern ulong_t tw_timer2; 20167c478bd9Sstevel@tonic-gate extern ulong_t tw_timer3; 20177c478bd9Sstevel@tonic-gate extern ulong_t tw_timer4; 20187c478bd9Sstevel@tonic-gate extern ulong_t tw_timer5; 20197c478bd9Sstevel@tonic-gate 20207c478bd9Sstevel@tonic-gate extern ulong_t ti_on; 20217c478bd9Sstevel@tonic-gate extern ulong_t ti_fire; 20227c478bd9Sstevel@tonic-gate extern ulong_t ti_fire1; 20237c478bd9Sstevel@tonic-gate extern ulong_t ti_fire2; 20247c478bd9Sstevel@tonic-gate extern ulong_t ti_fire3; 20257c478bd9Sstevel@tonic-gate extern ulong_t ti_fire4; 20267c478bd9Sstevel@tonic-gate extern ulong_t ti_add; 20277c478bd9Sstevel@tonic-gate extern ulong_t ti_add1; 20287c478bd9Sstevel@tonic-gate extern ulong_t ti_add2; 20297c478bd9Sstevel@tonic-gate extern ulong_t ti_add3; 20307c478bd9Sstevel@tonic-gate extern ulong_t ti_add4; 20317c478bd9Sstevel@tonic-gate extern ulong_t ti_add5; 20327c478bd9Sstevel@tonic-gate extern ulong_t ti_add_reuse; 20337c478bd9Sstevel@tonic-gate extern ulong_t ti_delete; 20347c478bd9Sstevel@tonic-gate extern ulong_t ti_delete1; 20357c478bd9Sstevel@tonic-gate extern ulong_t ti_delete2; 20367c478bd9Sstevel@tonic-gate extern ulong_t ti_reap; 20377c478bd9Sstevel@tonic-gate extern ulong_t ti_reap1; 20387c478bd9Sstevel@tonic-gate extern ulong_t ti_reap2; 20397c478bd9Sstevel@tonic-gate extern ulong_t ti_reap3; 20407c478bd9Sstevel@tonic-gate extern ulong_t ti_reap4; 20417c478bd9Sstevel@tonic-gate extern ulong_t ti_reap5; 20427c478bd9Sstevel@tonic-gate extern ulong_t ti_timer; 20437c478bd9Sstevel@tonic-gate extern ulong_t ti_timer1; 20447c478bd9Sstevel@tonic-gate extern ulong_t ti_timer2; 20457c478bd9Sstevel@tonic-gate extern ulong_t ti_timer3; 20467c478bd9Sstevel@tonic-gate extern ulong_t ti_timer4; 20477c478bd9Sstevel@tonic-gate extern ulong_t ti_timer5; 20487c478bd9Sstevel@tonic-gate extern ulong_t ti_timer6; 20497c478bd9Sstevel@tonic-gate 20507c478bd9Sstevel@tonic-gate extern uint32_t nca_conn_q; 20517c478bd9Sstevel@tonic-gate extern uint32_t nca_conn_q0; 20527c478bd9Sstevel@tonic-gate extern uint32_t nca_conn_req_max_q; 20537c478bd9Sstevel@tonic-gate extern uint32_t nca_conn_req_max_q0; 20547c478bd9Sstevel@tonic-gate 20557c478bd9Sstevel@tonic-gate extern char nca_resp_500[]; 20567c478bd9Sstevel@tonic-gate extern ssize_t nca_resp_500_sz; 20577c478bd9Sstevel@tonic-gate 20587c478bd9Sstevel@tonic-gate extern uint32_t ncaurihash_sz; 20597c478bd9Sstevel@tonic-gate extern uint32_t ncafilehash_sz; 20607c478bd9Sstevel@tonic-gate extern uint32_t ncactaghash_sz; 20617c478bd9Sstevel@tonic-gate extern uint32_t ncavnodehash_sz; 20627c478bd9Sstevel@tonic-gate extern nodef_t *ncaurihash; 20637c478bd9Sstevel@tonic-gate extern nodef_t *ncafilehash; 20647c478bd9Sstevel@tonic-gate extern nodef_t *ncavnodehash; 20657c478bd9Sstevel@tonic-gate extern nodef_t *ncactaghash; 20667c478bd9Sstevel@tonic-gate extern char nca_httpd_door_path[]; 20677c478bd9Sstevel@tonic-gate extern char nca_httpd_downdoor_path[]; 20687c478bd9Sstevel@tonic-gate extern door_handle_t nca_downcall_door_hand; 20697c478bd9Sstevel@tonic-gate extern uint32_t n_http_buf_size; 20707c478bd9Sstevel@tonic-gate extern door_handle_t nca_httpd_door_hand; 20717c478bd9Sstevel@tonic-gate extern sqfan_t nca_miss_fanout1; 20727c478bd9Sstevel@tonic-gate extern sqfan_t nca_miss_fanout2; 20737c478bd9Sstevel@tonic-gate extern nca_door_t nca_httpd_door; 20747c478bd9Sstevel@tonic-gate extern int nca_downdoor_created; 20757c478bd9Sstevel@tonic-gate extern int n_http_buf_table; 20767c478bd9Sstevel@tonic-gate extern http_buf_table_t *g_http_buf_table; 20777c478bd9Sstevel@tonic-gate extern struct kmem_cache *node_cache; 20787c478bd9Sstevel@tonic-gate #ifdef DEBUG 20797c478bd9Sstevel@tonic-gate extern node_t *nca_http_response(nca_conn_t *, const char *, int, char *, int, 20807c478bd9Sstevel@tonic-gate uint_t, const char *); 20817c478bd9Sstevel@tonic-gate extern node_t *nca_http_response_node(nca_conn_t *, const char *, int, node_t *, 20827c478bd9Sstevel@tonic-gate const char *); 20837c478bd9Sstevel@tonic-gate #else 20847c478bd9Sstevel@tonic-gate extern node_t *nca_http_response(nca_conn_t *, const char *, int, char *, int, 20857c478bd9Sstevel@tonic-gate uint_t); 20867c478bd9Sstevel@tonic-gate extern node_t *nca_http_response_node(nca_conn_t *, const char *, int, 20877c478bd9Sstevel@tonic-gate node_t *); 20887c478bd9Sstevel@tonic-gate #endif 20897c478bd9Sstevel@tonic-gate extern void nca_node_del(node_t *); 20907c478bd9Sstevel@tonic-gate extern void nca_node_uncache(node_t *); 20917c478bd9Sstevel@tonic-gate extern node_t *nca_node_add(char *, int, nodef_t *, int); 20927c478bd9Sstevel@tonic-gate extern node_t *node_create(int, boolean_t, char *, int); 20937c478bd9Sstevel@tonic-gate extern void nca_reclaim_phys(node_t *, boolean_t, boolean_t); 20947c478bd9Sstevel@tonic-gate extern boolean_t nca_http_pmap(node_t *); 20957c478bd9Sstevel@tonic-gate extern boolean_t nca_http_vmap(node_t *, int); 20967c478bd9Sstevel@tonic-gate extern time_t nca_http_date(char *); 20977c478bd9Sstevel@tonic-gate extern node_t *nca_httpd_data(node_t *, nca_conn_t *, nca_io2_t *, int); 20987c478bd9Sstevel@tonic-gate extern void nca_missed(node_t *, mblk_t *, nca_squeue_t *); 20997c478bd9Sstevel@tonic-gate extern void nca_miss_conn_mv(node_t *, nca_conn_t *); 21007c478bd9Sstevel@tonic-gate extern void nca_miss_conn_fr(node_t *, nca_conn_t *); 21017c478bd9Sstevel@tonic-gate extern void nca_http_logit(nca_conn_t *); 21027c478bd9Sstevel@tonic-gate extern void nca_http_error(nca_conn_t *); 21037c478bd9Sstevel@tonic-gate extern void nca_node_xmit(node_t *, nca_conn_t *); 21047c478bd9Sstevel@tonic-gate 21057c478bd9Sstevel@tonic-gate /* 21067c478bd9Sstevel@tonic-gate * It contains data for forwarding data to application programs. 21077c478bd9Sstevel@tonic-gate * For door case, doorhandle is the upcall door handle and listenerq 21087c478bd9Sstevel@tonic-gate * is NULL; for ncafs, listenerq is the upcall listener queue and 21097c478bd9Sstevel@tonic-gate * doorhandle is NULL. listenning is always B_TRUE for door and it is 21107c478bd9Sstevel@tonic-gate * B_TRUE for ncafs only after the listen system call has been issued. 21117c478bd9Sstevel@tonic-gate */ 21127c478bd9Sstevel@tonic-gate typedef struct nca_listener_s { 21137c478bd9Sstevel@tonic-gate boolean_t listenning; /* is ready for accepting connection */ 21147c478bd9Sstevel@tonic-gate door_handle_t doorhandle; /* door handle or NULL for ncafs */ 21157c478bd9Sstevel@tonic-gate queue_t *listenerq; /* upcall queue or NULL for door */ 21167c478bd9Sstevel@tonic-gate } nca_listener_t; 21177c478bd9Sstevel@tonic-gate 21187c478bd9Sstevel@tonic-gate /* 21197c478bd9Sstevel@tonic-gate * Returned values of nca_isnca_data. 21207c478bd9Sstevel@tonic-gate * NOT_NCA_DATA: not NCA data. 21217c478bd9Sstevel@tonic-gate * NCA_DATA_ANY_ADDR: NCA data, matches INADDR_ANY. 21227c478bd9Sstevel@tonic-gate * NCA_DATA_ADDR: NCA data, match an IP address. 21237c478bd9Sstevel@tonic-gate */ 21247c478bd9Sstevel@tonic-gate #define NOT_NCA_DATA 0 21257c478bd9Sstevel@tonic-gate #define NCA_DATA_ANY_ADDR 1 21267c478bd9Sstevel@tonic-gate #define NCA_DATA_ADDR 2 21277c478bd9Sstevel@tonic-gate 21287c478bd9Sstevel@tonic-gate extern uint32_t ipportrehashcount1; 21297c478bd9Sstevel@tonic-gate extern uint32_t ipportrehashcount2; 21307c478bd9Sstevel@tonic-gate extern uint32_t ipportbucketcnt; 21317c478bd9Sstevel@tonic-gate extern uint32_t ipporttablesize; 21327c478bd9Sstevel@tonic-gate extern uint32_t ncafscount; 21337c478bd9Sstevel@tonic-gate extern uint32_t doorcount; 21347c478bd9Sstevel@tonic-gate extern int ip_virtual_hosting; 21357c478bd9Sstevel@tonic-gate 21367c478bd9Sstevel@tonic-gate extern nca_listener_t *nca_listener_find(ipaddr_t, uint16_t); 21377c478bd9Sstevel@tonic-gate extern nca_listener_t *nca_listener_find2(ipaddr_t, uint16_t); 21387c478bd9Sstevel@tonic-gate extern int nca_isnca_data(ipaddr_t, uint16_t); 21397c478bd9Sstevel@tonic-gate extern int nca_listener_add(ipaddr_t, uint16_t, void *, boolean_t); 21407c478bd9Sstevel@tonic-gate extern int nca_listener_del(ipaddr_t, uint16_t); 21417c478bd9Sstevel@tonic-gate extern void nca_listener_report(mblk_t *); 21427c478bd9Sstevel@tonic-gate 21437c478bd9Sstevel@tonic-gate #ifdef __cplusplus 21447c478bd9Sstevel@tonic-gate } 21457c478bd9Sstevel@tonic-gate #endif 21467c478bd9Sstevel@tonic-gate 21477c478bd9Sstevel@tonic-gate #endif /* _INET_NCA_H */ 2148