#ifndef _INET_ILB_IMPL_H
#define _INET_ILB_IMPL_H
#include <sys/types.h>
#include <sys/kstat.h>
#include <sys/netstack.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ILB_KSTAT_MOD_NAME "ilb"
typedef struct ilb_g_kstat_s {
kstat_named_t num_rules;
kstat_named_t ip_frag_in;
kstat_named_t ip_frag_dropped;
} ilb_g_kstat_t;
#define ILB_KSTAT_UPDATE(ilbs, x, y) \
{ \
DTRACE_PROBE1(ilb__g__kstat__##x, ilb_stack_t *, \
(ilbs)); \
((ilbs)->ilbs_kstat->x.value.ui64 += (y)); \
}
typedef struct ilb_rule_kstat {
kstat_named_t num_servers;
kstat_named_t bytes_not_processed;
kstat_named_t pkt_not_processed;
kstat_named_t bytes_dropped;
kstat_named_t pkt_dropped;
kstat_named_t nomem_bytes_dropped;
kstat_named_t nomem_pkt_dropped;
kstat_named_t noport_bytes_dropped;
kstat_named_t noport_pkt_dropped;
kstat_named_t icmp_echo_processed;
kstat_named_t icmp_dropped;
kstat_named_t icmp_2big_processed;
kstat_named_t icmp_2big_dropped;
} ilb_rule_kstat_t;
#define ILB_R_KSTAT(rule, x) \
{ \
DTRACE_PROBE1(ilb__r__kstat__##x, ilb_rule_t *, \
(rule)); \
((rule)->ir_kstat.x.value.ui64++); \
}
#define ILB_R_KSTAT_UPDATE(rule, x, y) \
{ \
DTRACE_PROBE1(ilb__r__kstat__##x, ilb_rule_t *, \
(rule)); \
((rule)->ir_kstat.x.value.ui64 += (y)); \
}
typedef struct ilb_server_kstat {
kstat_named_t bytes_processed;
kstat_named_t pkt_processed;
kstat_named_t ip_address;
} ilb_server_kstat_t;
#define ILB_S_KSTAT(host, x) \
{ \
DTRACE_PROBE1(ilb__s__kstat__##x, ilb_server_t *, \
(host)); \
((host)->iser_kstat.x.value.ui64++); \
}
#define ILB_S_KSTAT_UPDATE(host, x, y) \
{ \
DTRACE_PROBE1(ilb__s__kstat__##x, ilb_server_t *, \
(host)); \
((host)->iser_kstat.x.value.ui64 += (y)); \
}
#define ILB_ALL_PORTS_RANGE 65534
struct ilb_nat_src_s;
typedef struct ilb_server_s {
in6_addr_t iser_addr_v6;
in6_addr_t iser_prefix_v6;
#define iser_addr_v4 iser_addr_v6.s6_addr32[3]
#define iser_prefix_v4 iser_prefix_v6.s6_addr32[3]
boolean_t iser_port_range;
in_port_t iser_min_port;
in_port_t iser_max_port;
char iser_name[ILB_SERVER_NAMESZ];
char iser_ip_addr[INET6_ADDRSTRLEN];
netstackid_t iser_stackid;
kstat_t *iser_ksp;
ilb_server_kstat_t iser_kstat;
struct ilb_server_s *iser_next;
boolean_t iser_enabled;
kmutex_t iser_lock;
kcondvar_t iser_cv;
uint64_t iser_refcnt;
int64_t iser_die_time;
struct ilb_nat_src_s *iser_nat_src;
} ilb_server_t;
#define ILB_SERVER_REFHOLD(host) \
{ \
mutex_enter(&(host)->iser_lock); \
(host)->iser_refcnt++; \
ASSERT((host)->iser_refcnt != 1); \
mutex_exit(&(host)->iser_lock); \
}
#define ILB_SERVER_REFRELE(host) \
{ \
mutex_enter(&(host)->iser_lock); \
(host)->iser_refcnt--; \
if ((host)->iser_refcnt == 1) \
cv_signal(&(host)->iser_cv); \
mutex_exit(&(host)->iser_lock); \
}
struct ilb_rule_s;
struct ilb_hash_s;
typedef struct ilb_alg_data_s {
boolean_t (*ilb_alg_lb)(in6_addr_t *, in_port_t, in6_addr_t *,
in_port_t, void *, ilb_server_t **);
int (*ilb_alg_server_add)(ilb_server_t *, void *);
int (*ilb_alg_server_del)(ilb_server_t *, void *);
int (*ilb_alg_server_enable)(ilb_server_t *, void *);
int (*ilb_alg_server_disable)(ilb_server_t *, void *);
void (*ilb_alg_fini)(struct ilb_alg_data_s **);
void *ilb_alg_data;
} ilb_alg_data_t;
typedef struct ilb_rule_s {
char ir_name[ILB_RULE_NAMESZ];
uint8_t ir_ipver;
uint8_t ir_proto;
ilb_topo_impl_t ir_topo;
zoneid_t ir_zoneid;
uint32_t ir_flags;
in6_addr_t ir_target_v6;
#define ir_target_v4 ir_target_v6.s6_addr32[3]
in6_addr_t ir_prefix_v6;
#define ir_target_prefix_v4 ir_prefix_v6.s6_addr32[3]
boolean_t ir_port_range;
in_port_t ir_min_port;
in_port_t ir_max_port;
ilb_server_t *ir_servers;
uint32_t ir_nat_expiry;
uint32_t ir_conn_drain_timeout;
in6_addr_t ir_nat_src_start;
in6_addr_t ir_nat_src_end;
boolean_t ir_sticky;
in6_addr_t ir_sticky_mask;
uint32_t ir_sticky_expiry;
struct ilb_rule_s *ir_next;
struct ilb_rule_s *ir_hash_next;
struct ilb_rule_s *ir_hash_prev;
struct ilb_hash_s *ir_hash;
ilb_algo_impl_t ir_alg_type;
ilb_alg_data_t *ir_alg;
kstat_t *ir_ksp;
ilb_rule_kstat_t ir_kstat;
uint_t ir_ks_instance;
kmutex_t ir_lock;
kcondvar_t ir_cv;
uint32_t ir_refcnt;
} ilb_rule_t;
#define ILB_RULE_REFHOLD(rule) \
{ \
mutex_enter(&(rule)->ir_lock); \
(rule)->ir_refcnt++; \
ASSERT((rule)->ir_refcnt != 1); \
mutex_exit(&(rule)->ir_lock); \
}
#define ILB_RULE_REFRELE(rule) \
{ \
mutex_enter(&(rule)->ir_lock); \
ASSERT((rule)->ir_refcnt >= 2); \
if (--(rule)->ir_refcnt <= 2) \
cv_signal(&(rule)->ir_cv); \
mutex_exit(&(rule)->ir_lock); \
}
typedef struct ilb_hash_s {
ilb_rule_t *ilb_hash_rule;
kmutex_t ilb_hash_lock;
#if defined(_LP64)
char ilb_hash_pad[48];
#else
char ilb_hash_pad[56];
#endif
} ilb_hash_t;
struct ilb_nat_src_entry_s;
typedef struct {
in6_addr_t vip;
in6_addr_t nat_dst;
in_port_t dport;
in_port_t nat_dport;
in6_addr_t src;
in6_addr_t nat_src;
in_port_t sport;
in_port_t nat_sport;
struct ilb_nat_src_entry_s *src_ent;
} ilb_nat_info_t;
extern int ilb_kmem_flags;
#ifdef __cplusplus
}
#endif
#endif