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