usr/src/uts/common/inet/ip/ipclassifier.c
author masputra
Sat, 22 Oct 2005 22:50:14 -0700
changeset 741 40027a3621ac
parent 409 22012dc8ea5b
child 1503 9c3595b79c0d
permissions -rw-r--r--
PSARC 2005/082 Yosemite: UDP Performance Enhancement 4796051 Solaris needs a more complete HW checksumming support 4905227 duplicate macros in ipclassifier.h and ip.h 4915681 need hardware checksum offload for the case of IP/UDP reassembly 6201076 outbound flow-control dysfunctional, ip to ce using mdt 6223331 ipv6 flow control may corrupt UDP packets 6223809 16-bit aligned IP header should be allowed for all x86 platforms 6275398 Galaxy hangs when running lmbench 6281836 Yosemite project integration into Solaris 6281885 xge needs to support IPv6 checksum offload 6282776 IPv6 NCE fast path is not created for incoming solicitation 6304890 IP transmit-side checksum logic needs to be tightened 6304902 IP6_IN_NOCKSUM is obsolete and should be torched 6304904 UDP should reject TI_GETPEERNAME for non-connected endpoint 6306768 IP and UDP device and module definitions need to be centralized
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
153
b7f7b242faa2 5013200 ipclassifier bind list insertion order is flawed in some cases
ethindra
parents: 0
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
const char ipclassifier_version[] = "@(#)ipclassifier.c	1.6	04/03/31 SMI";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * IP PACKET CLASSIFIER
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * The IP packet classifier provides mapping between IP packets and persistent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * connection state for connection-oriented protocols. It also provides
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * interface for managing connection states.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * The connection state is kept in conn_t data structure and contains, among
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * other things:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 *	o local/remote address and ports
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *	o Transport protocol
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *	o squeue for the connection (for TCP only)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *	o reference counter
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 *	o Connection state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *	o hash table linkage
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *	o interface/ire information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 *	o credentials
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 *	o ipsec policy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 *	o send and receive functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *	o mutex lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * Connections use a reference counting scheme. They are freed when the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * reference counter drops to zero. A reference is incremented when connection
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 * is placed in a list or table, when incoming packet for the connection arrives
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * and when connection is processed via squeue (squeue processing may be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * asynchronous and the reference protects the connection from being destroyed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 * before its processing is finished).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * send and receive functions are currently used for TCP only. The send function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * determines the IP entry point for the packet once it leaves TCP to be sent to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 * the destination address. The receive function is used by IP when the packet
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * should be passed for TCP processing. When a new connection is created these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * are set to ip_output() and tcp_input() respectively. During the lifetime of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 * the connection the send and receive functions may change depending on the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 * changes in the connection state. For example, Once the connection is bound to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 * an addresse, the receive function for this connection is set to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 * tcp_conn_request().  This allows incoming SYNs to go directly into the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 * listener SYN processing function without going to tcp_input() first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * Classifier uses several hash tables:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 * 	ipcl_conn_fanout:	contains all TCP connections in CONNECTED state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 *	ipcl_bind_fanout:	contains all connections in BOUND state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 *	ipcl_proto_fanout:	IPv4 protocol fanout
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 *	ipcl_proto_fanout_v6:	IPv6 protocol fanout
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 *	ipcl_udp_fanout:	contains all UDP connections
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 *	ipcl_globalhash_fanout:	contains all connections
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * The ipcl_globalhash_fanout is used for any walkers (like snmp and Clustering)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * which need to view all existing connections.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * All tables are protected by per-bucket locks. When both per-bucket lock and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * connection lock need to be held, the per-bucket lock should be acquired
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 * first, followed by the connection lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 * All functions doing search in one of these tables increment a reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * counter on the connection found (if any). This reference should be dropped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * when the caller has finished processing the connection.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 * INTERFACES:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * ===========
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * Connection Lookup:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * ------------------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 * conn_t *ipcl_classify_v4(mp, protocol, hdr_len, zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 * conn_t *ipcl_classify_v6(mp, protocol, hdr_len, zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 * Finds connection for an incoming IPv4 or IPv6 packet. Returns NULL if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 * it can't find any associated connection. If the connection is found, its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 * reference counter is incremented.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 *	mp:	mblock, containing packet header. The full header should fit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 *		into a single mblock. It should also contain at least full IP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 *		and TCP or UDP header.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 *	protocol: Either IPPROTO_TCP or IPPROTO_UDP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 *	hdr_len: The size of IP header. It is used to find TCP or UDP header in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 *		 the packet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 * 	zoneid: The zone in which the returned connection must be.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *	For TCP connections, the lookup order is as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 *		5-tuple {src, dst, protocol, local port, remote port}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 *			lookup in ipcl_conn_fanout table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 *		3-tuple {dst, remote port, protocol} lookup in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 *			ipcl_bind_fanout table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 *	For UDP connections, a 5-tuple {src, dst, protocol, local port,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 *	remote port} lookup is done on ipcl_udp_fanout. Note that,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 *	these interfaces do not handle cases where a packets belongs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 *	to multiple UDP clients, which is handled in IP itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 * conn_t	*ipcl_tcp_lookup_reversed_ipv4(ipha_t *, tcph_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 * conn_t	*ipcl_tcp_lookup_reversed_ipv6(ip6_t *, tcpha_t *, int, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 *	Lookup routine to find a exact match for {src, dst, local port,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 *	remote port) for TCP connections in ipcl_conn_fanout. The address and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 *	ports are read from the IP and TCP header respectively.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * conn_t	*ipcl_lookup_listener_v4(lport, laddr, protocol);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * conn_t	*ipcl_lookup_listener_v6(lport, laddr, protocol, ifindex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 * 	Lookup routine to find a listener with the tuple {lport, laddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 * 	protocol} in the ipcl_bind_fanout table. For IPv6, an additional
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 * 	parameter interface index is also compared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 * void ipcl_walk(func, arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 * 	Apply 'func' to every connection available. The 'func' is called as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 *	(*func)(connp, arg). The walk is non-atomic so connections may be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 *	created and destroyed during the walk. The CONN_CONDEMNED and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 *	CONN_INCIPIENT flags ensure that connections which are newly created
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 *	or being destroyed are not selected by the walker.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 * Table Updates
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 * -------------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 * int ipcl_conn_insert(connp, protocol, src, dst, ports)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 * int ipcl_conn_insert_v6(connp, protocol, src, dst, ports, ifindex)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 *	Insert 'connp' in the ipcl_conn_fanout.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 *	Arguements :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 *		connp		conn_t to be inserted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
 *		protocol	connection protocol
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
 *		src		source address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
 *		dst		destination address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
 *		ports		local and remote port
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 *		ifindex		interface index for IPv6 connections
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 *	Return value :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
 *		0		if connp was inserted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
 *		EADDRINUSE	if the connection with the same tuple
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
 *				already exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
 * int ipcl_bind_insert(connp, protocol, src, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
 * int ipcl_bind_insert_v6(connp, protocol, src, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
 * 	Insert 'connp' in ipcl_bind_fanout.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
 * 	Arguements :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
 * 		connp		conn_t to be inserted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
 * 		protocol	connection protocol
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
 * 		src		source address connection wants
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 * 				to bind to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
 * 		lport		local port connection wants to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
 * 				bind to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
 * void ipcl_hash_remove(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 * 	Removes the 'connp' from the connection fanout table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
 * Connection Creation/Destruction
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
 * -------------------------------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
 * conn_t *ipcl_conn_create(type, sleep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
 * 	Creates a new conn based on the type flag, inserts it into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
 * 	globalhash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
 *	type:	This flag determines the type of conn_t which needs to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
 *		created.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
 *		IPCL_TCPCONN	indicates a TCP connection
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
 *		IPCL_IPCONN	indicates all non-TCP connections.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
 * void ipcl_conn_destroy(connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
 * 	Destroys the connection state, removes it from the global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
 * 	connection hash table and frees its memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
#include <sys/stream.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
#include <sys/dlpi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
#include <sys/stropts.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
#include <sys/strsubr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
#include <sys/strlog.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
#include <sys/strsun.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
#define	_SUN_TPI_VERSION 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
#include <sys/ddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
#include <sys/isa_defs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
#include <inet/common.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
#include <netinet/ip6.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
#include <netinet/icmp6.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
#include <inet/ip.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
#include <inet/ip6.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
#include <inet/tcp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
#include <inet/tcp_trace.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
#include <inet/ip_multi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
#include <inet/ip_if.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
#include <inet/ip_ire.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
#include <inet/ip_rts.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
#include <inet/optcom.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
#include <inet/ip_ndp.h>
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   236
#include <inet/udp_impl.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
#include <inet/sctp_ip.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
#include <sys/ethernet.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
#include <net/if_types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
#include <inet/mi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
#include <inet/ipclassifier.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
#include <inet/ipsec_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
#define	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
#undef	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
#ifdef	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
int	ipcl_debug_level = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
#define	IPCL_DEBUG_LVL(level, args)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	if (ipcl_debug_level  & level) { printf args; }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
#define	IPCL_DEBUG_LVL(level, args) {; }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
connf_t	*ipcl_conn_fanout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
connf_t	*ipcl_bind_fanout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
connf_t	ipcl_proto_fanout[IPPROTO_MAX + 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
connf_t	ipcl_proto_fanout_v6[IPPROTO_MAX + 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
connf_t	*ipcl_udp_fanout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
/* A separate hash list for raw socket. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
connf_t *ipcl_raw_fanout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
connf_t rts_clients;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
/* Old value for compatibility */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
uint_t tcp_conn_hash_size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
/* New value. Zero means choose automatically. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
uint_t ipcl_conn_hash_size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
uint_t ipcl_conn_hash_memfactor = 8192;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
uint_t ipcl_conn_hash_maxsize = 82500;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
uint_t ipcl_conn_fanout_size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
/* bind/udp fanout table size */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
uint_t ipcl_bind_fanout_size = 512;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
uint_t ipcl_udp_fanout_size = 256;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
/* Raw socket fanout size.  Must be a power of 2. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
uint_t ipcl_raw_fanout_size = 256;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 * Power of 2^N Primes useful for hashing for N of 0-28,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 * these primes are the nearest prime <= 2^N - 2^(N-2).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
#define	P2Ps() {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 761, 1531, 3067,	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		6143, 12281, 24571, 49139, 98299, 196597, 393209,	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		786431, 1572853, 3145721, 6291449, 12582893, 25165813,	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		50331599, 100663291, 201326557, 0}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
 * wrapper structure to ensure that conn+tcpb are aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
 * on cache lines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
typedef struct itc_s {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	union {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
		conn_t	itcu_conn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		char	itcu_filler[CACHE_ALIGN(conn_s)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	}	itc_u;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	tcp_t	itc_tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
} itc_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
#define	itc_conn	itc_u.itcu_conn
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
struct kmem_cache  *ipcl_tcpconn_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
struct kmem_cache  *ipcl_tcp_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
struct kmem_cache  *ipcl_conn_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
extern struct kmem_cache  *sctp_conn_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
extern struct kmem_cache  *tcp_sack_info_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
extern struct kmem_cache  *tcp_iphc_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
extern void	tcp_timermp_free(tcp_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
extern mblk_t	*tcp_timermp_alloc(int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
static int	ipcl_tcpconn_constructor(void *, void *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
static void	ipcl_tcpconn_destructor(void *, void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
static int conn_g_index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
connf_t	*ipcl_globalhash_fanout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
#ifdef	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
#define	INET_NTOA_BUFSIZE	18
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
inet_ntoa_r(uint32_t in, char *b)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	unsigned char	*p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	p = (unsigned char *)&in;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	(void) sprintf(b, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	return (b);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
 * ipclassifier intialization routine, sets up hash tables and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
 * conn caches.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
ipcl_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	int sizes[] = P2Ps();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	ipcl_conn_cache = kmem_cache_create("ipcl_conn_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	    sizeof (conn_t), CACHE_ALIGN_SIZE,
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   355
	    NULL, NULL, NULL, NULL, NULL, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	ipcl_tcpconn_cache = kmem_cache_create("ipcl_tcpconn_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	    sizeof (itc_t), CACHE_ALIGN_SIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	    ipcl_tcpconn_constructor, ipcl_tcpconn_destructor,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	    NULL, NULL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	 * Calculate size of conn fanout table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	if (ipcl_conn_hash_size != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
		ipcl_conn_fanout_size = ipcl_conn_hash_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	} else if (tcp_conn_hash_size != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		ipcl_conn_fanout_size = tcp_conn_hash_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		extern pgcnt_t freemem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
		ipcl_conn_fanout_size =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
		    (freemem * PAGESIZE) / ipcl_conn_hash_memfactor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
		if (ipcl_conn_fanout_size > ipcl_conn_hash_maxsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
			ipcl_conn_fanout_size = ipcl_conn_hash_maxsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	for (i = 9; i < sizeof (sizes) / sizeof (*sizes) - 1; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		if (sizes[i] >= ipcl_conn_fanout_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	if ((ipcl_conn_fanout_size = sizes[i]) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		/* Out of range, use the 2^16 value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		ipcl_conn_fanout_size = sizes[16];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	ipcl_conn_fanout = (connf_t *)kmem_zalloc(ipcl_conn_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	    sizeof (*ipcl_conn_fanout), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	for (i = 0; i < ipcl_conn_fanout_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		mutex_init(&ipcl_conn_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	ipcl_bind_fanout = (connf_t *)kmem_zalloc(ipcl_bind_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	    sizeof (*ipcl_bind_fanout), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	for (i = 0; i < ipcl_bind_fanout_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		mutex_init(&ipcl_bind_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
	for (i = 0; i < A_CNT(ipcl_proto_fanout); i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
		mutex_init(&ipcl_proto_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	for (i = 0; i < A_CNT(ipcl_proto_fanout_v6); i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
		mutex_init(&ipcl_proto_fanout_v6[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	mutex_init(&rts_clients.connf_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	ipcl_udp_fanout = (connf_t *)kmem_zalloc(ipcl_udp_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	    sizeof (*ipcl_udp_fanout), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	for (i = 0; i < ipcl_udp_fanout_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
		mutex_init(&ipcl_udp_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	ipcl_raw_fanout = (connf_t *)kmem_zalloc(ipcl_raw_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	    sizeof (*ipcl_raw_fanout), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	for (i = 0; i < ipcl_raw_fanout_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
		mutex_init(&ipcl_raw_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	ipcl_globalhash_fanout = (connf_t *)kmem_zalloc(sizeof (connf_t) *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	    CONN_G_HASH_SIZE, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	for (i = 0; i < CONN_G_HASH_SIZE; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
		mutex_init(&ipcl_globalhash_fanout[i].connf_lock, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
		    MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
ipcl_destroy(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	kmem_cache_destroy(ipcl_conn_cache);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	kmem_cache_destroy(ipcl_tcpconn_cache);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	for (i = 0; i < ipcl_conn_fanout_size; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		mutex_destroy(&ipcl_conn_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	kmem_free(ipcl_conn_fanout, ipcl_conn_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	    sizeof (*ipcl_conn_fanout));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	for (i = 0; i < ipcl_bind_fanout_size; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
		mutex_destroy(&ipcl_bind_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	kmem_free(ipcl_bind_fanout, ipcl_bind_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	    sizeof (*ipcl_bind_fanout));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	for (i = 0; i < A_CNT(ipcl_proto_fanout); i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		mutex_destroy(&ipcl_proto_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	for (i = 0; i < A_CNT(ipcl_proto_fanout_v6); i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		mutex_destroy(&ipcl_proto_fanout_v6[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	for (i = 0; i < ipcl_udp_fanout_size; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
		mutex_destroy(&ipcl_udp_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	kmem_free(ipcl_udp_fanout, ipcl_udp_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	    sizeof (*ipcl_udp_fanout));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	for (i = 0; i < ipcl_raw_fanout_size; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		mutex_destroy(&ipcl_raw_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	kmem_free(ipcl_raw_fanout, ipcl_raw_fanout_size *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	    sizeof (*ipcl_raw_fanout));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	kmem_free(ipcl_globalhash_fanout, sizeof (connf_t) * CONN_G_HASH_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	mutex_destroy(&rts_clients.connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
 * conn creation routine. initialize the conn, sets the reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
 * and inserts it in the global hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
ipcl_conn_create(uint32_t type, int sleep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	itc_t	*itc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	conn_t	*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	switch (type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	case IPCL_TCPCONN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
		if ((itc = kmem_cache_alloc(ipcl_tcpconn_cache,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		    sleep)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		connp = &itc->itc_conn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
		connp->conn_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		IPCL_DEBUG_LVL(1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
		    ("ipcl_conn_create: connp = %p tcp (%p)",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
		    (void *)connp, (void *)connp->conn_tcp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
		ipcl_globalhash_insert(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	case IPCL_SCTPCONN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
		if ((connp = kmem_cache_alloc(sctp_conn_cache, sleep)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
		connp->conn_flags = IPCL_SCTPCONN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	case IPCL_IPCCONN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		connp = kmem_cache_alloc(ipcl_conn_cache, sleep);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
		if (connp == NULL)
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   504
			return (NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		bzero(connp, sizeof (conn_t));
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   506
		mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL);
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   508
		connp->conn_flags = IPCL_IPCCONN;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
		connp->conn_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
		IPCL_DEBUG_LVL(1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
		    ("ipcl_conn_create: connp = %p\n", (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
		ipcl_globalhash_insert(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
		break;
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   514
	default:
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   515
		connp = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   516
		ASSERT(0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
ipcl_conn_destroy(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	mblk_t	*mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
	ASSERT(!MUTEX_HELD(&connp->conn_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
	ASSERT(connp->conn_ref == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	ASSERT(connp->conn_ire_cache == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	ipcl_globalhash_remove(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	cv_destroy(&connp->conn_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
	if (connp->conn_flags & IPCL_TCPCONN) {
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   535
		tcp_t	*tcp = connp->conn_tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   536
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
		mutex_destroy(&connp->conn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
		ASSERT(connp->conn_tcp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
		tcp_free(tcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		mp = tcp->tcp_timercache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		if (tcp->tcp_sack_info != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
			bzero(tcp->tcp_sack_info, sizeof (tcp_sack_info_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
			kmem_cache_free(tcp_sack_info_cache,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
			    tcp->tcp_sack_info);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
		if (tcp->tcp_iphc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
			if (tcp->tcp_hdr_grown) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
				kmem_free(tcp->tcp_iphc, tcp->tcp_iphc_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
				bzero(tcp->tcp_iphc, tcp->tcp_iphc_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
				kmem_cache_free(tcp_iphc_cache, tcp->tcp_iphc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
			tcp->tcp_iphc_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		ASSERT(tcp->tcp_iphc_len == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
		if (connp->conn_latch != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
			IPLATCH_REFRELE(connp->conn_latch);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
		if (connp->conn_policy != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
			IPPH_REFRELE(connp->conn_policy);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		bzero(connp, sizeof (itc_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		tcp->tcp_timercache = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		connp->conn_tcp = tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		connp->conn_flags = IPCL_TCPCONN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
		connp->conn_ulp = IPPROTO_TCP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
		tcp->tcp_connp = connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		kmem_cache_free(ipcl_tcpconn_cache, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	} else if (connp->conn_flags & IPCL_SCTPCONN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
		sctp_free(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
	} else {
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
   573
		ASSERT(connp->conn_udp == NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		mutex_destroy(&connp->conn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		kmem_cache_free(ipcl_conn_cache, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
 * Running in cluster mode - deregister listener information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
ipcl_conn_unlisten(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	ASSERT((connp->conn_flags & IPCL_CL_LISTENER) != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
	ASSERT(connp->conn_lport != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
	if (cl_inet_unlisten != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
		sa_family_t	addr_family;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
		uint8_t		*laddrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
		if (connp->conn_pkt_isv6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
			addr_family = AF_INET6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
			laddrp = (uint8_t *)&connp->conn_bound_source_v6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
			addr_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
			laddrp = (uint8_t *)&connp->conn_bound_source;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
		(*cl_inet_unlisten)(IPPROTO_TCP, addr_family, laddrp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
		    connp->conn_lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	connp->conn_flags &= ~IPCL_CL_LISTENER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
 * We set the IPCL_REMOVED flag (instead of clearing the flag indicating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
 * which table the conn belonged to). So for debugging we can see which hash
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
 * table this connection was in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
#define	IPCL_HASH_REMOVE(connp)	{					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	connf_t	*connfp = (connp)->conn_fanout;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	ASSERT(!MUTEX_HELD(&((connp)->conn_lock)));			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	if (connfp != NULL) {						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
		IPCL_DEBUG_LVL(4, ("IPCL_HASH_REMOVE: connp %p",	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
		    (void *)(connp)));					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
		mutex_enter(&connfp->connf_lock);			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
		if ((connp)->conn_next != NULL)				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
			(connp)->conn_next->conn_prev =			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
			    (connp)->conn_prev;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		if ((connp)->conn_prev != NULL)				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
			(connp)->conn_prev->conn_next =			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
			    (connp)->conn_next;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
		else							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
			connfp->connf_head = (connp)->conn_next;	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		(connp)->conn_fanout = NULL;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		(connp)->conn_next = NULL;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		(connp)->conn_prev = NULL;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
		(connp)->conn_flags |= IPCL_REMOVED;			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
		if (((connp)->conn_flags & IPCL_CL_LISTENER) != 0)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
			ipcl_conn_unlisten((connp));			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
		CONN_DEC_REF((connp));					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		mutex_exit(&connfp->connf_lock);			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
ipcl_hash_remove(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	IPCL_HASH_REMOVE(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
 * The whole purpose of this function is allow removal of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
 * a conn_t from the connected hash for timewait reclaim.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
 * This is essentially a TW reclaim fastpath where timewait
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
 * collector checks under fanout lock (so no one else can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
 * get access to the conn_t) that refcnt is 2 i.e. one for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
 * TCP and one for the classifier hash list. If ref count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
 * is indeed 2, we can just remove the conn under lock and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
 * avoid cleaning up the conn under squeue. This gives us
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
 * improved performance.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
ipcl_hash_remove_locked(conn_t *connp, connf_t	*connfp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
	ASSERT(MUTEX_HELD(&connfp->connf_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	ASSERT(MUTEX_HELD(&connp->conn_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
	ASSERT((connp->conn_flags & IPCL_CL_LISTENER) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	if ((connp)->conn_next != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		(connp)->conn_next->conn_prev =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
			(connp)->conn_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	if ((connp)->conn_prev != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
		(connp)->conn_prev->conn_next =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
			(connp)->conn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
		connfp->connf_head = (connp)->conn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	(connp)->conn_fanout = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	(connp)->conn_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	(connp)->conn_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	(connp)->conn_flags |= IPCL_REMOVED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	ASSERT((connp)->conn_ref == 2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	(connp)->conn_ref--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
#define	IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp) {		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	ASSERT((connp)->conn_fanout == NULL);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	ASSERT((connp)->conn_next == NULL);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	ASSERT((connp)->conn_prev == NULL);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	if ((connfp)->connf_head != NULL) {				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		(connfp)->connf_head->conn_prev = (connp);		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
		(connp)->conn_next = (connfp)->connf_head;		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	(connp)->conn_fanout = (connfp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	(connfp)->connf_head = (connp);					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
	(connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) |	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	    IPCL_CONNECTED;						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	CONN_INC_REF(connp);						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
#define	IPCL_HASH_INSERT_CONNECTED(connfp, connp) {			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	IPCL_DEBUG_LVL(8, ("IPCL_HASH_INSERT_CONNECTED: connfp %p "	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	    "connp %p", (void *)(connfp), (void *)(connp)));		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	IPCL_HASH_REMOVE((connp));					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	mutex_enter(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	mutex_exit(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
#define	IPCL_HASH_INSERT_BOUND(connfp, connp) {				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
	conn_t *pconnp = NULL, *nconnp;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
	IPCL_DEBUG_LVL(32, ("IPCL_HASH_INSERT_BOUND: connfp %p "	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	    "connp %p", (void *)connfp, (void *)(connp)));		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	IPCL_HASH_REMOVE((connp));					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
	mutex_enter(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	nconnp = (connfp)->connf_head;					\
153
b7f7b242faa2 5013200 ipclassifier bind list insertion order is flawed in some cases
ethindra
parents: 0
diff changeset
   710
	while (nconnp != NULL &&					\
b7f7b242faa2 5013200 ipclassifier bind list insertion order is flawed in some cases
ethindra
parents: 0
diff changeset
   711
	    !_IPCL_V4_MATCH_ANY(nconnp->conn_srcv6)) {			\
b7f7b242faa2 5013200 ipclassifier bind list insertion order is flawed in some cases
ethindra
parents: 0
diff changeset
   712
		pconnp = nconnp;					\
b7f7b242faa2 5013200 ipclassifier bind list insertion order is flawed in some cases
ethindra
parents: 0
diff changeset
   713
		nconnp = nconnp->conn_next;				\
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	if (pconnp != NULL) {						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
		pconnp->conn_next = (connp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		(connp)->conn_prev = pconnp;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
	} else {							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		(connfp)->connf_head = (connp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
	if (nconnp != NULL) {						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
		(connp)->conn_next = nconnp;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
		nconnp->conn_prev = (connp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	(connp)->conn_fanout = (connfp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	(connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) |	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	    IPCL_BOUND;							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	CONN_INC_REF(connp);						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	mutex_exit(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
#define	IPCL_HASH_INSERT_WILDCARD(connfp, connp) {			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
	conn_t **list, *prev, *next;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	boolean_t isv4mapped =						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
	    IN6_IS_ADDR_V4MAPPED(&(connp)->conn_srcv6);			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	IPCL_DEBUG_LVL(32, ("IPCL_HASH_INSERT_WILDCARD: connfp %p "	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
	    "connp %p", (void *)(connfp), (void *)(connp)));		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
	IPCL_HASH_REMOVE((connp));					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
	mutex_enter(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
	list = &(connfp)->connf_head;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	prev = NULL;							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	while ((next = *list) != NULL) {				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
		if (isv4mapped &&					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
		    IN6_IS_ADDR_UNSPECIFIED(&next->conn_srcv6) &&	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		    connp->conn_zoneid == next->conn_zoneid) {		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
			(connp)->conn_next = next;			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
			if (prev != NULL)				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
				prev = next->conn_prev;			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
			next->conn_prev = (connp);			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
			break;						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		}							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
		list = &next->conn_next;				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
		prev = next;						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	}								\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	(connp)->conn_prev = prev;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	*list = (connp);						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	(connp)->conn_fanout = (connfp);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	(connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) |	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	    IPCL_BOUND;							\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	CONN_INC_REF((connp));						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	mutex_exit(&(connfp)->connf_lock);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
ipcl_hash_insert_wildcard(connf_t *connfp, conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
ipcl_proto_insert(conn_t *connp, uint8_t protocol)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	ASSERT(connp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	connp->conn_ulp = protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	/* Insert it in the protocol hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	connfp = &ipcl_proto_fanout[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
ipcl_proto_insert_v6(conn_t *connp, uint8_t protocol)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
	ASSERT(connp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	connp->conn_ulp = protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	/* Insert it in the Bind Hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	connfp = &ipcl_proto_fanout_v6[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
	IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
 * This function is used only for inserting SCTP raw socket now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
 * This may change later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
 * Note that only one raw socket can be bound to a port.  The param
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
 * lport is in network byte order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
ipcl_sctp_hash_insert(conn_t *connp, in_port_t lport)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
	conn_t	*oconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
	connfp = &ipcl_raw_fanout[IPCL_RAW_HASH(ntohs(lport))];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	/* Check for existing raw socket already bound to the port. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
	for (oconnp = connfp->connf_head; oconnp != NULL;
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
   816
	    oconnp = oconnp->conn_next) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		if (oconnp->conn_lport == lport &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		    oconnp->conn_zoneid == connp->conn_zoneid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
		    oconnp->conn_af_isv6 == connp->conn_af_isv6 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		    ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
		    IN6_IS_ADDR_UNSPECIFIED(&oconnp->conn_srcv6) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
		    IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_srcv6) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		    IN6_IS_ADDR_V4MAPPED_ANY(&oconnp->conn_srcv6)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
		    IN6_ARE_ADDR_EQUAL(&oconnp->conn_srcv6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		    &connp->conn_srcv6))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	if (oconnp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
		return (EADDRNOTAVAIL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_remv6) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	    IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_remv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
		    IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_srcv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
		IPCL_HASH_INSERT_CONNECTED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
 * (v4, v6) bind hash insertion routines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
ipcl_bind_insert(conn_t *connp, uint8_t protocol, ipaddr_t src, uint16_t lport)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
#ifdef	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	char	buf[INET_NTOA_BUFSIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	int	ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	ASSERT(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	IPCL_DEBUG_LVL(64, ("ipcl_bind_insert: connp %p, src = %s, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	    "port = %d\n", (void *)connp, inet_ntoa_r(src, buf), lport));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	connp->conn_ulp = protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	IN6_IPADDR_TO_V4MAPPED(src, &connp->conn_srcv6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	connp->conn_lport = lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
		if (protocol == IPPROTO_UDP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
			IPCL_DEBUG_LVL(64,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
			    ("ipcl_bind_insert: connp %p - udp\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
			    (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
			connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
			IPCL_DEBUG_LVL(64,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
			    ("ipcl_bind_insert: connp %p - protocol\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
			    (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
			connfp = &ipcl_proto_fanout[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
		if (connp->conn_rem != INADDR_ANY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
			IPCL_HASH_INSERT_CONNECTED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
		} else if (connp->conn_src != INADDR_ANY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
		/* Insert it in the Bind Hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
		connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
		if (connp->conn_src != INADDR_ANY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
		if (cl_inet_listen != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
			ASSERT(!connp->conn_pkt_isv6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
			connp->conn_flags |= IPCL_CL_LISTENER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
			(*cl_inet_listen)(IPPROTO_TCP, AF_INET,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
			    (uint8_t *)&connp->conn_bound_source, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	case IPPROTO_SCTP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
		ret = ipcl_sctp_hash_insert(connp, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
ipcl_bind_insert_v6(conn_t *connp, uint8_t protocol, const in6_addr_t *src,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
    uint16_t lport)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	int	ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
	ASSERT(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	connp->conn_ulp = protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	connp->conn_srcv6 = *src;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
	connp->conn_lport = lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
		if (protocol == IPPROTO_UDP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
			IPCL_DEBUG_LVL(128,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
			    ("ipcl_bind_insert_v6: connp %p - udp\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
			    (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
			connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
			IPCL_DEBUG_LVL(128,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
			    ("ipcl_bind_insert_v6: connp %p - protocol\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
			    (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
			connfp = &ipcl_proto_fanout_v6[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
		if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_remv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
			IPCL_HASH_INSERT_CONNECTED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
		} else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
		/* XXX - Need a separate table for IN6_IS_ADDR_UNSPECIFIED? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
		/* Insert it in the Bind Hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
		if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		if (cl_inet_listen != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
			sa_family_t	addr_family;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
			uint8_t		*laddrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
			if (connp->conn_pkt_isv6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
				addr_family = AF_INET6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
				laddrp =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
				    (uint8_t *)&connp->conn_bound_source_v6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
				addr_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
				laddrp = (uint8_t *)&connp->conn_bound_source;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
			connp->conn_flags |= IPCL_CL_LISTENER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
			(*cl_inet_listen)(IPPROTO_TCP, addr_family, laddrp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
			    lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	case IPPROTO_SCTP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
		ret = ipcl_sctp_hash_insert(connp, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
 * ipcl_conn_hash insertion routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
ipcl_conn_insert(conn_t *connp, uint8_t protocol, ipaddr_t src,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
    ipaddr_t rem, uint32_t ports)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
	connf_t		*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	uint16_t	*up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	conn_t		*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
#ifdef	IPCL_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	char	sbuf[INET_NTOA_BUFSIZE], rbuf[INET_NTOA_BUFSIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	in_port_t	lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
	int		ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	IPCL_DEBUG_LVL(256, ("ipcl_conn_insert: connp %p, src = %s, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	    "dst = %s, ports = %x, protocol = %x", (void *)connp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	    inet_ntoa_r(src, sbuf), inet_ntoa_r(rem, rbuf),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	    ports, protocol));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
		if (!(connp->conn_flags & IPCL_EAGER)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
			 * for a eager connection, i.e connections which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
			 * have just been created, the initialization is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
			 * already done in ip at conn_creation time, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
			 * we can skip the checks here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
			IPCL_CONN_INIT(connp, protocol, src, rem, ports);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
		connfp = &ipcl_conn_fanout[IPCL_CONN_HASH(connp->conn_rem,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
		    connp->conn_ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
		for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
		    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
			if (IPCL_CONN_MATCH(tconnp, connp->conn_ulp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
			    connp->conn_rem, connp->conn_src,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
			    connp->conn_ports)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
				/* Already have a conn. bail out */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
				mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
				return (EADDRINUSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
		if (connp->conn_fanout != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
			 * Probably a XTI/TLI application trying to do a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
			 * rebind. Let it happen.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
			IPCL_HASH_REMOVE(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
			mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
		IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	case IPPROTO_SCTP:
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1050
		/*
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1051
		 * The raw socket may have already been bound, remove it
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1052
		 * from the hash first.
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1053
		 */
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1054
		IPCL_HASH_REMOVE(connp);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1055
		lport = htons((uint16_t)(ntohl(ports) & 0xFFFF));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
		ret = ipcl_sctp_hash_insert(connp, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
		up = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
		IPCL_CONN_INIT(connp, protocol, src, rem, ports);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
		if (protocol == IPPROTO_UDP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
			connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(up[1])];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
			connfp = &ipcl_proto_fanout[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
		if (connp->conn_rem != INADDR_ANY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
			IPCL_HASH_INSERT_CONNECTED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
		} else if (connp->conn_src != INADDR_ANY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
ipcl_conn_insert_v6(conn_t *connp, uint8_t protocol, const in6_addr_t *src,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
    const in6_addr_t *rem, uint32_t ports, uint_t ifindex)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
	connf_t		*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
	uint16_t	*up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
	conn_t		*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
	in_port_t	lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
	int		ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
		/* Just need to insert a conn struct */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
		if (!(connp->conn_flags & IPCL_EAGER)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
			IPCL_CONN_INIT_V6(connp, protocol, *src, *rem, ports);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		connfp = &ipcl_conn_fanout[IPCL_CONN_HASH_V6(connp->conn_remv6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
		    connp->conn_ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
		for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
		    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
			if (IPCL_CONN_MATCH_V6(tconnp, connp->conn_ulp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
			    connp->conn_remv6, connp->conn_srcv6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
			    connp->conn_ports) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
			    (tconnp->conn_tcp->tcp_bound_if == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
			    tconnp->conn_tcp->tcp_bound_if == ifindex)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
				/* Already have a conn. bail out */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
				mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
				return (EADDRINUSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
		if (connp->conn_fanout != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
			 * Probably a XTI/TLI application trying to do a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
			 * rebind. Let it happen.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
			IPCL_HASH_REMOVE(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
			mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
		IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
	case IPPROTO_SCTP:
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1127
		IPCL_HASH_REMOVE(connp);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1128
		lport = htons((uint16_t)(ntohl(ports) & 0xFFFF));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
		ret = ipcl_sctp_hash_insert(connp, lport);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		up = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
		IPCL_CONN_INIT_V6(connp, protocol, *src, *rem, ports);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
		if (protocol == IPPROTO_UDP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
			connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(up[1])];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
			connfp = &ipcl_proto_fanout_v6[protocol];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
		if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_remv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
			IPCL_HASH_INSERT_CONNECTED(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
		} else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
			IPCL_HASH_INSERT_BOUND(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
 * v4 packet classifying function. looks up the fanout table to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
 * find the conn, the packet belongs to. returns the conn with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
 * the reference held, null otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
ipcl_classify_v4(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
	ipha_t	*ipha;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
	connf_t	*connfp, *bind_connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
	uint16_t lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
	uint16_t fport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	uint32_t ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	conn_t	*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	uint16_t  *up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	ipha = (ipha_t *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	up = (uint16_t *)((uchar_t *)ipha + hdr_len + TCP_PORTS_OFFSET);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
		ports = *(uint32_t *)up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
		connfp =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
		    &ipcl_conn_fanout[IPCL_CONN_HASH(ipha->ipha_src, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
		for (connp = connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
			if (IPCL_CONN_MATCH(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
			    ipha->ipha_src, ipha->ipha_dst, ports))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
		lport = up[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
		bind_connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
		mutex_enter(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
		for (connp = bind_connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
			if (IPCL_BIND_MATCH(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
			    ipha->ipha_dst, lport) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
			    connp->conn_zoneid == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
			/* Have a listner at least */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
			mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
		mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
		IPCL_DEBUG_LVL(512,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
		    ("ipcl_classify: couldn't classify mp = %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
		    (void *)mp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
		lport = up[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
		fport = up[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
		IPCL_DEBUG_LVL(512, ("ipcl_udp_classify %x %x", lport, fport));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
		connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
		for (connp = connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
			if (IPCL_UDP_MATCH(connp, lport, ipha->ipha_dst,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
			    fport, ipha->ipha_src) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
			    connp->conn_zoneid == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		 * We shouldn't come here for multicast/broadcast packets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
		IPCL_DEBUG_LVL(512,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
		    ("ipcl_classify: cant find udp conn_t for ports : %x %x",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		    lport, fport));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
ipcl_classify_v6(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
	ip6_t		*ip6h;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
	connf_t		*connfp, *bind_connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	uint16_t	lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
	uint16_t	fport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	tcph_t		*tcph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
	uint32_t	ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
	conn_t		*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
	uint16_t	*up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
	ip6h = (ip6_t *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
	case IPPROTO_TCP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
		tcph = (tcph_t *)&mp->b_rptr[hdr_len];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
		up = (uint16_t *)tcph->th_lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
		ports = *(uint32_t *)up;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
		connfp =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
		    &ipcl_conn_fanout[IPCL_CONN_HASH_V6(ip6h->ip6_src, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		for (connp = connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
			if (IPCL_CONN_MATCH_V6(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
			    ip6h->ip6_src, ip6h->ip6_dst, ports))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
		lport = up[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
		bind_connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
		mutex_enter(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
		for (connp = bind_connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
			if (IPCL_BIND_MATCH_V6(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
			    ip6h->ip6_dst, lport) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
			    connp->conn_zoneid == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
			/* Have a listner at least */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
			mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
			IPCL_DEBUG_LVL(512,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
			    ("ipcl_classify_v6: found listner "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
			    "connp = %p\n", (void *)connp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
		IPCL_DEBUG_LVL(512,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
		    ("ipcl_classify_v6: couldn't classify mp = %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
		    (void *)mp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	case IPPROTO_UDP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
		up = (uint16_t *)&mp->b_rptr[hdr_len];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
		lport = up[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
		fport = up[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
		IPCL_DEBUG_LVL(512, ("ipcl_udp_classify_v6 %x %x", lport,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
		    fport));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
		mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		for (connp = connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
		    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
			if (IPCL_UDP_MATCH_V6(connp, lport, ip6h->ip6_dst,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
			    fport, ip6h->ip6_src) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
			    connp->conn_zoneid == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		if (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
		 * We shouldn't come here for multicast/broadcast packets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
		mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
		IPCL_DEBUG_LVL(512,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		    ("ipcl_classify_v6: cant find udp conn_t for ports : %x %x",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
		    lport, fport));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
 * wrapper around ipcl_classify_(v4,v6) routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
ipcl_classify(mblk_t *mp, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	uint16_t	hdr_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	ipha_t		*ipha;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	uint8_t		*nexthdrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
	if (MBLKL(mp) < sizeof (ipha_t))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	switch (IPH_HDR_VERSION(mp->b_rptr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
	case IPV4_VERSION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
		ipha = (ipha_t *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
		hdr_len = IPH_HDR_LENGTH(ipha);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
		return (ipcl_classify_v4(mp, ipha->ipha_protocol, hdr_len,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
		    zoneid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	case IPV6_VERSION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
		if (!ip_hdr_length_nexthdr_v6(mp, (ip6_t *)mp->b_rptr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
		    &hdr_len, &nexthdrp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
		return (ipcl_classify_v6(mp, *nexthdrp, hdr_len, zoneid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
ipcl_classify_raw(uint8_t protocol, zoneid_t zoneid, uint32_t ports,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
    ipha_t *hdr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	struct connf_s	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
	conn_t		*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
	in_port_t	lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
	int		af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
	lport = ((uint16_t *)&ports)[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
	af = IPH_HDR_VERSION(hdr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	connfp = &ipcl_raw_fanout[IPCL_RAW_HASH(ntohs(lport))];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	for (connp = connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
	    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
		/* We don't allow v4 fallback for v6 raw socket. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		if ((af == (connp->conn_af_isv6 ? IPV4_VERSION :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
		    IPV6_VERSION)) || (connp->conn_zoneid != zoneid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		if (connp->conn_fully_bound) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
			if (af == IPV4_VERSION) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
				if (IPCL_CONN_MATCH(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
				    hdr->ipha_src, hdr->ipha_dst, ports)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
				if (IPCL_CONN_MATCH_V6(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
				    ((ip6_t *)hdr)->ip6_src,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
				    ((ip6_t *)hdr)->ip6_dst, ports)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
			if (af == IPV4_VERSION) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
				if (IPCL_BIND_MATCH(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
				    hdr->ipha_dst, lport)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
				if (IPCL_BIND_MATCH_V6(connp, protocol,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
				    ((ip6_t *)hdr)->ip6_dst, lport)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
	}
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1435
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1436
	if (connp != NULL)
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1437
		goto found;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1438
	mutex_exit(&connfp->connf_lock);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1439
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1440
	/* Try to look for a wildcard match. */
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1441
	connfp = &ipcl_raw_fanout[IPCL_RAW_HASH(0)];
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1442
	mutex_enter(&connfp->connf_lock);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1443
	for (connp = connfp->connf_head; connp != NULL;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1444
	    connp = connp->conn_next) {
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1445
		/* We don't allow v4 fallback for v6 raw socket. */
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1446
		if ((af == (connp->conn_af_isv6 ? IPV4_VERSION :
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1447
		    IPV6_VERSION)) || (connp->conn_zoneid != zoneid)) {
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1448
			continue;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1449
		}
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1450
		if (af == IPV4_VERSION) {
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1451
			if (IPCL_RAW_MATCH(connp, protocol, hdr->ipha_dst))
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1452
				break;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1453
		} else {
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1454
			if (IPCL_RAW_MATCH_V6(connp, protocol,
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1455
			    ((ip6_t *)hdr)->ip6_dst)) {
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1456
				break;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1457
			}
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1458
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	}
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1460
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1461
	if (connp != NULL)
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1462
		goto found;
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1463
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
	return (NULL);
409
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1466
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1467
found:
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1468
	ASSERT(connp != NULL);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1469
	CONN_INC_REF(connp);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1470
	mutex_exit(&connfp->connf_lock);
22012dc8ea5b 6294727 SCTP raw socket bind() failed for ports which are mutliples of 256
kcpoon
parents: 153
diff changeset
  1471
	return (connp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
ipcl_tcpconn_constructor(void *buf, void *cdrarg, int kmflags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	itc_t	*itc = (itc_t *)buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
	conn_t 	*connp = &itc->itc_conn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
	tcp_t	*tcp = &itc->itc_tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	bzero(itc, sizeof (itc_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
	tcp->tcp_timercache = tcp_timermp_alloc(KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	connp->conn_tcp = tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
	connp->conn_flags = IPCL_TCPCONN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	connp->conn_ulp = IPPROTO_TCP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
	tcp->tcp_connp = connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
ipcl_tcpconn_destructor(void *buf, void *cdrarg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	tcp_timermp_free(((conn_t *)buf)->conn_tcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
 * All conns are inserted in a global multi-list for the benefit of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
 * walkers. The walk is guaranteed to walk all open conns at the time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
 * of the start of the walk exactly once. This property is needed to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
 * achieve some cleanups during unplumb of interfaces. This is achieved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
 * as follows.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
 * ipcl_conn_create and ipcl_conn_destroy are the only functions that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
 * call the insert and delete functions below at creation and deletion
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
 * time respectively. The conn never moves or changes its position in this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
 * multi-list during its lifetime. CONN_CONDEMNED ensures that the refcnt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
 * won't increase due to walkers, once the conn deletion has started. Note
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
 * that we can't remove the conn from the global list and then wait for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
 * the refcnt to drop to zero, since walkers would then see a truncated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
 * list. CONN_INCIPIENT ensures that walkers don't start looking at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
 * conns until ip_open is ready to make them globally visible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
 * The global round robin multi-list locks are held only to get the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
 * next member/insertion/deletion and contention should be negligible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
 * if the multi-list is much greater than the number of cpus.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
ipcl_globalhash_insert(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
	int	index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	 * No need for atomic here. Approximate even distribution
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	 * in the global lists is sufficient.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	conn_g_index++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	index = conn_g_index & (CONN_G_HASH_SIZE - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	connp->conn_g_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	 * Mark as INCIPIENT, so that walkers will ignore this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	 * for now, till ip_open is ready to make it visible globally.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	connp->conn_state_flags |= CONN_INCIPIENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	/* Insert at the head of the list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	mutex_enter(&ipcl_globalhash_fanout[index].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	connp->conn_g_next = ipcl_globalhash_fanout[index].connf_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	if (connp->conn_g_next != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
		connp->conn_g_next->conn_g_prev = connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	ipcl_globalhash_fanout[index].connf_head = connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	/* The fanout bucket this conn points to */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	connp->conn_g_fanout = &ipcl_globalhash_fanout[index];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
	mutex_exit(&ipcl_globalhash_fanout[index].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
ipcl_globalhash_remove(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	 * We were never inserted in the global multi list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	 * IPCL_NONE variety is never inserted in the global multilist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	 * since it is presumed to not need any cleanup and is transient.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
	if (connp->conn_g_fanout == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
	mutex_enter(&connp->conn_g_fanout->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
	if (connp->conn_g_prev != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
		connp->conn_g_prev->conn_g_next = connp->conn_g_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
		connp->conn_g_fanout->connf_head = connp->conn_g_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	if (connp->conn_g_next != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
		connp->conn_g_next->conn_g_prev = connp->conn_g_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	mutex_exit(&connp->conn_g_fanout->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	/* Better to stumble on a null pointer than to corrupt memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	connp->conn_g_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	connp->conn_g_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
 * Walk the list of all conn_t's in the system, calling the function provided
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
 * with the specified argument for each.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
 * Applies to both IPv4 and IPv6.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
 * IPCs may hold pointers to ipif/ill. To guard against stale pointers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
 * ipcl_walk() is called to cleanup the conn_t's, typically when an interface is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
 * unplumbed or removed. New conn_t's that are created while we are walking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
 * may be missed by this walk, because they are not necessarily inserted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
 * at the tail of the list. They are new conn_t's and thus don't have any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
 * stale pointers. The CONN_CLOSING flag ensures that no new reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
 * is created to the struct that is going away.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
ipcl_walk(pfv_t func, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
	conn_t	*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	conn_t	*prev_connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	for (i = 0; i < CONN_G_HASH_SIZE; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
		mutex_enter(&ipcl_globalhash_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		prev_connp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		connp = ipcl_globalhash_fanout[i].connf_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		while (connp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
			mutex_enter(&connp->conn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
			if (connp->conn_state_flags &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
			    (CONN_CONDEMNED | CONN_INCIPIENT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
				mutex_exit(&connp->conn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
				connp = connp->conn_g_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
			CONN_INC_REF_LOCKED(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
			mutex_exit(&connp->conn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
			mutex_exit(&ipcl_globalhash_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
			(*func)(connp, arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
			if (prev_connp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
				CONN_DEC_REF(prev_connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
			mutex_enter(&ipcl_globalhash_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
			prev_connp = connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
			connp = connp->conn_g_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
		mutex_exit(&ipcl_globalhash_fanout[i].connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
		if (prev_connp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
			CONN_DEC_REF(prev_connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
 * Search for a peer TCP/IPv4 loopback conn by doing a reverse lookup on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
 * the {src, dst, lport, fport} quadruplet.  Returns with conn reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
 * held; caller must call CONN_DEC_REF.  Only checks for connected entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
 * (peer tcp in at least ESTABLISHED state).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
ipcl_conn_tcp_lookup_reversed_ipv4(conn_t *connp, ipha_t *ipha, tcph_t *tcph)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	uint32_t ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	uint16_t *pports = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	conn_t	*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	boolean_t zone_chk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
	 * If either the source of destination address is loopback, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
	 * both endpoints must be in the same Zone.  Otherwise, both of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	 * the addresses are system-wide unique (tcp is in ESTABLISHED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	 * state) and the endpoints may reside in different Zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
	zone_chk = (ipha->ipha_src == htonl(INADDR_LOOPBACK) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	    ipha->ipha_dst == htonl(INADDR_LOOPBACK));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
	bcopy(tcph->th_fport, &pports[0], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	bcopy(tcph->th_lport, &pports[1], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
	connfp = &ipcl_conn_fanout[IPCL_CONN_HASH(ipha->ipha_dst, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
		if (IPCL_CONN_MATCH(tconnp, IPPROTO_TCP,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
		    ipha->ipha_dst, ipha->ipha_src, ports) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
		    tconnp->conn_tcp->tcp_state >= TCPS_ESTABLISHED &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
		    (!zone_chk || tconnp->conn_zoneid == connp->conn_zoneid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
			ASSERT(tconnp != connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
			CONN_INC_REF(tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
			return (tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
 * Search for a peer TCP/IPv6 loopback conn by doing a reverse lookup on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
 * the {src, dst, lport, fport} quadruplet.  Returns with conn reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
 * held; caller must call CONN_DEC_REF.  Only checks for connected entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
 * (peer tcp in at least ESTABLISHED state).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
ipcl_conn_tcp_lookup_reversed_ipv6(conn_t *connp, ip6_t *ip6h, tcph_t *tcph)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
	uint32_t ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
	uint16_t *pports = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
	conn_t	*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
	boolean_t zone_chk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	 * If either the source of destination address is loopback, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	 * both endpoints must be in the same Zone.  Otherwise, both of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
	 * the addresses are system-wide unique (tcp is in ESTABLISHED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	 * state) and the endpoints may reside in different Zones.  We
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
	 * don't do Zone check for link local address(es) because the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	 * current Zone implementation treats each link local address as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
	 * being unique per system node, i.e. they belong to global Zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
	zone_chk = (IN6_IS_ADDR_LOOPBACK(&ip6h->ip6_src) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
	    IN6_IS_ADDR_LOOPBACK(&ip6h->ip6_dst));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
	bcopy(tcph->th_fport, &pports[0], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
	bcopy(tcph->th_lport, &pports[1], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
	connfp = &ipcl_conn_fanout[IPCL_CONN_HASH_V6(ip6h->ip6_dst, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
	for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
	    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
		/* We skip tcp_bound_if check here as this is loopback tcp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
		if (IPCL_CONN_MATCH_V6(tconnp, IPPROTO_TCP,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
		    ip6h->ip6_dst, ip6h->ip6_src, ports) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
		    tconnp->conn_tcp->tcp_state >= TCPS_ESTABLISHED &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
		    (!zone_chk || tconnp->conn_zoneid == connp->conn_zoneid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
			ASSERT(tconnp != connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
			CONN_INC_REF(tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
			return (tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
 * Find an exact {src, dst, lport, fport} match for a bounced datagram.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
 * Returns with conn reference held. Caller must call CONN_DEC_REF.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
 * Only checks for connected entries i.e. no INADDR_ANY checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
ipcl_tcp_lookup_reversed_ipv4(ipha_t *ipha, tcph_t *tcph, int min_state)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	uint32_t ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
	uint16_t *pports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
	conn_t	*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
	pports = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
	bcopy(tcph->th_fport, &pports[0], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
	bcopy(tcph->th_lport, &pports[1], sizeof (uint16_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
	connfp = &ipcl_conn_fanout[IPCL_CONN_HASH(ipha->ipha_dst, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
	for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
	    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
		if (IPCL_CONN_MATCH(tconnp, IPPROTO_TCP,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
		    ipha->ipha_dst, ipha->ipha_src, ports) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
		    tconnp->conn_tcp->tcp_state >= min_state) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
			CONN_INC_REF(tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
			return (tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
 * Find an exact {src, dst, lport, fport} match for a bounced datagram.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
 * Returns with conn reference held. Caller must call CONN_DEC_REF.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
 * Only checks for connected entries i.e. no INADDR_ANY checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
 * Match on ifindex in addition to addresses.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
ipcl_tcp_lookup_reversed_ipv6(ip6_t *ip6h, tcpha_t *tcpha, int min_state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
    uint_t ifindex)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	tcp_t	*tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	uint32_t ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	uint16_t *pports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	connf_t	*connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
	conn_t	*tconnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
	pports = (uint16_t *)&ports;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	pports[0] = tcpha->tha_fport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	pports[1] = tcpha->tha_lport;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
	connfp = &ipcl_conn_fanout[IPCL_CONN_HASH_V6(ip6h->ip6_dst, ports)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
	mutex_enter(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
	for (tconnp = connfp->connf_head; tconnp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
	    tconnp = tconnp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
		tcp = tconnp->conn_tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
		if (IPCL_CONN_MATCH_V6(tconnp, IPPROTO_TCP,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
		    ip6h->ip6_dst, ip6h->ip6_src, ports) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
		    tcp->tcp_state >= min_state &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
		    (tcp->tcp_bound_if == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
		    tcp->tcp_bound_if == ifindex)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
			CONN_INC_REF(tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
			mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
			return (tconnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	mutex_exit(&connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
 * To find a TCP listening connection matching the incoming segment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
ipcl_lookup_listener_v4(uint16_t lport, ipaddr_t laddr, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
	connf_t		*bind_connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	conn_t		*connp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	tcp_t		*tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	 * Avoid false matches for packets sent to an IP destination of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	 * all zeros.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
	if (laddr == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
	bind_connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	mutex_enter(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	for (connp = bind_connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
		tcp = connp->conn_tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
		if (IPCL_BIND_MATCH(connp, IPPROTO_TCP, laddr, lport) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
		    connp->conn_zoneid == zoneid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
		    (tcp->tcp_listener == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
			mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
	mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
conn_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
ipcl_lookup_listener_v6(uint16_t lport, in6_addr_t *laddr, uint_t ifindex,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
    zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
	connf_t		*bind_connfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	conn_t		*connp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	tcp_t		*tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	 * Avoid false matches for packets sent to an IP destination of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	 * all zeros.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
	if (IN6_IS_ADDR_UNSPECIFIED(laddr))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	bind_connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(lport)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	mutex_enter(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	for (connp = bind_connfp->connf_head; connp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	    connp = connp->conn_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
		tcp = connp->conn_tcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
		if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP, *laddr, lport) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
		    connp->conn_zoneid == zoneid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
		    (tcp->tcp_bound_if == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
		    tcp->tcp_bound_if == ifindex) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
		    tcp->tcp_listener == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
			CONN_INC_REF(connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
			mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
			return (connp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
	mutex_exit(&bind_connfp->connf_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1870
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1871
 * ipcl_get_next_conn
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1872
 *	get the next entry in the conn global list
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1873
 *	and put a reference on the next_conn.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1874
 *	decrement the reference on the current conn.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1875
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1876
 * This is an iterator based walker function that also provides for
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1877
 * some selection by the caller. It walks through the conn_hash bucket
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1878
 * searching for the next valid connp in the list, and selects connections
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1879
 * that are neither closed nor condemned. It also REFHOLDS the conn
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1880
 * thus ensuring that the conn exists when the caller uses the conn.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1881
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1882
conn_t *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1883
ipcl_get_next_conn(connf_t *connfp, conn_t *connp, uint32_t conn_flags)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1884
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1885
	conn_t	*next_connp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1886
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1887
	if (connfp == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1888
		return (NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1889
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1890
	mutex_enter(&connfp->connf_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1891
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1892
	next_connp = (connp == NULL) ?
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1893
	    connfp->connf_head : connp->conn_g_next;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1894
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1895
	while (next_connp != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1896
		mutex_enter(&next_connp->conn_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1897
		if (!(next_connp->conn_flags & conn_flags) ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1898
		    (next_connp->conn_state_flags &
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1899
		    (CONN_CONDEMNED | CONN_INCIPIENT))) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1900
			/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1901
			 * This conn has been condemned or
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1902
			 * is closing, or the flags don't match
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1903
			 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1904
			mutex_exit(&next_connp->conn_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1905
			next_connp = next_connp->conn_g_next;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1906
			continue;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1907
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1908
		CONN_INC_REF_LOCKED(next_connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1909
		mutex_exit(&next_connp->conn_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1910
		break;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1911
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1912
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1913
	mutex_exit(&connfp->connf_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1914
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1915
	if (connp != NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1916
		CONN_DEC_REF(connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1917
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1918
	return (next_connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1919
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 409
diff changeset
  1920
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
#ifdef CONN_DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
 * Trace of the last NBUF refhold/refrele
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
conn_trace_ref(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
	int	last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	conn_trace_t	*ctb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	ASSERT(MUTEX_HELD(&connp->conn_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	last = connp->conn_trace_last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
	last++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	if (last == CONN_TRACE_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
		last = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	ctb = &connp->conn_trace_buf[last];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	ctb->ctb_depth = getpcstack(ctb->ctb_stack, IP_STACK_DEPTH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
	connp->conn_trace_last = last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
conn_untrace_ref(conn_t *connp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
	int	last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	conn_trace_t	*ctb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	ASSERT(MUTEX_HELD(&connp->conn_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	last = connp->conn_trace_last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	last++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	if (last == CONN_TRACE_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
		last = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
	ctb = &connp->conn_trace_buf[last];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	ctb->ctb_depth = getpcstack(ctb->ctb_stack, IP_STACK_DEPTH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	connp->conn_trace_last = last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
#endif