/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos72Q src/bos/kernext/cluster/inc/cluster_user.h 1.73                 */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2010,2019              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)34       1.73  src/bos/kernext/cluster/inc/cluster_user.h, sysxcluster, bos72Q, q2019_05A9 1/25/19 12:56:47 */

#ifndef _CLUSTER_USER_H
#define _CLUSTER_USER_H

#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/cfgdb.h>
#include <lvm.h>
#include <netinet/in.h>
#include <sys/cluster.h>
#include <cluster/cluster_user_net.h>
/*
#include <sys/err_rec.h>
 * CANNOT include this as it will break:
 * src/bos/usr/ios/cli/errlog.c build
 *
 * Reference Defect: 966357
*/

#define	SYMKEY_ALG_SZ	6
#define	MAX_SEC_PATH	1024

/*
 * Internal CAA levels, to be used by CAA only. 
 * New functional levels defined at new releases should allow for additional
 * levels to be introduced in the service packs between each release.
 */  
#define CAA_LVL_1               0x00000001      /* CAA 2011 */
#define CAA_LVL_2               0x00020000      /* CAA 2012 */
#define CAA_LVL_3               0x00030000      /* CAA 2013 */
#define CAA_LVL_4               0x00040000      /* CAA 2015 */
#define CAA_LVL_5               0x00050000      /* CAA 2016 */
#define CAA_LVL_6               0x00060000      /* CAA 2017 */
#define CAA_LVL_7               0x00070000      /* CAA 2019 */

const static int caa_levels[7] = {
    CAA_LVL_1,
    CAA_LVL_2,
    CAA_LVL_3,
    CAA_LVL_4,
    CAA_LVL_5,
    CAA_LVL_6,
    CAA_LVL_7
};

/* The maximum level should only be known by the kernel extension. */
#ifdef _KERNEL
#define CAA_MAX_NODE_LEVEL      CAA_LVL_7
#endif /* _KERNEL */

/* Functional and fix-only masks for the CAA effective levels. */
#define CAA_LVL_FUNCTION_MASK   0xFFFFF000
#define CAA_LVL_FIXONLY_MASK    0x00000FFF

/* Gateway ip flags */
#define GWIP_BUSY_CONNECTING    0X0001

/* 
 * Macro to determine whether capabilities have changed between the prior
 * effective level and the new effective level.
 */
#define HAS_CAA_CAPABILITY_CHANGED(_old_lvl, _new_lvl) \
        ( ((_new_lvl) & CAA_LVL_FUNCTION_MASK) >       \
                ((_old_lvl) & CAA_LVL_FUNCTION_MASK) )

typedef char    t_cluster_name_t[MAXHOSTNAMELEN];
typedef char    t_node_name_t[MAXHOSTNAMELEN];
typedef char    t_if_name_t[IFNAMSIZ];
typedef char    zone_name_t[MAXHOSTNAMELEN];

#define CLUSTER_TYPE_LOCAL  1
#define CLUSTER_TYPE_ZONE   2
#define CLUSTER_TYPE_LINK   3
#define MAX_GW_INTERFACE   48

/* cl_change operation */
#define CAA_ENTITY_DEL        0
#define CAA_ENTITY_ADD        1
#define CAA_ENTITY_MOD        2

/* site flags */
#define FLAG_NOPER_PENDING    0x00000000
#define FLAG_MERGE_PENDING    0x00000001
#define FLAG_RBOOT_PENDING    0x00000002
#define FLAG_LINK_BROKE       0x00000004

/* Eye catchers */
#define SITE_B_MARK __EYEC8('C','A','A','_','S','I','T','E');
#define SITE_E_MARK __EYEC8('c','a','a','_','s','i','t','e');
#define MCAST_B_MARK __EYEC8('C','A','A','M','C','A','S','T');
#define MCAST_E_MARK __EYEC8('c','a','a','m','c','a','s','t');

/* Tunables applicable to both cluster and node entities */
typedef struct t_tuncommon {
    int32_t    config_timeout;  /* In seconds        */
    int32_t    node_down_delay; /* In milliseconds   */
    int32_t    node_timeout;    /* In milliseconds   */
    int32_t    link_timeout;    /* In milliseconds   */
    int32_t    caa_level;       /* Eff cluster level & Max Node Level */ 
    char       deadman_mode;    /* a=assert, e=event */
    char       repos_mode;      /* a=assert, e=event */
    int16_t    remote_hb_factor;/* hb factor        */
    int16_t    packet_ttl;      /* Packet time-to-live */
    int8_t     no_if_traffic_monitor; /* Interface traffic monitoring */
    int8_t     spare;           /* Extra space */
    int32_t    spares[3];       /* Extra space */
} t_tuncommon_t;

/* Clusterwide tunables not applicable to node entities */
typedef struct t_tunclust {
    char           communication_mode;    /* u=unicast, m=multicast */
    char           reserverd;
    short          hb_src_san;    /* -1..3             */
    short          hb_src_disk;   /* -1..3             */
    char           site_merge_policy; /* p, h, m       */
    char           locl_merge_policy; /* n(one) or m(ajority) */
    int32_t        network_fdt;     /* Local network failure detection time */
    int32_t        dr_enabled  : 2, /* Disaster Recovery on - off - unset */
                   reserved    : 30;
    int32_t        spare[2];
} t_tunclust_t;

typedef struct t_clustuuid
{
    t_wwid_t        cluster_uuid;        /* The unique identifier */
    t_cluster_name_t    cluster_name;
    u_int16_t       ndd_tcpsock_port;    /* for multi-site support */
    u_int16_t       cluster_type;
    u_int16_t       site_shid;           /* my site short id */
    u_int16_t       cluster_shid;
    t_tuncommon_t   cluster_tuncommon;
    t_tunclust_t    cluster_tunclust;
} t_clustuuid_t, *t_clustuuid_p;

typedef struct t_clust_data
{
    eye_catch8b_t       b_mark;
    t_wwid_t            cluster_uuid;        /* The unique identifier */
    t_cluster_name_t    cluster_name;
    u_int16_t           cluster_type;
    u_int16_t           cluster_shid;
    int64_t             reserved[4];    /* reserved for future use */
    eye_catch8b_t       e_mark;
} t_clust_data_t, *t_clust_data_p;

typedef struct t_site_data
{
    eye_catch8b_t         b_mark;         /* eye-catcher to mark the beginning */
    t_wwid_t              uuid;           /* The unique identifier */
    t_cluster_name_t      name;           /* name of the site */
    uint16_t              prio;           /* priority of the site */
    uint16_t              shid;           /* short id of the site */
    uint16_t              nodes_up;       /* Number of nodes up in this site */
    uint16_t              flags;          /* flags of the site */
    uint64_t              reserved[4];    /* reserved for future use */
    eye_catch8b_t         e_mark;         /* eye-catcher to mark the end */
} t_site_data_t, *t_site_data_p;

typedef struct t_sitelist
{
    u_int32_t       num_sites;        /* number of sites. */
    u_int32_t       pad;              /* Pad to allign the struct*/
    t_site_data_t   site_detail[1];   /* Really num_sites long. */
} t_sitelist_t, *t_sitelist_p;

typedef struct t_mcast_data
{
    eye_catch8b_t         b_mark;         /* eye-catcher to mark the beginning */
    t_wwid_t              uuid;           /* The unique identifier */
    t_wwid_t              site_uuid;      /* uuid of site it belongs to */
    struct t_addr_ip_mreq multiaddr_ipv4; /* mcast of site ipv4 format */
    struct t_addr_ip_mreq multiaddr_ipv6; /* mcast of site ipv6 format */
    uint64_t              reserved[4];    /* reserved for future use */
    eye_catch8b_t         e_mark;         /* eye-catcher to mark the end */
} t_mcast_data_t, *t_mcast_data_p;

typedef struct t_mcastlist
{
    u_int32_t       num_mcasts;        /* number of mcasts. */
    u_int32_t       pad;               /* Pad to allign the struct*/
    t_mcast_data_t  mcast_detail[1];   /* Really num_mcasts long. */
} t_mcastlist_t, *t_mcastlist_p;

typedef struct t_contact
{
    t_if_name_t     contact_if_name;     /* The unique identifier for this */
    u_int32_t       contact_state;
} t_contact_t, *t_contact_p;

/* All data in this structure is constant and user visible
 * no matter what cluster is referencing the node. The exception is
 * shorthand id which is used for input only
 */
typedef struct t_node_data
{
    t_addr_ip_t     net_addr;
    u_int32_t       flags;
    u_int32_t       num_clusters;       /* No of clusters node is a member */

    u_int32_t       points_of_contact;  /* Number of interfaces node has communicated on */
    u_int32_t       num_zones;          /* No of zones node is a member */
    short           srtt;               /* Smoothed round trip time */
    short           rttvar;             /* Round trip var */
    t_wwid_t        uuid;               /* For node */
    t_wwid_t        site_uuid;

    uint16_t        site_shid;
    clustid_t       shorthand_id;
    t_node_name_t   host_name;
    u_int32_t       sec_status;         /* Indicates security enablement of a node */

    /* gateway parameters */
    short           n_gw;
    struct {
        short       gw_flag;
        short       gw_pri;
        t_addr_ip_t gw_ip;
    } gw[MAX_GW_INTERFACE];

    /* node tunables */
    t_tuncommon_t   tunables;

    u_int32_t       gw_flag: 1;
    u_int32_t       ffdc_by_comp: 6;   /* FFDC bits need to sync with ucluster_prot.h */
    u_int32_t       ffdc_priority:  2; 
    u_int32_t       ffdc_verbosity: 1;
    u_int32_t       reason: 4;         /* for NODE_UP or NODE_DOWN */         
    u_int32_t       pad1: 18;
    u_int32_t       pad[6];

} t_node_data_t, *t_node_data_p;

typedef struct t_node_query
{
    t_node_data_t   base_data;
    t_clustuuid_t   cluster_data[1];   /* Really num_clusters (in base_data) long */
    t_contact_t     contact_data[1];   /* Really points_of_contact (in base_data) long */
} t_node_query_t, *t_node_query_p;

/* Contact V2 structure contains additional information for TCP sock interface */ 
typedef struct t_contact_v2
{
    t_if_name_t     contact_if_name;     /* The unique identifier for this */
    u_int32_t       contact_state;
    u_int32_t       contact_flags;
    t_addr_ip_t     contact_src_ip;   /* SRC IP Address of tcpsock interface */
    t_addr_ip_t     contact_dst_ip;   /* DST IP Address of tcpsock interface */
    u_int32_t       reserved[4];
} t_contact_v2_t, *t_contact_v2_p;

/* Node query v2 structure contains additional contact information */
typedef struct t_node_query_v2
{
    t_node_data_t   base_data;
    t_clustuuid_t   cluster_data[1];   /* Really num_clusters (in base_data) long */
    t_contact_v2_t  contact_data[1];   /* Really points_of_contact (in base_data) long */
} t_node_query_v2_t, *t_node_query_v2_p;


#define CLUSTER_DISK_DOWN 0x0
#define CLUSTER_DISK_UP 0x1
#define CLUSTER_DISK_NOT_FOUND  0x02
#define CLUSTER_DISK_NOT_READY  0x04

/* disk_attr_flags: This is not the same as User Space (ucluster_prot.h)
 * CL_3RD_PARTY_REPOSDISK
 */
#define CLUSTER_DISK_3RD_PARTY   0x1
#define CLUSTER_DISK_BKUP_DISK   0x2
#define CLUSTER_DISK_COM_DISK    0x4

typedef struct t_disk_data
{
    dev64_t     disk_clust_dev_t;
    char        disk_name[ATTRNAMESIZE];   /* CuAt.name */
    struct unique_id disk_pvid;            /* CuAt.pvid */
    char        reserved[32];              /* Remaining of original LVM_NAMESIZ */
    char        disk_udid[ATTRVALSIZE];    /* CuAt.unique_id */
    t_wwid_t    disk_uuid;                 /* 128 bit UUID per <uuid.h> */
    t_wwid_t    site_uuid;
    unsigned    status_flag: 3;
    unsigned    type: 3;
    unsigned    disk_attr_flags: 4;
    unsigned    pad: 22;
    unsigned    pad1;
} t_disk_data_t, *t_disk_data_p;

typedef struct d_list   /* How cluster keeps disk lists */
{
    char                    node_name[MAXHOSTNAMELEN];
    t_wwid_t                node_uuid;
    u_int32_t               num_disk; /* Number of disk */
    t_disk_data_t           disk_detail[1]; /* Really num_if long */
} d_list_t, *d_list_p;

typedef struct disk_list_cluster   /* How cluster keeps disk lists */
{
    if_list_cluster_hdr_t   list_hdr;
    struct d_list           disk_list[1]; /*num_nodes_reporting long */
} d_list_cluster_t, *d_list_cluster_p;

typedef struct t_nodelist
{
    u_int32_t       num_nodes;        /* number of nodes. */
    u_int32_t       pad;              /* Pad to allign the struct*/
    t_node_data_t   node_detail[1];   /* Really num_nodes long. */
} t_nodelist_t, *t_nodelist_p;

typedef struct t_disklist
{
    u_int32_t       num_disks;        /* number of cluster disks. */
    u_int32_t       pad;              /* Pad to allign the struct*/
    t_disk_data_t   disk_detail[1];   /* Really num_disks long. */
} t_disklist_t, *t_disklist_p;

typedef struct t_event_data
{
    dev64_t         dev;
    char            disk_name[ATTRNAMESIZE];
    struct unique_id disk_pvid;           
    char            reserved[32];
    char            disk_udid[ATTRVALSIZE];
    t_wwid_t        uuid;
    t_wwid_t        site_uuid;
    unsigned        status_disk: 3;
    unsigned        type: 3;
    unsigned        disk_attr_flags: 4;
    unsigned        status_vg: 1;
    unsigned        pad: 21;
    struct unique_id vg_id;
    struct unique_id pv_id;
    char            vg_name[LVM_NAMESIZ];
} t_event_data_t, *t_event_data_p;

typedef struct eventdisk   /* How cluster keeps list of disks */
{
    TAILQ_ENTRY(eventdisk)  kevent_entry;
    t_event_data_t          t_disk_detail; /* wwid of storage device */
} t_eventdisk_t, *t_eventdisk_p;

typedef struct t_event_disklst
{
    u_int32_t  num_clust_disks;
    u_int32_t  num_local_disk;
    u_int32_t  num_repo_disk;

} t_event_disklst_t, *t_event_disklst_p;

typedef struct t_ctrl
{
    t_clustuuid_t   cluster;
    t_node_data_t   node;
    t_disk_data_t   disk;
} t_ctrl_t, *t_ctrl_p;

typedef struct t_stat
{
    struct t_stat_net nets;
} t_stat_t, *t_stat_p;

/* 
 * Mapping to src/bos/kernel/sys/ahafs_kern.h events with same values
 * Names made unique by "User Event = UEVENT"
 */
typedef enum
{
    CAA_UEVENT_DOWN  = 0,
    CAA_UEVENT_UP    = 1,
    CAA_UEVENT_SPLIT = 2,
    CAA_UEVENT_MERGE = 3
} event_type_t;

/* 
 * Mapping to src/bos/kernel/sys/ahafs_kern.h events with same values
 * Names are already unique.
 */
typedef enum
{
    CAA_SUBEVENT_NONE   = 0,
    CAA_LINK_DOWN       = 1,
    CAA_LINK_UP         = 2,
    CAA_RESYNC_SITES    = 3,
    CAA_NODE_SHUTDOWN   = 4,
    CAA_FORCE_DOWN      = 5,
    CAA_FORCE_UP        = 6,
    CAA_SUBEVENT_LOCAL  = 7,
    CAA_SUBEVENT_REMOTE = 8
} event_subtype_t;

typedef struct t_splitmerge
{
    event_type_t     type;
    event_subtype_t  subtype;
    uint16_t         local_nodeup;
    uint16_t         remote_nodeup;
    char             local_island[256];  /* in the format shid:shid: */
    char             remote_island[256]; /* in the format shid:shid: */
} t_splitmerge_t, *t_splitmerge_p;

/* cluster zone list */
#define MAX_CLUSTER_ZONES       256

#define SIZEOF_ZONE_NODELIST(x) \
    ((x)->zone_num_nodes * sizeof(t_node_name_t))

#define SIZEOF_ZONE(x)      \
    (sizeof(cluster_zone_t) - sizeof((x)->zone_node_name) + \
     (SIZEOF_ZONE_NODELIST(x)))

#define ZONE_NEXT(z)        \
    ((cluster_zone_t *)((void *)(z) + SIZEOF_ZONE(z)))

typedef struct cluster_zone
{
    t_wwid_t    zone_id;   /* zone id */
    zone_name_t zone_name; /* zone name */
    u_int32_t   zone_num_nodes;
    u_int32_t   zone_shid; /* shorthand ID (low 16 only) */
    t_node_name_t   zone_node_name[1];
} cluster_zone_t;

typedef struct cluster_zones
{
    u_int32_t       num_zones;
    u_int32_t       pad;
    cluster_zone_t  zone[1]; /* zone details, num_zones long */
} cluster_zones_t;

/* cluster link */
#define MAX_LINK_GW     5
typedef struct link_gw
{
    clustid_t       gw_node_id;
    clustid_t       gw_remote_node_id;
    u_int32_t       gw_status;
} link_gw_t, *link_gw_p;

typedef struct cluster_link
{
    t_wwid_t         ovel_id;        /* ovel uuid */
    t_cluster_name_t ovel_name;      /* ovel name */
    t_addr_ip_mreq_t ovel_multicast; /* ovel multicast address */
    u_int32_t        ovel_status;    /* ovel status, used only in queries */
    t_wwid_t         rsircol_id;     /* remote sircol uuid */
    t_cluster_name_t rsircol_name;   /* remote sircol name */
#if 0
    link_gw_t        link_gws[MAX_LINK_GW];
#endif
} cluster_link_t, *cluster_link_p;

#if 0
typedef struct cluster_links
{
    u_int32_t       num_links;
    u_int32_t       pad;
    cluster_link_t  link[1];
} cluster_links_t, *cluster_links_p;
#endif

typedef struct cluster_sec_data
{
    int         seclevel;
    int         security_enabled;
    char        symkey_alg[SYMKEY_ALG_SZ];
    short	cert_type;  /* Certificate type */
    char        cert_path[MAX_SEC_PATH]; /*Certificate  Path */
    char        priv_path[MAX_SEC_PATH]; /* Private Key path */
  
} cluster_sec_data_t, *cluster_sec_data_p;

/* Commands passed to xcluster_lock() */
#define CLUSTER_LOCK            1
#define CLUSTER_UNLOCK          2
#define CLUSTER_LOCK_QUERY      3
#define CLUSTER_LOCK_NOWAIT     4
#define CLUSTER_LOCK_WAIT       5
#define CLUSTER_SITE_LOCK       6
#define CLUSTER_SITE_UNLOCK     7
#define CLUSTER_SITE_LOCK_QUERY 8

/* Commands passed to xcluster_parm() */
#define CLUSTER_VAL_GET         1
#define CLUSTER_VAL_SET         2

/* For storage disk event */
#define CLUSDISK                0x1
#define LOCALDISK               0x2
#define REPDISK                 0x4

/* commands passed to xcluster_control_io syscall */
#define CLUSTER_STOP_IO             0x0
#define CLUSTER_START_IO            0x1
#define CLUSTER_STOP_NETIO          0x2
#define CLUSTER_START_NETIO         0x4
#define CLUSTER_STOP_ALL_NETIO      0x8
#define CLUSTER_START_ALL_NETIO    0x10

/* commands passed to xcluster_ctrl syscall */
#define CAA_CTRL_GET_REAL          1
#define CAA_CTRL_GET_EFF           2
#define CAA_CTRL_SET               3
#define CAA_CTRL_UNSET             4
#define CAA_CTRL_RM_REPOS          5
#define CAA_CTRL_ADD_REPOS         6
#define CAA_CTRL_MERGE_COMPLETE    7
#define CAA_CTRL_GET_SFW_STATUS    8

/* arg value for node flags (ie. node operational state).  */
#define CAA_NODE_STATE          1

/* arg values for cluster tunables */
#define CAA_CL_CONFIG_TIMEOUT   2
#define CAA_CL_NODE_DOWN_DELAY  3
#define CAA_CL_NODE_TIMEOUT     4
#define CAA_CL_LINK_TIMEOUT     5
#define CAA_CL_DEADMAN_MODE     6
#define CAA_CL_REPOS_MODE       7
#define CAA_CL_COMM_MODE        8
#define CAA_CL_HB_SRC_SAN       9
#define CAA_CL_HB_SRC_DISK      10
#define CAA_CL_SITE_UP          11
#define CAA_CL_LOCL_MERGE_POLICY 12

/* arg values for node tunables */
#define CAA_CONFIG_TIMEOUT      13
#define CAA_NODE_DOWN_DELAY     14
#define CAA_NODE_TIMEOUT        15
#define CAA_LINK_TIMEOUT        16
#define CAA_DEADMAN_MODE        17
#define CAA_REPOS_MODE          18

/* arg values for cluster - node tunables */
#define CAA_CL_REMOTE_HB_FACTOR  19
#define CAA_CL_SITE_MERGE_POLICY 20

/* arg value for levels */
#define CAA_CL_EFF_LVL           21

/* arg value for packet TTL (node and cluster) */
#define CAA_CL_PACKET_TTL       22
#define CAA_PACKET_TTL          23

/* CAA_CTRL_GET_SFW_STATUS arg values, DPCOMM/SANCOMM status */
#define CAA_DPCOMM_STATUS       24
#define CAA_SANCOMM_STATUS      25

/* arg value for disk flags (ie. disk operational state). */
#define CAA_CTRL_DISK_STATE     26

/*
 *  Arg values to monitor network traffic,
 *  to determine the state of network interfaces.
 */
#define CAA_CL_NOIF_TRAF_MON    27
#define CAA_NOIF_TRAF_MON       28

/* Arg values for local network failure detection interval (node and cluster) */
#define CAA_CL_NETWORK_FDT    29

/* Disaster Recovery tunable */
#define CAA_CL_DR_ENABLED     30

#define CAA_CTRL_MAX_ARG CAA_CL_DR_ENABLED

/* Security cmd value */
#define CLUSTER_SEC_ENABLE   1
#define CLUSTER_SEC_DISABLE  2
#define CLUSTER_SEC_RE_ENABLE 3
#define CLUSTER_GET_SECDATA 4

/* Security enable values */
#define FALSE            0
#define TRUE             1
#define EN_INPROCESS     2
#define DIS_INPROCESS    3
#define SYMKEY_INPUT     4

/* Security Certificate Types */
#define SELF_SIGNED      1
#define OPEN_SSL         2
#define SSH              3
#define SYMKEY_DEFINED   4

/* Argument structure for FFDC operations.  
 * Used by both the libcluster and the kernext layer interfaces.
 */
#define FFDC_SUBTYPE_REGULAR    0
#define FFDC_SUBTYPE_GATHER     1
#define FFDC_SUBTYPE_UPCALL     2

#define FFDC_FROM_FILE_BUFLEN   32

/* Sync cl_ffdc_args with kcl_ffdc_args in sys/cluster.h */
struct cl_ffdc_args {
    uint16_t        ff_subtype;           /* Message subtype. */
    uint16_t        ff_version;           /* Message version number. */

    uint32_t        ff_by_comp      : 6,  /* 1-63 */
                    ff_by_me        : 1,  /* 0-1 : 0 not by me, 1 by me. */
                    ff_priority     : 2,  /* 0-3 : 0 unset, 1 high, 
                                           *       2 med, 3 low. 
                                           */
                    ff_verbosity    : 1,  /* 0-1 : 0 unset, 1 verbose. */
                    ff_lineno       : 16, /* Max line 65536. */
                    ff_repo_down    : 1,  /* 0-1 : 0 Repo is up.
                                           *     : 1 Repo is down.
                                           */
                    ff_staged       : 1,  /* 0-1 : 0 Snap and gather 
                                           *       in one stage. 
                                           *     : 1 Split snap and 
                                           *       gather into separate 
                                           *       stages.
                                           */
                    ff_ffdc_pad1    : 4;

    char            ff_from_file[FFDC_FROM_FILE_BUFLEN];

    uint16_t        ff_correlator;        /* Correlator for this ffdc req.  
                                           * Undefined in CL_FFDC_MSG_VERSION_1.
                                           * Required in CL_FFDC_MSG_VERSION_2.
                                           */
    clustid_t       ff_initiator;         /* Initiator nodeId. */
    clustid_t       ff_gatherId;          /* Source nodeId for gather msg. */

    uint16_t        ff_reserved1[5];      /* Reserved for future use. */

};

/* Valid values for ff_version. */
#define CL_FFDC_MSG_VERSION_1       0x1
#define CL_FFDC_MSG_VERSION_2       0x2

#define CL_FFDC_MSG_VERSION_LATEST  CL_FFDC_MSG_VERSION_2

/* Client FFDC callout scripts */
#define SCRIPT_CAA_FFDC         "/usr/lib/cluster/caa_ffdc.sh"
#define SCRIPT_RSCT_FFDC        "/usr/sbin/rsct_ffdc.sh"
#define SCRIPT_VIOS_FFDC        "/usr/ios/sbin/vios_ffdc.sh"
#define SCRIPT_POOL_FFDC        "/usr/sbin/pool_ffdc.sh"
#define SCRIPT_PHA_FFDC         "/usr/es/sbin/cluster/sbin/sm_ffdc.sh"
#define SCRIPT_COMMON_FFDC      "/usr/lib/cluster/common_ffdc.sh"

/*
 * Who initiated the FFDC
 * As well as a done bit and max for range checking
 *
 * There are only 6 bits reserved for this in t_node_data_t.
 * Max value it can ever be is 63.
 */
/* "CLEAR"                  0 */
#define FFDC_DONE           1
#define FFDC_BY_CAA         2
#define FFDC_BY_RSCT        3       
#define FFDC_BY_VIOS        4
#define FFDC_BY_POOL        5
#define FFDC_BY_PHA         6
#define FFDC_BY_FULLSNAP    7
/* ... */
/* #define FFDC_UNUSED  63 */
#define FFDC_MAX        FFDC_BY_FULLSNAP

const static struct {
    char by_str[10];
} FFDC_BY_STR[] = {
    "Clear",  /* 0 - Unset        */
    "Done",   /* 1 - FFDC_DONE    */
    "CAA",    /* 2 - FFDC_BY_CAA  */
    "RSCT",   /* 3 - FFDC_BY_RSCT */
    "VIOS",   /* 4 - FFDC_BY_VIOS */
    "POOL",   /* 5 - FFDC_BY_POOL */
    "PHA",    /* 6 - FFDC_BY_PHA  */
    "Full"    /* 7 - FFDC_BY_FULLSNAP */
};

/*
 * Priority of the FFDC
 * FFDC Mapping to to strings to maintain in one location.
 *
 * There are only 2 bits reserved for this in t_node_data_t.
 * Max entries it can ever have is 4 (0, 1, 2, 3).
 */
/* "NONE"               0 */
#define FFDC_HIGH       1
#define FFDC_MED        2
#define FFDC_LOW        3

const static struct {
    char prio[10];
} FFDC_PRIO_STR[] = {
    "None",  /* 0 - Unset     */
    "High",  /* 1 - FFDC_HIGH */
    "Med",   /* 2 - FFDC_MED  */
    "Low"    /* 3 - FFDC_LOW  */
};

const static struct {
    int unset;
    int def;
    int min;
    int max;
} CAA_TUNABLE_CONST[] = {
    {   -2,      -2,      -2,      -2 }, /* 0  - unused                  */
    {   -2,      -2,      -2,      -2 }, /* 1  - CAA_NODE_STATE - n/a    */
    {   -1,     240,       0, INT_MAX }, /* 2  - CAA_CL_CONFIG_TIMEOUT   */
    {   -1,   10000,    5000,  600000 }, /* 3  - CAA_CL_NODE_DOWN_DELAY  */
    {   -1,   20000,   10000,  600000 }, /* 4  - CAA_CL_NODE_TIMEOUT     */
    {   -1,   30000,       0, 1200000 }, /* 5  - CAA_CL_LINK_TIMEOUT     */
    { '\0',     'a',    '\0',    '\0' }, /* 6  - CAA_CL_DEADMAN_MODE     */
    { '\0',     'e',    '\0',    '\0' }, /* 7  - CAA_CL_REPOS_MODE       */
    { '\0',     'm',    '\0',    '\0' }, /* 8  - CAA_CL_COMM_MODE        */
    {   -2,       2,      -1,       3 }, /* 9  - CAA_CL_HB_SRC_SAN       */
    {   -2,       1,      -1,       3 }, /* 10 - CAA_CL_HB_SRC_DISK      */
    { '\0',     'e',    '\0',    '\0' }, /* 11 - CAA_CL_SITE_UP          */
    { '\0',     'm',    '\0',    '\0' }, /* 12 - CAA_CL_LOCL_MERGE_POLICY*/
    {   -1,     240,       0, INT_MAX }, /* 13 - CAA_CONFIG_TIMEOUT      */
    {   -1,   10000,    5000,  600000 }, /* 14 - CAA_NODE_DOWN_DELAY     */
    {   -1,   20000,   10000,  600000 }, /* 15 - CAA_NODE_TIMEOUT        */
    {   -1,   30000,       0, 1200000 }, /* 16 - CAA_LINK_TIMEOUT        */
    { '\0',     'a',    '\0',    '\0' }, /* 17 - CAA_DEADMAN_MODE        */
    { '\0',     'e',    '\0',    '\0' }, /* 18 - CAA_REPOS_MODE          */
    {   -1,       1,       1,     100 }, /* 19 - CAA_CL_REMOTE_HB_FACTOR */
    { '\0',     'p',    '\0',    '\0' }, /* 20 - CAA_CL_SITE_MERGE_POLICY*/
    {   -1,      -1,      -1,     -1  }, /* 21 - DUMMY ENTRY for LEVEL   */
    {   -1,      32,       1,     64  }, /* 22 - CAA_CL_PACKET_TTL       */
    {   -1,      32,       1,     64  }, /* 23 - CAA_PACKET_TTL          */
    { '\0',    '\0',    '\0',    '\0' }, /* 24 - CAA_DPCOMM_STATUS       */
    { '\0',    '\0',    '\0',    '\0' }, /* 25 - CAA_SANCOMM_STATUS      */
    { '\0',    '\0',    '\0',    '\0' }, /* 26 - CAA_CTRL_DISK_STATE     */
    {   -1,       0,       0,      1  }, /* 27 - CAA_CL_NOIF_TRAF_MON    */
    {   -1,       0,       0,      1  }, /* 28 - CAA_NOIF_TRAF_MON       */
    {   -1,       0,       0, 590000  }, /* 29 - CAA_CL_NETWORK_FDT      */
    {   -1,       0,       0,      1  }, /* 30 - CAA_CL_DR_ENABLED      */
};

const static struct {
    int unset;
    int def;
    int min;
    int max;
} CAA_TUNABLE_CONST_VIO[] = {
    {   -2,      -2,      -2,      -2 }, /* 0  - unused                  */
    {   -2,      -2,      -2,      -2 }, /* 1  - CAA_NODE_STATE - n/a    */
    {   -1,     480,       0, INT_MAX }, /* 2  - CAA_CL_CONFIG_TIMEOUT   */
    {   -1,   10000,    5000,  600000 }, /* 3  - CAA_CL_NODE_DOWN_DELAY  */
    {   -1,   20000,   10000,  600000 }, /* 4  - CAA_CL_NODE_TIMEOUT     */
    {   -1,       0,       0,       0 }, /* 5  - CAA_CL_LINK_TIMEOUT     */
    { '\0',     'a',    '\0',    '\0' }, /* 6  - CAA_CL_DEADMAN_MODE     */
    { '\0',     'e',    '\0',    '\0' }, /* 7  - CAA_CL_REPOS_MODE       */
    { '\0',     'm',    '\0',    '\0' }, /* 8  - CAA_CL_COMM_MODE        */
    {   -2,       0,      -1,       3 }, /* 9  - CAA_CL_HB_SRC_SAN       */
    {   -2,       1,      -1,       3 }, /* 10 - CAA_CL_HB_SRC_DISK      */
    { '\0',     'e',    '\0',    '\0' }, /* 11 - CAA_CL_SITE_UP          */
    { '\0',     'n',    '\0',    '\0' }, /* 12 - CAA_CL_LOCL_MERGE_POLICY*/
    {   -1,     480,       0, INT_MAX }, /* 13 - CAA_CONFIG_TIMEOUT      */
    {   -1,   10000,    5000,  600000 }, /* 14 - CAA_NODE_DOWN_DELAY     */
    {   -1,   20000,   10000,  600000 }, /* 15 - CAA_NODE_TIMEOUT        */
    {   -1,       0,       0,       0 }, /* 16 - CAA_LINK_TIMEOUT        */
    { '\0',     'a',    '\0',    '\0' }, /* 17 - CAA_DEADMAN_MODE        */
    { '\0',     'e',    '\0',    '\0' }, /* 18 - CAA_REPOS_MODE          */
    {   -1,       1,       1,     100 }, /* 19 - CAA_CL_REMOTE_HB_FACTOR */
    { '\0',     'p',    '\0',    '\0' }, /* 20 - CAA_CL_SITE_MERGE_POLICY*/
    {   -1,      -1,      -1,     -1  }, /* 21 - DUMMY ENTRY for LEVEL   */
    {   -1,      32,       1,     64  }, /* 22 - CAA_CL_PACKET_TTL       */
    {   -1,      32,       1,     64  }, /* 23 - CAA_PACKET_TTL          */
    { '\0',    '\0',    '\0',    '\0' }, /* 24 - CAA_DPCOMM_STATUS       */
    { '\0',    '\0',    '\0',    '\0' }, /* 25 - CAA_SANCOMM_STATUS      */
    { '\0',    '\0',    '\0',    '\0' }, /* 26 - CAA_CTRL_DISK_STATE     */
    {   -1,       0,       0,      1  }, /* 27 - CAA_CL_NOIF_TRAF_MON    */
    {   -1,       0,       0,      1  }, /* 28 - CAA_NOIF_TRAF_MON       */
    {   -1,       0,       0, 590000  }, /* 29 - CAA_CL_NETWORK_FDT      */
    {   -1,       0,       0,      1  }, /* 30 - CAA_CL_DR_ENABLED      */
};

#ifndef _KERNEL
#define is_a_vios am_i_a_vios
#endif
#define caa_tun_const(w, i) (is_a_vios()?(CAA_TUNABLE_CONST_VIO[i].##w):(CAA_TUNABLE_CONST[i].##w))
#define ffdc_prio_const(i) ((i>=0 && i<=FFDC_LOW)?FFDC_PRIO_STR[i].prio:"Out of range")
#define ffdc_by_const(i) ((i>=0 && i<=FFDC_MAX)?FFDC_BY_STR[i].by_str:"Out of range")

#endif /* _CLUSTER_USER_H */
