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_MAX          (NS_ILB+1)
  85 
  86 /*
  87  * State maintained for each module which tracks the state of
  88  * the create, shutdown and destroy callbacks.
  89  *
  90  * Keeps track of pending actions to avoid holding locks when
  91  * calling into the create/shutdown/destroy functions in the module.
  92  */
  93 #ifdef _KERNEL
  94 typedef struct {
  95         uint16_t        nms_flags;
  96         kcondvar_t      nms_cv;
  97 } nm_state_t;
  98 
  99 /*
 100  * nms_flags
 101  */
 102 #define NSS_CREATE_NEEDED       0x0001
 103 #define NSS_CREATE_INPROGRESS   0x0002
 104 #define NSS_CREATE_COMPLETED    0x0004
 105 #define NSS_SHUTDOWN_NEEDED     0x0010
 106 #define NSS_SHUTDOWN_INPROGRESS 0x0020
 107 #define NSS_SHUTDOWN_COMPLETED  0x0040
 108 #define NSS_DESTROY_NEEDED      0x0100
 109 #define NSS_DESTROY_INPROGRESS  0x0200
 110 #define NSS_DESTROY_COMPLETED   0x0400
 111 
 112 #define NSS_CREATE_ALL  \
 113         (NSS_CREATE_NEEDED|NSS_CREATE_INPROGRESS|NSS_CREATE_COMPLETED)
 114 #define NSS_SHUTDOWN_ALL        \
 115         (NSS_SHUTDOWN_NEEDED|NSS_SHUTDOWN_INPROGRESS|NSS_SHUTDOWN_COMPLETED)
 116 #define NSS_DESTROY_ALL \
 117         (NSS_DESTROY_NEEDED|NSS_DESTROY_INPROGRESS|NSS_DESTROY_COMPLETED)
 118 
 119 #define NSS_ALL_INPROGRESS      \
 120         (NSS_CREATE_INPROGRESS|NSS_SHUTDOWN_INPROGRESS|NSS_DESTROY_INPROGRESS)
 121 #else
 122 /* User-level compile like IP Filter needs a netstack_t. Dummy */
 123 typedef uint_t nm_state_t;
 124 #endif /* _KERNEL */
 125 
 126 /*
 127  * One for every netstack in the system.
 128  * We use a union so that the compilar and lint can provide type checking -
 129  * in principle we could have
 130  * #define      netstack_arp            netstack_modules[NS_ARP]
 131  * etc, but that would imply void * types hence no type checking by the
 132  * compiler.
 133  *
 134  * All the fields in netstack_t except netstack_next are protected by
 135  * netstack_lock. netstack_next is protected by netstack_g_lock.
 136  */
 137 struct netstack {
 138         union {
 139                 void    *nu_modules[NS_MAX];
 140                 struct {
 141                         struct dls_stack        *nu_dls;
 142                         struct iptun_stack      *nu_iptun;
 143                         struct str_stack        *nu_str;
 144                         struct hook_stack       *nu_hook;
 145                         struct neti_stack       *nu_neti;
 146                         struct arp_stack        *nu_arp;
 147                         struct ip_stack         *nu_ip;
 148                         struct icmp_stack       *nu_icmp;
 149                         struct udp_stack        *nu_udp;
 150                         struct tcp_stack        *nu_tcp;
 151                         struct sctp_stack       *nu_sctp;
 152                         struct rts_stack        *nu_rts;
 153                         struct ipsec_stack      *nu_ipsec;
 154                         struct keysock_stack    *nu_keysock;
 155                         struct spd_stack        *nu_spdsock;
 156                         struct ipsecah_stack    *nu_ipsecah;
 157                         struct ipsecesp_stack   *nu_ipsecesp;
 158                         struct ipnet_stack      *nu_ipnet;
 159                         struct ilb_stack        *nu_ilb;
 160                 } nu_s;
 161         } netstack_u;
 162 #define netstack_modules        netstack_u.nu_modules
 163 #define netstack_dls            netstack_u.nu_s.nu_dls
 164 #define netstack_iptun          netstack_u.nu_s.nu_iptun
 165 #define netstack_str            netstack_u.nu_s.nu_str
 166 #define netstack_hook           netstack_u.nu_s.nu_hook
 167 #define netstack_neti           netstack_u.nu_s.nu_neti
 168 #define netstack_arp            netstack_u.nu_s.nu_arp
 169 #define netstack_ip             netstack_u.nu_s.nu_ip
 170 #define netstack_icmp           netstack_u.nu_s.nu_icmp
 171 #define netstack_udp            netstack_u.nu_s.nu_udp
 172 #define netstack_tcp            netstack_u.nu_s.nu_tcp
 173 #define netstack_sctp           netstack_u.nu_s.nu_sctp
 174 #define netstack_rts            netstack_u.nu_s.nu_rts
 175 #define netstack_ipsec          netstack_u.nu_s.nu_ipsec
 176 #define netstack_keysock        netstack_u.nu_s.nu_keysock
 177 #define netstack_spdsock        netstack_u.nu_s.nu_spdsock
 178 #define netstack_ipsecah        netstack_u.nu_s.nu_ipsecah
 179 #define netstack_ipsecesp       netstack_u.nu_s.nu_ipsecesp
 180 #define netstack_ipnet          netstack_u.nu_s.nu_ipnet
 181 #define netstack_ilb            netstack_u.nu_s.nu_ilb
 182 
 183         nm_state_t      netstack_m_state[NS_MAX]; /* module state */
 184 
 185         kmutex_t        netstack_lock;
 186         struct netstack *netstack_next;
 187         netstackid_t    netstack_stackid;
 188         int             netstack_numzones;      /* Number of zones using this */
 189         int             netstack_refcnt;        /* Number of hold-rele */
 190         int             netstack_flags; /* See below */
 191 
 192 #ifdef _KERNEL
 193         /* Needed to ensure that we run the callback functions in order */
 194         kcondvar_t      netstack_cv;
 195 #endif
 196 };
 197 typedef struct netstack netstack_t;
 198 
 199 /* netstack_flags values */
 200 #define NSF_UNINIT              0x01            /* Not initialized */
 201 #define NSF_CLOSING             0x02            /* Going away */
 202 #define NSF_ZONE_CREATE         0x04            /* create callbacks inprog */
 203 #define NSF_ZONE_SHUTDOWN       0x08            /* shutdown callbacks */
 204 #define NSF_ZONE_DESTROY        0x10            /* destroy callbacks */
 205 
 206 #define NSF_ZONE_INPROGRESS     \
 207         (NSF_ZONE_CREATE|NSF_ZONE_SHUTDOWN|NSF_ZONE_DESTROY)
 208 
 209 /*
 210  * One for each of the NS_* values.
 211  */
 212 struct netstack_registry {
 213         int             nr_flags;       /* 0 if nothing registered */
 214         void            *(*nr_create)(netstackid_t, netstack_t *);
 215         void            (*nr_shutdown)(netstackid_t, void *);
 216         void            (*nr_destroy)(netstackid_t, void *);
 217 };
 218 
 219 /* nr_flags values */
 220 #define NRF_REGISTERED  0x01
 221 #define NRF_DYING       0x02    /* No new creates */
 222 
 223 /*
 224  * To support kstat_create_netstack() using kstat_add_zone we need
 225  * to track both
 226  *  - all zoneids that use the global/shared stack
 227  *  - all kstats that have been added for the shared stack
 228  */
 229 
 230 extern void netstack_init(void);
 231 extern void netstack_hold(netstack_t *);
 232 extern void netstack_rele(netstack_t *);
 233 extern netstack_t *netstack_find_by_cred(const cred_t *);
 234 extern netstack_t *netstack_find_by_stackid(netstackid_t);
 235 extern netstack_t *netstack_find_by_zoneid(zoneid_t);
 236 
 237 extern zoneid_t netstackid_to_zoneid(netstackid_t);
 238 extern zoneid_t netstack_get_zoneid(netstack_t *);
 239 extern netstackid_t zoneid_to_netstackid(zoneid_t);
 240 
 241 extern netstack_t *netstack_get_current(void);
 242 
 243 /*
 244  * Register interest in changes to the set of netstacks.
 245  * The createfn and destroyfn are required, but the shutdownfn can be
 246  * NULL.
 247  * Note that due to the current zsd implementation, when the create
 248  * function is called the zone isn't fully present, thus functions
 249  * like zone_find_by_* will fail, hence the create function can not
 250  * use many zones kernel functions including zcmn_err().
 251  */
 252 extern void     netstack_register(int,
 253     void *(*)(netstackid_t, netstack_t *),
 254     void (*)(netstackid_t, void *),
 255     void (*)(netstackid_t, void *));
 256 extern void     netstack_unregister(int);
 257 extern kstat_t  *kstat_create_netstack(char *, int, char *, char *, uchar_t,
 258     uint_t, uchar_t, netstackid_t);
 259 extern void     kstat_delete_netstack(kstat_t *, netstackid_t);
 260 
 261 /*
 262  * Simple support for walking all the netstacks.
 263  * The caller of netstack_next() needs to call netstack_rele() when
 264  * done with a netstack.
 265  */
 266 typedef int     netstack_handle_t;
 267 
 268 extern void     netstack_next_init(netstack_handle_t *);
 269 extern void     netstack_next_fini(netstack_handle_t *);
 270 extern netstack_t       *netstack_next(netstack_handle_t *);
 271 
 272 #ifdef  __cplusplus
 273 }
 274 #endif
 275 
 276 
 277 #endif  /* _SYS_NETSTACK_H */