1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <inet/common.h>
  28 #include "sctp_impl.h"
  29 
  30 /* Control whether SCTP can enter defensive mode when under memory pressure. */
  31 static boolean_t sctp_do_reclaim = B_TRUE;
  32 
  33 static void     sctp_reclaim_timer(void *);
  34 
  35 /* Diagnostic routine used to return a string associated with the sctp state. */
  36 char *
  37 sctp_display(sctp_t *sctp, char *sup_buf)
  38 {
  39         char    *buf;
  40         char    buf1[30];
  41         static char     priv_buf[INET6_ADDRSTRLEN * 2 + 80];
  42         char    *cp;
  43         conn_t  *connp;
  44 
  45         if (sctp == NULL)
  46                 return ("NULL_SCTP");
  47 
  48         connp = sctp->sctp_connp;
  49         buf = (sup_buf != NULL) ? sup_buf : priv_buf;
  50 
  51         switch (sctp->sctp_state) {
  52         case SCTPS_IDLE:
  53                 cp = "SCTP_IDLE";
  54                 break;
  55         case SCTPS_BOUND:
  56                 cp = "SCTP_BOUND";
  57                 break;
  58         case SCTPS_LISTEN:
  59                 cp = "SCTP_LISTEN";
  60                 break;
  61         case SCTPS_COOKIE_WAIT:
  62                 cp = "SCTP_COOKIE_WAIT";
  63                 break;
  64         case SCTPS_COOKIE_ECHOED:
  65                 cp = "SCTP_COOKIE_ECHOED";
  66                 break;
  67         case SCTPS_ESTABLISHED:
  68                 cp = "SCTP_ESTABLISHED";
  69                 break;
  70         case SCTPS_SHUTDOWN_PENDING:
  71                 cp = "SCTP_SHUTDOWN_PENDING";
  72                 break;
  73         case SCTPS_SHUTDOWN_SENT:
  74                 cp = "SCTPS_SHUTDOWN_SENT";
  75                 break;
  76         case SCTPS_SHUTDOWN_RECEIVED:
  77                 cp = "SCTPS_SHUTDOWN_RECEIVED";
  78                 break;
  79         case SCTPS_SHUTDOWN_ACK_SENT:
  80                 cp = "SCTPS_SHUTDOWN_ACK_SENT";
  81                 break;
  82         default:
  83                 (void) mi_sprintf(buf1, "SCTPUnkState(%d)", sctp->sctp_state);
  84                 cp = buf1;
  85                 break;
  86         }
  87         (void) mi_sprintf(buf, "[%u, %u] %s",
  88             ntohs(connp->conn_lport), ntohs(connp->conn_fport), cp);
  89 
  90         return (buf);
  91 }
  92 
  93 void
  94 sctp_display_all(sctp_stack_t *sctps)
  95 {
  96         sctp_t *sctp_walker;
  97 
  98         mutex_enter(&sctps->sctps_g_lock);
  99         for (sctp_walker = list_head(&sctps->sctps_g_list);
 100             sctp_walker != NULL;
 101             sctp_walker = (sctp_t *)list_next(&sctps->sctps_g_list,
 102             sctp_walker)) {
 103                 (void) sctp_display(sctp_walker, NULL);
 104         }
 105         mutex_exit(&sctps->sctps_g_lock);
 106 }
 107 
 108 /*
 109  * Given a sctp_stack_t and a port (in host byte order), find a listener
 110  * configuration for that port and return the ratio.
 111  */
 112 uint32_t
 113 sctp_find_listener_conf(sctp_stack_t *sctps, in_port_t port)
 114 {
 115         sctp_listener_t *sl;
 116         uint32_t ratio = 0;
 117 
 118         mutex_enter(&sctps->sctps_listener_conf_lock);
 119         for (sl = list_head(&sctps->sctps_listener_conf); sl != NULL;
 120             sl = list_next(&sctps->sctps_listener_conf, sl)) {
 121                 if (sl->sl_port == port) {
 122                         ratio = sl->sl_ratio;
 123                         break;
 124                 }
 125         }
 126         mutex_exit(&sctps->sctps_listener_conf_lock);
 127         return (ratio);
 128 }
 129 
 130 /*
 131  * To remove all listener limit configuration in a sctp_stack_t.
 132  */
 133 void
 134 sctp_listener_conf_cleanup(sctp_stack_t *sctps)
 135 {
 136         sctp_listener_t *sl;
 137 
 138         mutex_enter(&sctps->sctps_listener_conf_lock);
 139         while ((sl = list_head(&sctps->sctps_listener_conf)) != NULL) {
 140                 list_remove(&sctps->sctps_listener_conf, sl);
 141                 kmem_free(sl, sizeof (sctp_listener_t));
 142         }
 143         mutex_destroy(&sctps->sctps_listener_conf_lock);
 144         list_destroy(&sctps->sctps_listener_conf);
 145 }
 146 
 147 
 148 /*
 149  * Timeout function to reset the SCTP stack variable sctps_reclaim to false.
 150  */
 151 static void
 152 sctp_reclaim_timer(void *arg)
 153 {
 154         sctp_stack_t *sctps = (sctp_stack_t *)arg;
 155         int64_t tot_assoc = 0;
 156         int i;
 157         extern pgcnt_t lotsfree, needfree;
 158 
 159         for (i = 0; i < sctps->sctps_sc_cnt; i++)
 160                 tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
 161 
 162         /*
 163          * This happens only when a stack is going away.  sctps_reclaim_tid
 164          * should not be reset to 0 when returning in this case.
 165          */
 166         mutex_enter(&sctps->sctps_reclaim_lock);
 167         if (!sctps->sctps_reclaim) {
 168                 mutex_exit(&sctps->sctps_reclaim_lock);
 169                 return;
 170         }
 171 
 172         if ((freemem >= lotsfree + needfree) || tot_assoc < maxusers) {
 173                 sctps->sctps_reclaim = B_FALSE;
 174                 sctps->sctps_reclaim_tid = 0;
 175         } else {
 176                 /* Stay in defensive mode and restart the timer */
 177                 sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
 178                     sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
 179         }
 180         mutex_exit(&sctps->sctps_reclaim_lock);
 181 }
 182 
 183 /*
 184  * Kmem reclaim call back function.  When the system is under memory
 185  * pressure, we set the SCTP stack variable sctps_reclaim to true.  This
 186  * variable is reset to false after sctps_reclaim_period msecs.  During this
 187  * period, SCTP will be more aggressive in aborting connections not making
 188  * progress, meaning retransmitting for shorter time (sctp_pa_early_abort/
 189  * sctp_pp_early_abort number of strikes).
 190  */
 191 /* ARGSUSED */
 192 void
 193 sctp_conn_reclaim(void *arg)
 194 {
 195         netstack_handle_t nh;
 196         netstack_t *ns;
 197         sctp_stack_t *sctps;
 198         extern pgcnt_t lotsfree, needfree;
 199 
 200         if (!sctp_do_reclaim)
 201                 return;
 202 
 203         /*
 204          * The reclaim function may be called even when the system is not
 205          * really under memory pressure.
 206          */
 207         if (freemem >= lotsfree + needfree)
 208                 return;
 209 
 210         netstack_next_init(&nh);
 211         while ((ns = netstack_next(&nh)) != NULL) {
 212                 int i;
 213                 int64_t tot_assoc = 0;
 214 
 215                 /*
 216                  * During boot time, the first netstack_t is created and
 217                  * initialized before SCTP has registered with the netstack
 218                  * framework.  If this reclaim function is called before SCTP
 219                  * has finished its initialization, netstack_next() will
 220                  * return the first netstack_t (since its netstack_flags is
 221                  * not NSF_UNINIT).  And its netstack_sctp will be NULL.  We
 222                  * need to catch it.
 223                  *
 224                  * All subsequent netstack_t creation will not have this
 225                  * problem since the initialization is not finished until SCTP
 226                  * has finished its own sctp_stack_t initialization.  Hence
 227                  * netstack_next() will not return one with NULL netstack_sctp.
 228                  */
 229                 if ((sctps = ns->netstack_sctp) == NULL) {
 230                         netstack_rele(ns);
 231                         continue;
 232                 }
 233 
 234                 /*
 235                  * Even if the system is under memory pressure, the reason may
 236                  * not be because of SCTP activity.  Check the number of
 237                  * associations in each stack.  If the number exceeds the
 238                  * threshold (maxusers), turn on defensive mode.
 239                  */
 240                 for (i = 0; i < sctps->sctps_sc_cnt; i++)
 241                         tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
 242                 if (tot_assoc < maxusers) {
 243                         netstack_rele(ns);
 244                         continue;
 245                 }
 246 
 247                 mutex_enter(&sctps->sctps_reclaim_lock);
 248                 if (!sctps->sctps_reclaim) {
 249                         sctps->sctps_reclaim = B_TRUE;
 250                         sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
 251                             sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
 252                         SCTP_KSTAT(sctps, sctp_reclaim_cnt);
 253                 }
 254                 mutex_exit(&sctps->sctps_reclaim_lock);
 255                 netstack_rele(ns);
 256         }
 257         netstack_next_fini(&nh);
 258 }
 259 
 260 /*
 261  * When a CPU is added, we need to allocate the per CPU stats struct.
 262  */
 263 void
 264 sctp_stack_cpu_add(sctp_stack_t *sctps, processorid_t cpu_seqid)
 265 {
 266         int i;
 267 
 268         if (cpu_seqid < sctps->sctps_sc_cnt)
 269                 return;
 270         for (i = sctps->sctps_sc_cnt; i <= cpu_seqid; i++) {
 271                 ASSERT(sctps->sctps_sc[i] == NULL);
 272                 sctps->sctps_sc[i] = kmem_zalloc(sizeof (sctp_stats_cpu_t),
 273                     KM_SLEEP);
 274         }
 275         membar_producer();
 276         sctps->sctps_sc_cnt = cpu_seqid + 1;
 277 }