+ cfs_list_t ni_list; /* chain on ln_nis */
+ cfs_list_t ni_cptlist; /* chain on ln_nis_cpt */
+ int ni_maxtxcredits; /* # tx credits */
+ /* # per-peer send credits */
+ int ni_peertxcredits;
+ /* # per-peer router buffer credits */
+ int ni_peerrtrcredits;
+ /* seconds to consider peer dead */
+ int ni_peertimeout;
+ int ni_ncpts; /* number of CPTs */
+ __u32 *ni_cpts; /* bond NI on some CPTs */
+ lnet_nid_t ni_nid; /* interface's NID */
+ void *ni_data; /* instance-specific data */
+ lnd_t *ni_lnd; /* procedural interface */
+ struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */
+ int **ni_refs; /* percpt reference count */
+ long ni_last_alive; /* when I was last alive */
+ lnet_ni_status_t *ni_status; /* my health status */
+ /* equivalent interfaces to use */
+ char *ni_interfaces[LNET_MAX_INTERFACES];
+} lnet_ni_t;
+
+#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
+
+/* NB: value of these features equal to LNET_PROTO_PING_VERSION_x
+ * of old LNet, so there shouldn't be any compatibility issue */
+#define LNET_PING_FEAT_INVAL (0) /* no feature */
+#define LNET_PING_FEAT_BASE (1 << 0) /* just a ping */
+#define LNET_PING_FEAT_NI_STATUS (1 << 1) /* return NI status */
+
+#define LNET_PING_FEAT_MASK (LNET_PING_FEAT_BASE | \
+ LNET_PING_FEAT_NI_STATUS)
+
+typedef struct {
+ __u32 pi_magic;
+ __u32 pi_features;
+ lnet_pid_t pi_pid;
+ __u32 pi_nnis;
+ lnet_ni_status_t pi_ni[0];
+} WIRE_ATTR lnet_ping_info_t;
+
+/* router checker data, per router */
+#define LNET_MAX_RTR_NIS 16
+#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS])
+typedef struct {
+ /* chain on the_lnet.ln_zombie_rcd or ln_deathrow_rcd */
+ cfs_list_t rcd_list;
+ lnet_handle_md_t rcd_mdh; /* ping buffer MD */
+ struct lnet_peer *rcd_gateway; /* reference to gateway */
+ lnet_ping_info_t *rcd_pinginfo; /* ping buffer */
+} lnet_rc_data_t;
+
+typedef struct lnet_peer {
+ cfs_list_t lp_hashlist; /* chain on peer hash */
+ cfs_list_t lp_txq; /* messages blocking for tx credits */
+ cfs_list_t lp_rtrq; /* messages blocking for router credits */
+ cfs_list_t lp_rtr_list; /* chain on router list */
+ int lp_txcredits; /* # tx credits available */
+ int lp_mintxcredits; /* low water mark */
+ int lp_rtrcredits; /* # router credits */
+ int lp_minrtrcredits; /* low water mark */
+ unsigned int lp_alive:1; /* alive/dead? */
+ unsigned int lp_notify:1; /* notification outstanding? */
+ unsigned int lp_notifylnd:1; /* outstanding notification for LND? */
+ unsigned int lp_notifying:1; /* some thread is handling notification */
+ unsigned int lp_ping_notsent; /* SEND event outstanding from ping */
+ int lp_alive_count; /* # times router went dead<->alive */
+ long lp_txqnob; /* bytes queued for sending */
+ cfs_time_t lp_timestamp; /* time of last aliveness news */
+ cfs_time_t lp_ping_timestamp; /* time of last ping attempt */
+ cfs_time_t lp_ping_deadline; /* != 0 if ping reply expected */
+ cfs_time_t lp_last_alive; /* when I was last alive */
+ cfs_time_t lp_last_query; /* when lp_ni was queried last time */
+ lnet_ni_t *lp_ni; /* interface peer is on */
+ lnet_nid_t lp_nid; /* peer's NID */
+ int lp_refcount; /* # refs */
+ int lp_cpt; /* CPT this peer attached on */
+ /* # refs from lnet_route_t::lr_gateway */
+ int lp_rtr_refcount;
+ /* returned RC ping features */
+ unsigned int lp_ping_feats;
+ cfs_list_t lp_routes; /* routers on this peer */
+ lnet_rc_data_t *lp_rcd; /* router checker state */
+} lnet_peer_t;
+
+
+/* peer hash size */
+#define LNET_PEER_HASH_BITS 9
+#define LNET_PEER_HASH_SIZE (1 << LNET_PEER_HASH_BITS)
+
+/* peer hash table */
+struct lnet_peer_table {
+ int pt_version; /* /proc validity stamp */
+ int pt_number; /* # peers extant */
+ cfs_list_t pt_deathrow; /* zombie peers */
+ cfs_list_t *pt_hash; /* NID->peer hash */
+};
+
+#define lnet_peer_aliveness_enabled(lp) ((lp)->lp_ni->ni_peertimeout > 0)
+
+typedef struct {
+ cfs_list_t lr_list; /* chain on net */
+ cfs_list_t lr_gwlist; /* chain on gateway */
+ lnet_peer_t *lr_gateway; /* router node */
+ __u32 lr_net; /* remote network number */
+ int lr_seq; /* sequence for round-robin */
+ unsigned int lr_downis; /* number of down NIs */
+ unsigned int lr_hops; /* how far I am */
+} lnet_route_t;
+
+typedef struct {
+ cfs_list_t lrn_list; /* chain on ln_remote_nets */
+ cfs_list_t lrn_routes; /* routes to me */
+ __u32 lrn_net; /* my net number */
+} lnet_remotenet_t;
+
+typedef struct {
+ cfs_list_t rbp_bufs; /* my free buffer pool */
+ cfs_list_t rbp_msgs; /* messages blocking for a buffer */
+ int rbp_npages; /* # pages in each buffer */
+ int rbp_nbuffers; /* # buffers */
+ int rbp_credits; /* # free buffers / blocked messages */
+ int rbp_mincredits; /* low water mark */
+} lnet_rtrbufpool_t;
+
+typedef struct {
+ cfs_list_t rb_list; /* chain on rbp_bufs */
+ lnet_rtrbufpool_t *rb_pool; /* owning pool */
+ lnet_kiov_t rb_kiov[0]; /* the buffer space */
+} lnet_rtrbuf_t;
+
+#include <libcfs/libcfs_pack.h>
+typedef struct {
+ __u32 msgs_alloc;
+ __u32 msgs_max;
+ __u32 errors;
+ __u32 send_count;
+ __u32 recv_count;
+ __u32 route_count;
+ __u32 drop_count;
+ __u64 send_length;
+ __u64 recv_length;
+ __u64 route_length;
+ __u64 drop_length;
+} WIRE_ATTR lnet_counters_t;
+#include <libcfs/libcfs_unpack.h>
+
+#define LNET_PEER_HASHSIZE 503 /* prime! */
+
+#define LNET_NRBPOOLS 3 /* # different router buffer pools */
+
+enum {
+ /* Didn't match anything */
+ LNET_MATCHMD_NONE = (1 << 0),
+ /* Matched OK */
+ LNET_MATCHMD_OK = (1 << 1),
+ /* Must be discarded */
+ LNET_MATCHMD_DROP = (1 << 2),
+ /* match and buffer is exhausted */
+ LNET_MATCHMD_EXHAUSTED = (1 << 3),
+ /* match or drop */
+ LNET_MATCHMD_FINISH = (LNET_MATCHMD_OK | LNET_MATCHMD_DROP),
+};