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 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2016, Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #ifndef _SYS_NETSTACK_H
  32 #define _SYS_NETSTACK_H
  33 
  34 #include <sys/kstat.h>
  35 #include <sys/cred.h>
  36 #include <sys/mutex.h>
  37 
  38 #ifdef  __cplusplus
  39 extern "C" {
  40 #endif
  41 
  42 /*
  43  * This allows various pieces in and around IP to have a separate instance
  44  * for each instance of IP. This is used to support zones that have an
  45  * exclusive stack.
  46  * Pieces of software far removed from IP (e.g., kernel software
  47  * sitting on top of TCP or UDP) probably should not use the netstack
  48  * support; if such software wants to support separate zones it
  49  * can do that using the zones framework (zone_key_create() etc)
  50  * whether there is a shared IP stack or and exclusive IP stack underneath.
  51  */
  52 
  53 /*
  54  * Each netstack has an identifier. We reuse the zoneid allocation for
  55  * this but have a separate typedef. Thus the shared stack (used by
  56  * the global zone and other shared stack zones) have a zero ID, and
  57  * the exclusive stacks have a netstackid that is the same as their zoneid.
  58  */
  59 typedef id_t    netstackid_t;
  60 
  61 #define GLOBAL_NETSTACKID       0
  62 
  63 /*
  64  * One for each module which uses netstack support.
  65  * Used in netstack_register().
  66  *
  67  * The order of these is important for some modules both for
  68  * the creation (which done in ascending order) and destruction (which is
  69  * done in in decending order).
  70  */
  71 #define NS_ALL          -1      /* Match all */
  72 #define NS_DLS          0
  73 #define NS_IPTUN        1
  74 #define NS_STR          2       /* autopush list etc */
  75 #define NS_HOOK         3
  76 #define NS_NETI         4
  77 #define NS_ARP          5
  78 #define NS_IP           6
  79 #define NS_ICMP         7
  80 #define NS_UDP          8
  81 #define NS_TCP          9
  82 #define NS_SCTP         10
  83 #define NS_RTS          11
  84 #define NS_IPSEC        12
  85 #define NS_KEYSOCK      13
  86 #define NS_SPDSOCK      14
  87 #define NS_IPSECAH      15
  88 #define NS_IPSECESP     16
  89 #define NS_IPNET        17
  90 #define NS_ILB          18
  91 #define NS_MAX          (NS_ILB+1)
  92 
  93 /*
  94  * State maintained for each module which tracks the state of
  95  * the create, shutdown and destroy callbacks.
  96  *
  97  * Keeps track of pending actions to avoid holding locks when
  98  * calling into the create/shutdown/destroy functions in the module.
  99  */
 100 #ifdef _KERNEL
 101 typedef struct {
 102         uint16_t        nms_flags;
 103         kcondvar_t      nms_cv;
 104 } nm_state_t;
 105 
 106 /*
 107  * nms_flags
 108  */
 109 #define NSS_CREATE_NEEDED       0x0001
 110 #define NSS_CREATE_INPROGRESS   0x0002
 111 #define NSS_CREATE_COMPLETED    0x0004
 112 #define NSS_SHUTDOWN_NEEDED     0x0010
 113 #define NSS_SHUTDOWN_INPROGRESS 0x0020
 114 #define NSS_SHUTDOWN_COMPLETED  0x0040
 115 #define NSS_DESTROY_NEEDED      0x0100
 116 #define NSS_DESTROY_INPROGRESS  0x0200
 117 #define NSS_DESTROY_COMPLETED   0x0400
 118 
 119 #define NSS_CREATE_ALL  \
 120         (NSS_CREATE_NEEDED|NSS_CREATE_INPROGRESS|NSS_CREATE_COMPLETED)
 121 #define NSS_SHUTDOWN_ALL        \
 122         (NSS_SHUTDOWN_NEEDED|NSS_SHUTDOWN_INPROGRESS|NSS_SHUTDOWN_COMPLETED)
 123 #define NSS_DESTROY_ALL \
 124         (NSS_DESTROY_NEEDED|NSS_DESTROY_INPROGRESS|NSS_DESTROY_COMPLETED)
 125 
 126 #define NSS_ALL_INPROGRESS      \
 127         (NSS_CREATE_INPROGRESS|NSS_SHUTDOWN_INPROGRESS|NSS_DESTROY_INPROGRESS)
 128 #else
 129 /* User-level compile like IP Filter needs a netstack_t. Dummy */
 130 typedef uint_t nm_state_t;
 131 #endif /* _KERNEL */
 132 
 133 /*
 134  * One for every netstack in the system.
 135  * We use a union so that the compilar and lint can provide type checking -
 136  * in principle we could have
 137  * #define      netstack_arp            netstack_modules[NS_ARP]
 138  * etc, but that would imply void * types hence no type checking by the
 139  * compiler.
 140  *
 141  * All the fields in netstack_t except netstack_next are protected by
 142  * netstack_lock. netstack_next is protected by netstack_g_lock.
 143  */
 144 struct netstack {
 145         union {
 146                 void    *nu_modules[NS_MAX];
 147                 struct {
 148                         struct dls_stack        *nu_dls;
 149                         struct iptun_stack      *nu_iptun;
 150                         struct str_stack        *nu_str;
 151                         struct hook_stack       *nu_hook;
 152                         struct neti_stack       *nu_neti;
 153                         struct arp_stack        *nu_arp;
 154                         struct ip_stack         *nu_ip;
 155                         struct icmp_stack       *nu_icmp;
 156                         struct udp_stack        *nu_udp;
 157                         struct tcp_stack        *nu_tcp;
 158                         struct sctp_stack       *nu_sctp;
 159                         struct rts_stack        *nu_rts;
 160                         struct ipsec_stack      *nu_ipsec;
 161                         struct keysock_stack    *nu_keysock;
 162                         struct spd_stack        *nu_spdsock;
 163                         struct ipsecah_stack    *nu_ipsecah;
 164                         struct ipsecesp_stack   *nu_ipsecesp;
 165                         struct ipnet_stack      *nu_ipnet;
 166                         struct ilb_stack        *nu_ilb;
 167                 } nu_s;
 168         } netstack_u;
 169 #define netstack_modules        netstack_u.nu_modules
 170 #define netstack_dls            netstack_u.nu_s.nu_dls
 171 #define netstack_iptun          netstack_u.nu_s.nu_iptun
 172 #define netstack_str            netstack_u.nu_s.nu_str
 173 #define netstack_hook           netstack_u.nu_s.nu_hook
 174 #define netstack_neti           netstack_u.nu_s.nu_neti
 175 #define netstack_arp            netstack_u.nu_s.nu_arp
 176 #define netstack_ip             netstack_u.nu_s.nu_ip
 177 #define netstack_icmp           netstack_u.nu_s.nu_icmp
 178 #define netstack_udp            netstack_u.nu_s.nu_udp
 179 #define netstack_tcp            netstack_u.nu_s.nu_tcp
 180 #define netstack_sctp           netstack_u.nu_s.nu_sctp
 181 #define netstack_rts            netstack_u.nu_s.nu_rts
 182 #define netstack_ipsec          netstack_u.nu_s.nu_ipsec
 183 #define netstack_keysock        netstack_u.nu_s.nu_keysock
 184 #define netstack_spdsock        netstack_u.nu_s.nu_spdsock
 185 #define netstack_ipsecah        netstack_u.nu_s.nu_ipsecah
 186 #define netstack_ipsecesp       netstack_u.nu_s.nu_ipsecesp
 187 #define netstack_ipnet          netstack_u.nu_s.nu_ipnet
 188 #define netstack_ilb            netstack_u.nu_s.nu_ilb
 189 
 190         nm_state_t      netstack_m_state[NS_MAX]; /* module state */
 191 
 192         kmutex_t        netstack_lock;
 193         struct netstack *netstack_next;
 194         netstackid_t    netstack_stackid;
 195         int             netstack_numzones;      /* Number of zones using this */
 196         int             netstack_refcnt;        /* Number of hold-rele */
 197         int             netstack_flags; /* See below */
 198 
 199 #ifdef _KERNEL
 200         /* Needed to ensure that we run the callback functions in order */
 201         kcondvar_t      netstack_cv;
 202 #endif
 203 };
 204 typedef struct netstack netstack_t;
 205 
 206 /* netstack_flags values */
 207 #define NSF_UNINIT              0x01            /* Not initialized */
 208 #define NSF_CLOSING             0x02            /* Going away */
 209 #define NSF_ZONE_CREATE         0x04            /* create callbacks inprog */
 210 #define NSF_ZONE_SHUTDOWN       0x08            /* shutdown callbacks */
 211 #define NSF_ZONE_DESTROY        0x10            /* destroy callbacks */
 212 
 213 #define NSF_ZONE_INPROGRESS     \
 214         (NSF_ZONE_CREATE|NSF_ZONE_SHUTDOWN|NSF_ZONE_DESTROY)
 215 
 216 /*
 217  * One for each of the NS_* values.
 218  */
 219 struct netstack_registry {
 220         int             nr_flags;       /* 0 if nothing registered */
 221         void            *(*nr_create)(netstackid_t, netstack_t *);
 222         void            (*nr_shutdown)(netstackid_t, void *);
 223         void            (*nr_destroy)(netstackid_t, void *);
 224 };
 225 
 226 /* nr_flags values */
 227 #define NRF_REGISTERED  0x01
 228 #define NRF_DYING       0x02    /* No new creates */
 229 
 230 /*
 231  * To support kstat_create_netstack() using kstat_add_zone we need
 232  * to track both
 233  *  - all zoneids that use the global/shared stack
 234  *  - all kstats that have been added for the shared stack
 235  */
 236 
 237 extern void netstack_init(void);
 238 extern void netstack_hold(netstack_t *);
 239 extern void netstack_rele(netstack_t *);
 240 extern netstack_t *netstack_find_by_cred(const cred_t *);
 241 extern netstack_t *netstack_find_by_stackid(netstackid_t);
 242 extern netstack_t *netstack_find_by_zoneid(zoneid_t);
 243 extern boolean_t netstack_inuse_by_stackid(netstackid_t stackid);
 244 
 245 extern zoneid_t netstackid_to_zoneid(netstackid_t);
 246 extern zoneid_t netstack_get_zoneid(netstack_t *);
 247 extern netstackid_t zoneid_to_netstackid(zoneid_t);
 248 
 249 extern netstack_t *netstack_get_current(void);
 250 
 251 /*
 252  * Register interest in changes to the set of netstacks.
 253  * The createfn and destroyfn are required, but the shutdownfn can be
 254  * NULL.
 255  * Note that due to the current zsd implementation, when the create
 256  * function is called the zone isn't fully present, thus functions
 257  * like zone_find_by_* will fail, hence the create function can not
 258  * use many zones kernel functions including zcmn_err().
 259  */
 260 extern void     netstack_register(int,
 261     void *(*)(netstackid_t, netstack_t *),
 262     void (*)(netstackid_t, void *),
 263     void (*)(netstackid_t, void *));
 264 extern void     netstack_unregister(int);
 265 extern kstat_t  *kstat_create_netstack(char *, int, char *, char *, uchar_t,
 266     uint_t, uchar_t, netstackid_t);
 267 extern void     kstat_delete_netstack(kstat_t *, netstackid_t);
 268 
 269 /*
 270  * Simple support for walking all the netstacks.
 271  * The caller of netstack_next() needs to call netstack_rele() when
 272  * done with a netstack.
 273  */
 274 typedef int     netstack_handle_t;
 275 
 276 extern void     netstack_next_init(netstack_handle_t *);
 277 extern void     netstack_next_fini(netstack_handle_t *);
 278 extern netstack_t       *netstack_next(netstack_handle_t *);
 279 
 280 #ifdef  __cplusplus
 281 }
 282 #endif
 283 
 284 
 285 #endif  /* _SYS_NETSTACK_H */