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  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 /* Copyright (c) 1990 Mentat Inc. */
  25 
  26 #ifndef _INET_IP_IRE_H
  27 #define _INET_IP_IRE_H
  28 
  29 #ifdef  __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 #define IPV6_LL_PREFIXLEN       10      /* Number of bits in link-local pref */
  34 
  35 #define IP_CACHE_TABLE_SIZE     256
  36 #define IP_MASK_TABLE_SIZE      (IP_ABITS + 1)          /* 33 ptrs */
  37 
  38 #define IP6_FTABLE_HASH_SIZE    32      /* size of each hash table in ptrs */
  39 #define IP6_CACHE_TABLE_SIZE    256
  40 #define IP6_MASK_TABLE_SIZE     (IPV6_ABITS + 1)        /* 129 ptrs */
  41 
  42 /*
  43  * We use the common modulo hash function.  In ip_ire_init(), we make
  44  * sure that the cache table size is always a power of 2.  That's why
  45  * we can use & instead of %.  Also note that we try hard to make sure
  46  * the lower bits of an address capture most info from the whole address.
  47  * The reason being that since our hash table is probably a lot smaller
  48  * than 2^32 buckets so the lower bits are the most important.
  49  */
  50 #define IRE_ADDR_HASH(addr, table_size) \
  51         (((addr) ^ ((addr) >> 8) ^ ((addr) >> 16) ^ ((addr) >> 24)) &     \
  52         ((table_size) - 1))
  53 
  54 /*
  55  * To make a byte-order neutral hash for IPv6, just take all the
  56  * bytes in the bottom 32 bits into account.
  57  */
  58 #define IRE_ADDR_HASH_V6(addr, table_size)                              \
  59         IRE_ADDR_HASH((addr).s6_addr32[3], table_size)
  60 
  61 /*
  62  * This assumes that the ftable size is a power of 2.
  63  * We include some high-order bytes to avoid all IRE_LOCALs in the same
  64  * bucket for performance reasons.
  65  */
  66 #define IRE_ADDR_MASK_HASH_V6(addr, mask, table_size)                   \
  67         ((((addr).s6_addr8[0] & (mask).s6_addr8[0]) ^                       \
  68         ((addr).s6_addr8[1] & (mask).s6_addr8[1]) ^                         \
  69         ((addr).s6_addr8[6] & (mask).s6_addr8[6]) ^                         \
  70         ((addr).s6_addr8[7] & (mask).s6_addr8[7]) ^                         \
  71         ((addr).s6_addr8[8] & (mask).s6_addr8[8]) ^                         \
  72         ((addr).s6_addr8[9] & (mask).s6_addr8[9]) ^                 \
  73         ((addr).s6_addr8[10] & (mask).s6_addr8[10]) ^                       \
  74         ((addr).s6_addr8[13] & (mask).s6_addr8[13]) ^                       \
  75         ((addr).s6_addr8[14] & (mask).s6_addr8[14]) ^                       \
  76         ((addr).s6_addr8[15] & (mask).s6_addr8[15])) & ((table_size) - 1))
  77 
  78 #define IRE_HIDDEN_TYPE(ire_type) ((ire_type) &                     \
  79         (IRE_HOST | IRE_PREFIX | IRE_DEFAULT | IRE_IF_ALL | IRE_BROADCAST))
  80 
  81 /*
  82  * match parameter definitions for IRE lookup routines.
  83  */
  84 #define MATCH_IRE_DSTONLY       0x0000  /* Match just the address */
  85 #define MATCH_IRE_TYPE          0x0001  /* Match IRE type */
  86 #define MATCH_IRE_MASK          0x0002  /* Match IRE mask */
  87 #define MATCH_IRE_SHORTERMASK   0x0004  /* A mask shorter than the argument */
  88 #define MATCH_IRE_GW            0x0008  /* Match IRE gateway */
  89 #define MATCH_IRE_ILL           0x0010  /* Match IRE on the ill */
  90 #define MATCH_IRE_ZONEONLY      0x0020  /* Match IREs in specified zone, ie */
  91                                         /* don't match IRE_LOCALs from other */
  92                                         /* zones or shared IREs */
  93 #define MATCH_IRE_SECATTR       0x0040  /* Match gateway security attributes */
  94 #define MATCH_IRE_TESTHIDDEN    0x0080  /* Match ire_testhidden IREs */
  95 #define MATCH_IRE_SRC_ILL       0x0100  /* ire_ill uses a src address on ill */
  96 #define MATCH_IRE_DIRECT        0x0200  /* Don't match indirect routes */
  97 
  98 #define MAX_IRE_RECURSION       4       /* Max IREs in ire_route_recursive */
  99 
 100 
 101 /*
 102  * We use atomics so that we get an accurate accounting on the ires.
 103  * Otherwise we can't determine leaks correctly.
 104  */
 105 #define BUMP_IRE_STATS(ire_stats, x) atomic_add_64(&(ire_stats).x, 1)
 106 
 107 #ifdef _KERNEL
 108 struct ts_label_s;
 109 struct nce_s;
 110 /*
 111  * structure for passing args between ire_ftable_lookup and ire_find_best_route
 112  */
 113 typedef struct ire_ftable_args_s {
 114         in6_addr_t              ift_addr_v6;
 115         in6_addr_t              ift_mask_v6;
 116         in6_addr_t              ift_gateway_v6;
 117 #define ift_addr                V4_PART_OF_V6(ift_addr_v6)
 118 #define ift_mask                V4_PART_OF_V6(ift_mask_v6)
 119 #define ift_gateway             V4_PART_OF_V6(ift_gateway_v6)
 120         int                     ift_type;
 121         const ill_t             *ift_ill;
 122         zoneid_t                ift_zoneid;
 123         const ts_label_t        *ift_tsl;
 124         int                     ift_flags;
 125         ire_t                   *ift_best_ire;
 126 } ire_ftable_args_t;
 127 
 128 extern  ipaddr_t        ip_plen_to_mask(uint_t);
 129 extern  in6_addr_t      *ip_plen_to_mask_v6(uint_t, in6_addr_t *);
 130 
 131 extern  int     ip_ire_advise(queue_t *, mblk_t *, cred_t *);
 132 extern  int     ip_ire_delete(queue_t *, mblk_t *, cred_t *);
 133 extern  void    ip_ire_reclaim(void *);
 134 
 135 extern  int     ip_mask_to_plen(ipaddr_t);
 136 extern  int     ip_mask_to_plen_v6(const in6_addr_t *);
 137 
 138 extern  ire_t   *ire_add(ire_t *);
 139 extern  ire_t   *ire_add_v6(ire_t *);
 140 extern  int     ire_atomic_start(irb_t *irb_ptr, ire_t *ire);
 141 extern  void    ire_atomic_end(irb_t *irb_ptr, ire_t *ire);
 142 
 143 extern  ire_t   *ire_create(uchar_t *, uchar_t *, uchar_t *,
 144     ushort_t, ill_t *, zoneid_t, uint_t, tsol_gc_t *, ip_stack_t *);
 145 
 146 extern  ire_t   **ire_create_bcast(ill_t *, ipaddr_t, zoneid_t, ire_t **);
 147 extern  ire_t   *ire_create_if_clone(ire_t *, const in6_addr_t *, uint_t *);
 148 extern  ire_t   *ire_lookup_bcast(ill_t *, ipaddr_t, zoneid_t);
 149 extern  int     ire_init_v4(ire_t *, uchar_t *, uchar_t *, uchar_t *,
 150     ushort_t, ill_t *, zoneid_t, uint_t, tsol_gc_t *, ip_stack_t *);
 151 extern  int     ire_init_v6(ire_t *, const in6_addr_t *, const in6_addr_t *,
 152     const in6_addr_t *, ushort_t, ill_t *, zoneid_t, uint_t, tsol_gc_t *,
 153     ip_stack_t *);
 154 
 155 extern  int     ire_init_common(ire_t *, ushort_t, ill_t *, zoneid_t, uint_t,
 156     uchar_t, tsol_gc_t *, ip_stack_t *);
 157 
 158 extern  ire_t   *ire_create_v6(const in6_addr_t *, const in6_addr_t *,
 159     const in6_addr_t *, ushort_t, ill_t *, zoneid_t, uint_t,
 160     tsol_gc_t *, ip_stack_t *);
 161 
 162 extern  void    ire_delete(ire_t *);
 163 extern  void    ire_delete_v6(ire_t *);
 164 
 165 extern  boolean_t ire_dep_build(ire_t *[], uint_t [], uint_t);
 166 extern  void    ire_dep_delete_if_clone(ire_t *);
 167 extern  void    ire_dep_incr_generation(ire_t *);
 168 extern  void    ire_dep_remove(ire_t *);
 169 extern  void    ire_dep_unbuild(ire_t *[], uint_t);
 170 extern  uint_t  ire_dep_validate_generations(ire_t *);
 171 extern  void    ire_dep_invalidate_generations(ire_t *);
 172 extern  boolean_t ire_determine_nce_capable(ire_t *);
 173 
 174 extern  void    ire_flush_cache_v4(ire_t *, int);
 175 extern  void    ire_flush_cache_v6(ire_t *, int);
 176 
 177 extern  ire_t   *ire_ftable_lookup_v4(ipaddr_t, ipaddr_t, ipaddr_t, int,
 178     const ill_t *, zoneid_t, const struct ts_label_s *, int, uint32_t,
 179     ip_stack_t *, uint_t *);
 180 extern  ire_t   *ire_ftable_lookup_v6(const in6_addr_t *, const in6_addr_t *,
 181     const in6_addr_t *, int, const ill_t *, zoneid_t,
 182     const struct ts_label_s *, int, uint32_t, ip_stack_t *, uint_t *);
 183 
 184 extern  ire_t   *ire_ftable_lookup_simple_v4(ipaddr_t, uint32_t, ip_stack_t *,
 185     uint_t *);
 186 extern  ire_t   *ire_ftable_lookup_simple_v6(const in6_addr_t *, uint32_t,
 187     ip_stack_t *, uint_t *);
 188 
 189 extern boolean_t ire_gateway_ok_zone_v4(ipaddr_t, zoneid_t, ill_t *,
 190     const ts_label_t *, ip_stack_t *, boolean_t);
 191 extern boolean_t ire_gateway_ok_zone_v6(const in6_addr_t *, zoneid_t, ill_t *,
 192     const ts_label_t *, ip_stack_t *, boolean_t);
 193 
 194 extern ire_t    *ire_alt_local(ire_t *, zoneid_t, const ts_label_t *,
 195     const ill_t *, uint_t *);
 196 
 197 extern  ill_t   *ire_lookup_multi_ill_v4(ipaddr_t, zoneid_t, ip_stack_t *,
 198     boolean_t *, ipaddr_t *);
 199 extern  ill_t   *ire_lookup_multi_ill_v6(const in6_addr_t *, zoneid_t,
 200     ip_stack_t *, boolean_t *, in6_addr_t *);
 201 
 202 extern  ire_t   *ire_nexthop(ire_t *);
 203 extern  ill_t   *ire_nexthop_ill(ire_t *);
 204 extern  ill_t   *ire_nce_ill(ire_t *);
 205 
 206 extern  ire_t   *ire_reject(ip_stack_t *, boolean_t);
 207 extern  ire_t   *ire_blackhole(ip_stack_t *, boolean_t);
 208 extern  ire_t   *ire_multicast(ill_t *);
 209 
 210 /* The different ire_recvfn functions */
 211 extern void     ire_recv_forward_v4(ire_t *, mblk_t *, void *,
 212     ip_recv_attr_t *);
 213 extern void     ire_recv_noroute_v4(ire_t *, mblk_t *, void *,
 214     ip_recv_attr_t *);
 215 extern void     ire_recv_broadcast_v4(ire_t *, mblk_t *, void *,
 216     ip_recv_attr_t *);
 217 extern void     ire_recv_multicast_v4(ire_t *, mblk_t *, void *,
 218     ip_recv_attr_t *);
 219 extern void     ire_recv_multirt_v4(ire_t *, mblk_t *, void *,
 220     ip_recv_attr_t *);
 221 extern void     ire_recv_loopback_v4(ire_t *, mblk_t *, void *,
 222     ip_recv_attr_t *);
 223 extern void     ire_recv_local_v4(ire_t *, mblk_t *, void *,
 224     ip_recv_attr_t *);
 225 extern void     ire_recv_noaccept_v4(ire_t *, mblk_t *, void *,
 226     ip_recv_attr_t *);
 227 
 228 extern void     ire_recv_forward_v6(ire_t *, mblk_t *, void *,
 229     ip_recv_attr_t *);
 230 extern void     ire_recv_noroute_v6(ire_t *, mblk_t *, void *,
 231     ip_recv_attr_t *);
 232 extern void     ire_recv_multicast_v6(ire_t *, mblk_t *, void *,
 233     ip_recv_attr_t *);
 234 extern void     ire_recv_multirt_v6(ire_t *, mblk_t *, void *,
 235     ip_recv_attr_t *);
 236 extern void     ire_recv_loopback_v6(ire_t *, mblk_t *, void *,
 237     ip_recv_attr_t *);
 238 extern void     ire_recv_local_v6(ire_t *, mblk_t *, void *, ip_recv_attr_t *);
 239 extern void     ire_recv_noaccept_v6(ire_t *, mblk_t *, void *,
 240     ip_recv_attr_t *);
 241 
 242 extern  void    irb_refhold(irb_t *);
 243 extern  void    irb_refhold_locked(irb_t *);
 244 extern  void    irb_refrele(irb_t *);
 245 extern  void    irb_increment_generation(irb_t *);
 246 
 247 extern  void    ire_refhold(ire_t *);
 248 extern  void    ire_refhold_notr(ire_t *);
 249 extern  void    ire_refhold_locked(ire_t *);
 250 extern  void    ire_refrele(ire_t *);
 251 extern  void    ire_refrele_notr(ire_t *);
 252 extern  void    ire_make_condemned(ire_t *);
 253 extern  boolean_t ire_no_good(ire_t *);
 254 extern  nce_t   *ire_handle_condemned_nce(nce_t *, ire_t *, ipha_t *, ip6_t *,
 255     boolean_t);
 256 
 257 extern ire_t    *ire_round_robin(irb_t *, ire_ftable_args_t *, uint_t,
 258     ire_t *, ip_stack_t *);
 259 
 260 extern ire_t    *ire_route_recursive_v4(ipaddr_t, uint_t, const ill_t *,
 261     zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t, ip_stack_t *,
 262     ipaddr_t *, tsol_ire_gw_secattr_t **, uint_t *);
 263 extern ire_t    *ire_route_recursive_v6(const in6_addr_t *, uint_t,
 264     const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t,
 265     ip_stack_t *, in6_addr_t *, tsol_ire_gw_secattr_t **, uint_t *);
 266 extern ire_t    *ire_route_recursive_dstonly_v4(ipaddr_t, uint_t,
 267     uint32_t, ip_stack_t *);
 268 extern ire_t    *ire_route_recursive_dstonly_v6(const in6_addr_t *, uint_t,
 269     uint32_t, ip_stack_t *);
 270 extern ire_t    *ire_route_recursive_impl_v4(ire_t *ire, ipaddr_t, uint_t,
 271     const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t,
 272     ip_stack_t *, ipaddr_t *, tsol_ire_gw_secattr_t **, uint_t *);
 273 extern ire_t    *ire_route_recursive_impl_v6(ire_t *ire, const in6_addr_t *,
 274     uint_t, const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t,
 275     uint32_t, ip_stack_t *, in6_addr_t *, tsol_ire_gw_secattr_t **, uint_t *);
 276 
 277 /* The different ire_sendfn functions */
 278 extern int      ire_send_local_v4(ire_t *, mblk_t *, void *,
 279     ip_xmit_attr_t *, uint32_t *);
 280 extern int      ire_send_multirt_v4(ire_t *, mblk_t *, void *,
 281     ip_xmit_attr_t *, uint32_t *);
 282 extern int      ire_send_noroute_v4(ire_t *, mblk_t *, void *,
 283     ip_xmit_attr_t *, uint32_t *);
 284 extern int      ire_send_multicast_v4(ire_t *, mblk_t *, void *,
 285     ip_xmit_attr_t *, uint32_t *);
 286 extern int      ire_send_broadcast_v4(ire_t *, mblk_t *, void *,
 287     ip_xmit_attr_t *, uint32_t *);
 288 extern int      ire_send_wire_v4(ire_t *, mblk_t *, void *,
 289     ip_xmit_attr_t *, uint32_t *);
 290 extern int      ire_send_local_v6(ire_t *, mblk_t *, void *,
 291     ip_xmit_attr_t *, uint32_t *);
 292 extern int      ire_send_multirt_v6(ire_t *, mblk_t *, void *,
 293     ip_xmit_attr_t *, uint32_t *);
 294 extern int      ire_send_noroute_v6(ire_t *, mblk_t *, void *,
 295     ip_xmit_attr_t *, uint32_t *);
 296 extern int      ire_send_multicast_v6(ire_t *, mblk_t *, void *,
 297     ip_xmit_attr_t *, uint32_t *);
 298 extern int      ire_send_wire_v6(ire_t *, mblk_t *, void *,
 299     ip_xmit_attr_t *, uint32_t *);
 300 
 301 extern nce_t    *ire_to_nce_pkt(ire_t *, mblk_t *);
 302 extern nce_t    *ire_to_nce(ire_t *, ipaddr_t, const in6_addr_t *);
 303 
 304 /* Different ire_postfragfn functions */
 305 extern int      ip_xmit(mblk_t *, struct nce_s *,
 306     iaflags_t, uint_t, uint32_t, zoneid_t, zoneid_t, uintptr_t *);
 307 extern int      ip_postfrag_loopcheck(mblk_t *, struct nce_s *,
 308     iaflags_t, uint_t, uint32_t, zoneid_t, zoneid_t, uintptr_t *);
 309 extern int      ip_postfrag_multirt_v4(mblk_t *, struct nce_s *,
 310     iaflags_t, uint_t, uint32_t, zoneid_t, zoneid_t, uintptr_t *);
 311 extern int      ip_postfrag_multirt_v6(mblk_t *, struct nce_s *,
 312     iaflags_t, uint_t, uint32_t, zoneid_t, zoneid_t, uintptr_t *);
 313 
 314 extern void     ip_postfrag_loopback(mblk_t *, struct nce_s *,
 315     iaflags_t, uint_t, zoneid_t);
 316 extern int      ire_revalidate_nce(ire_t *);
 317 
 318 extern ire_t    *ip_select_route_pkt(mblk_t *, ip_xmit_attr_t *,
 319     uint_t *, int *, boolean_t *);
 320 extern ire_t    *ip_select_route(const in6_addr_t *, const in6_addr_t,
 321     ip_xmit_attr_t *, uint_t *, in6_addr_t *, int *, boolean_t *);
 322 extern ire_t    *ip_select_route_v4(ipaddr_t, ipaddr_t, ip_xmit_attr_t *,
 323     uint_t *, ipaddr_t *, int *, boolean_t *);
 324 extern ire_t    *ip_select_route_v6(const in6_addr_t *, const in6_addr_t,
 325     ip_xmit_attr_t *, uint_t *, in6_addr_t *, int *, boolean_t *);
 326 
 327 extern  void    ire_walk(pfv_t, void *, ip_stack_t *);
 328 extern  void    ire_walk_ill(uint_t, uint_t, pfv_t, void *, ill_t *);
 329 extern  void    ire_walk_v4(pfv_t, void *, zoneid_t, ip_stack_t *);
 330 extern  void    ire_walk_ill_tables(uint_t match_flags, uint_t ire_type,
 331     pfv_t func, void *arg, size_t ftbl_sz, size_t htbl_sz,
 332     irb_t **ipftbl, ill_t *ill,
 333     zoneid_t zoneid, ip_stack_t *);
 334 extern  void    ire_walk_v6(pfv_t, void *, zoneid_t, ip_stack_t *);
 335 
 336 extern boolean_t        ire_match_args(ire_t *, ipaddr_t, ipaddr_t, ipaddr_t,
 337     int, const ill_t *, zoneid_t, const struct ts_label_s *, int);
 338 extern boolean_t        ire_match_args_v6(ire_t *, const in6_addr_t *,
 339     const in6_addr_t *, const in6_addr_t *, int, const ill_t *, zoneid_t,
 340     const ts_label_t *, int);
 341 
 342 extern  struct nce_s    *arp_nce_init(ill_t *, in_addr_t, int);
 343 extern  boolean_t       ire_walk_ill_match(uint_t, uint_t, ire_t *, ill_t *,
 344     zoneid_t, ip_stack_t *);
 345 extern  void ire_increment_generation(ire_t *);
 346 extern  void ire_increment_multicast_generation(ip_stack_t *, boolean_t);
 347 extern  void ire_rebind(ire_t *);
 348 extern  boolean_t ire_clone_verify(ire_t *);
 349 
 350 #endif /* _KERNEL */
 351 
 352 #ifdef  __cplusplus
 353 }
 354 #endif
 355 
 356 #endif  /* _INET_IP_IRE_H */