/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <inet/kstatcom.h>
#include <inet/ipclassifier.h>
#include "sctp_impl.h"
#include "sctp_addr.h"
static void sctp_clr_kstats2(sctp_kstat_t *);
static int sctp_snmp_state(sctp_t *);
static int
{
return (EIO);
if (rw == KSTAT_WRITE)
return (EACCES);
return (-1);
return (-1);
}
/*
* For all exclusive netstacks, the zone ID is always GLOBAL_ZONEID.
*/
if (stackid != GLOBAL_NETSTACKID)
else
/*
* Get the number of current associations and gather their
* individual set of statistics.
*/
if (sctp->sctp_condemned) {
continue;
}
sctp->sctp_refcnt++;
goto next_sctp;
/*
* Just bump the local sctp_mib. The number of
* existing associations is not kept in kernel.
*/
}
if (sctp->sctp_opkts) {
sctp->sctp_opkts);
sctp->sctp_opkts = 0;
}
if (sctp->sctp_obchunks) {
sctp->sctp_obchunks = 0;
}
if (sctp->sctp_odchunks) {
sctp->sctp_odchunks = 0;
}
if (sctp->sctp_oudchunks) {
sctp->sctp_oudchunks = 0;
}
if (sctp->sctp_rxtchunks) {
sctp->sctp_rxtchunks = 0;
}
if (sctp->sctp_ipkts) {
sctp->sctp_ipkts);
sctp->sctp_ipkts = 0;
}
if (sctp->sctp_ibchunks) {
sctp->sctp_ibchunks = 0;
}
if (sctp->sctp_idchunks) {
sctp->sctp_idchunks = 0;
}
if (sctp->sctp_iudchunks) {
sctp->sctp_iudchunks = 0;
}
if (sctp->sctp_fragdmsgs) {
sctp->sctp_fragdmsgs = 0;
}
if (sctp->sctp_reassmsgs) {
sctp->sctp_reassmsgs = 0;
}
}
/* Copy data from the SCTP MIB */
/* These are from global ndd params. */
/* Copy data from the local sctp_mib to the provided kstat. */
return (0);
}
void *
{
{ "sctpRtoAlgorithm", KSTAT_DATA_INT32, 0 },
{ "sctpRtoMin", KSTAT_DATA_UINT32, 0 },
{ "sctpRtoMax", KSTAT_DATA_UINT32, 0 },
{ "sctpRtoInitial", KSTAT_DATA_UINT32, 0 },
{ "sctpMaxAssocs", KSTAT_DATA_INT32, 0 },
{ "sctpValCookieLife", KSTAT_DATA_UINT32, 0 },
{ "sctpMaxInitRetr", KSTAT_DATA_UINT32, 0 },
{ "sctpCurrEstab", KSTAT_DATA_INT32, 0 },
{ "sctpActiveEstab", KSTAT_DATA_INT32, 0 },
{ "sctpPassiveEstab", KSTAT_DATA_INT32, 0 },
{ "sctpAborted", KSTAT_DATA_INT32, 0 },
{ "sctpShutdowns", KSTAT_DATA_INT32, 0 },
{ "sctpOutOfBlue", KSTAT_DATA_INT32, 0 },
{ "sctpChecksumError", KSTAT_DATA_INT32, 0 },
{ "sctpOutCtrlChunks", KSTAT_DATA_INT64, 0 },
{ "sctpOutOrderChunks", KSTAT_DATA_INT64, 0 },
{ "sctpOutUnorderChunks", KSTAT_DATA_INT64, 0 },
{ "sctpRetransChunks", KSTAT_DATA_INT64, 0 },
{ "sctpOutAck", KSTAT_DATA_INT32, 0 },
{ "sctpOutAckDelayed", KSTAT_DATA_INT32, 0 },
{ "sctpOutWinUpdate", KSTAT_DATA_INT32, 0 },
{ "sctpOutFastRetrans", KSTAT_DATA_INT32, 0 },
{ "sctpOutWinProbe", KSTAT_DATA_INT32, 0 },
{ "sctpInCtrlChunks", KSTAT_DATA_INT64, 0 },
{ "sctpInOrderChunks", KSTAT_DATA_INT64, 0 },
{ "sctpInUnorderChunks", KSTAT_DATA_INT64, 0 },
{ "sctpInAck", KSTAT_DATA_INT32, 0 },
{ "sctpInDupAck", KSTAT_DATA_INT32, 0 },
{ "sctpInAckUnsent", KSTAT_DATA_INT32, 0 },
{ "sctpFragUsrMsgs", KSTAT_DATA_INT64, 0 },
{ "sctpReasmUsrMsgs", KSTAT_DATA_INT64, 0 },
{ "sctpOutSCTPPkts", KSTAT_DATA_INT64, 0 },
{ "sctpInSCTPPkts", KSTAT_DATA_INT64, 0 },
{ "sctpInInvalidCookie", KSTAT_DATA_INT32, 0 },
{ "sctpTimRetrans", KSTAT_DATA_INT32, 0 },
{ "sctpTimRetransDrop", KSTAT_DATA_INT32, 0 },
{ "sctpTimHearBeatProbe", KSTAT_DATA_INT32, 0 },
{ "sctpTimHearBeatDrop", KSTAT_DATA_INT32, 0 },
{ "sctpListenDrop", KSTAT_DATA_INT32, 0 },
{ "sctpInClosed", KSTAT_DATA_INT32, 0 }
};
return (NULL);
/* These won't change. */
return (ksp);
}
/*
* To set all sctp_stat_t counters to 0.
*/
static void
{
}
/*
* To add counters from the per CPU sctp_kstat_counter_t to the stack
* sctp_kstat_t.
*/
static void
{
}
/*
* Sum up all per CPU tcp_stat_t kstat counters.
*/
static int
{
int i;
int cnt;
if (rw == KSTAT_WRITE)
return (EACCES);
return (-1);
return (-1);
}
/*
* sctps_sc_cnt may change in the middle of the loop. It is better
* to get its value first.
*/
for (i = 0; i < cnt; i++)
return (0);
}
/*
* The following kstats are for debugging purposes. They keep
* track of problems which should not happen normally. But in
* those cases which they do happen, these kstats would be handy
* for engineers to diagnose the problems. They are not intended
* to be consumed by customers.
*/
void *
{
{ "sctp_add_faddr", KSTAT_DATA_UINT64 },
{ "sctp_add_timer", KSTAT_DATA_UINT64 },
{ "sctp_conn_create", KSTAT_DATA_UINT64 },
{ "sctp_find_next_tq", KSTAT_DATA_UINT64 },
{ "sctp_fr_add_hdr", KSTAT_DATA_UINT64 },
{ "sctp_fr_not_found", KSTAT_DATA_UINT64 },
{ "sctp_output_failed", KSTAT_DATA_UINT64 },
{ "sctp_rexmit_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_init_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_cookie_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_cookie_ack_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_err_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_sack_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_shutdown_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_shutdown_ack_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_shutdown_comp_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_user_abort_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_asconf_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_asconf_ack_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_ftsn_failed", KSTAT_DATA_UINT64 },
{ "sctp_send_hb_failed", KSTAT_DATA_UINT64 },
{ "sctp_return_hb_failed", KSTAT_DATA_UINT64 },
{ "sctp_ss_rexmit_failed", KSTAT_DATA_UINT64 },
{ "sctp_cl_connect", KSTAT_DATA_UINT64 },
{ "sctp_cl_assoc_change", KSTAT_DATA_UINT64 },
{ "sctp_cl_check_addrs", KSTAT_DATA_UINT64 },
{ "sctp_reclaim_drop", KSTAT_DATA_UINT64 },
{ "sctp_listen_cnt_drop", KSTAT_DATA_UINT64 },
};
return (NULL);
return (ksp);
}
void
{
}
}
void
{
}
}
/*
* Return SNMP global stats in buffer in mpdata.
* Return associatiation table in mp_conn_data,
* local address table in mp_local_data, and
* remote address table in mp_rem_data.
*/
mblk_t *
{
int i;
int l;
int scanned = 0;
int idx;
/*
* Make copies of the original message.
* mpctl will hold SCTP counters,
* mp_conn_ctl will hold list of connections.
*/
return (NULL);
}
/* hostname address parameters are not supported in Solaris */
/* build table of connections -- need count in fixed part */
idx = 0;
if (sctp->sctp_condemned) {
continue;
}
sctp->sctp_refcnt++;
goto next_sctp;
/*
* Just bump the local sctp_mib. The number of
* existing associations is not kept in kernel.
*/
}
sctp->sctp_opkts = 0;
sctp->sctp_obchunks = 0;
sctp->sctp_odchunks = 0;
sctp->sctp_oudchunks = 0;
sctp->sctp_rxtchunks = 0;
sctp->sctp_ipkts = 0;
sctp->sctp_ibchunks = 0;
sctp->sctp_idchunks = 0;
sctp->sctp_iudchunks = 0;
sctp->sctp_fragdmsgs = 0;
sctp->sctp_reassmsgs = 0;
} else {
}
fp->sf_hb_interval);
} else {
sizeof (sce.sctpAssocRemPrimAddr));
sizeof (sce.sctpAssocLocPrimAddr));
}
/*
* Table for local addresses
*/
scanned = 0;
for (i = 0; i < SCTP_IPIF_HASH; i++) {
continue;
scanned++;
if (IN6_IS_ADDR_V4MAPPED(&addr)) {
} else {
}
(void) snmp_append_data2(mp_local_data,
&mp_local_tail, (char *)&scle,
sizeof (scle));
goto done;
}
}
done:
/*
* Table for remote addresses
*/
} else {
}
} else {
}
}
}
if (connp->conn_anon_mlp) {
}
switch (connp->conn_mac_mode) {
case CONN_MAC_DEFAULT:
break;
case CONN_MAC_AWARE:
break;
case CONN_MAC_IMPLICIT:
break;
}
}
/* A 0 here indicates that no primary process is known */
sce.sctpAssocPrimProcess = 0;
if (needattr)
}
/* table of connections... */
sizeof (struct T_optmgmt_ack)];
qreply(q, mp_conn_ctl);
/* assoc local address table */
sizeof (struct T_optmgmt_ack)];
qreply(q, mp_local_ctl);
/* assoc remote address table */
sizeof (struct T_optmgmt_ack)];
qreply(q, mp_rem_ctl);
/* table of MLP attributes */
sizeof (struct T_optmgmt_ack)];
else
qreply(q, mp_attr_ctl);
return (mp_ret);
}
/* Translate SCTP state to MIB2 SCTP state. */
static int
{
return (0);
switch (sctp->sctp_state) {
case SCTPS_IDLE:
case SCTPS_BOUND:
return (MIB2_SCTP_closed);
case SCTPS_LISTEN:
return (MIB2_SCTP_listen);
case SCTPS_COOKIE_WAIT:
return (MIB2_SCTP_cookieWait);
case SCTPS_COOKIE_ECHOED:
return (MIB2_SCTP_cookieEchoed);
case SCTPS_ESTABLISHED:
return (MIB2_SCTP_established);
case SCTPS_SHUTDOWN_PENDING:
return (MIB2_SCTP_shutdownPending);
case SCTPS_SHUTDOWN_SENT:
return (MIB2_SCTP_shutdownSent);
case SCTPS_SHUTDOWN_RECEIVED:
return (MIB2_SCTP_shutdownReceived);
case SCTPS_SHUTDOWN_ACK_SENT:
return (MIB2_SCTP_shutdownAckSent);
default:
return (0);
}
}
/*
* To sum up all MIB2 stats for a sctp_stack_t from all per CPU stats. The
* caller should initialize the target mib2_sctp_t properly as this function
* just adds up all the per CPU stats.
*/
static void
{
int i;
int cnt;
/* Static componets of mib2_sctp_t. */
/* fixed length structure for IPv4 and IPv6 counters */
sizeof (mib2_sctpConnLocalEntry_t));
sizeof (mib2_sctpConnRemoteEntry_t));
/*
* sctps_sc_cnt may change in the middle of the loop. It is better
* to get its value first.
*/
for (i = 0; i < cnt; i++)
}
static void
{
}