#include <infiniband/verbs.h> int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr);
The argument wr is an ibv_send_wr struct, as defined in <infiniband/verbs.h>.
struct ibv_send_wr {
uint64_t                wr_id;                  /* User defined WR ID */
struct ibv_send_wr     *next;                   /* Pointer to next WR in list, NULL if last WR */
struct ibv_sge         *sg_list;                /* Pointer to the s/g array */
int                     num_sge;                /* Size of the s/g array */
enum ibv_wr_opcode      opcode;                 /* Operation type */
unsigned int            send_flags;             /* Flags of the WR properties */
union {
__be32                  imm_data;               /* Immediate data (in network byte order) */
uint32_t                invalidate_rkey;        /* Remote rkey to invalidate */
};
union {
struct {
uint64_t        remote_addr;    /* Start address of remote memory buffer */
uint32_t        rkey;           /* Key of the remote Memory Region */
} rdma;
struct {
uint64_t        remote_addr;    /* Start address of remote memory buffer */ 
uint64_t        compare_add;    /* Compare operand */
uint64_t        swap;           /* Swap operand */
uint32_t        rkey;           /* Key of the remote Memory Region */
} atomic;
struct {
struct ibv_ah  *ah;             /* Address handle (AH) for the remote node address */
uint32_t        remote_qpn;     /* QP number of the destination QP */
uint32_t        remote_qkey;    /* Q_Key number of the destination QP */
} ud;
} wr;
union {
struct {
uint32_t remote_srqn;            /* Number of the remote SRQ */
} xrc;
} qp_type;
union {
struct {
struct ibv_mw            *mw;             /* Memory window (MW) of type 2 to bind */
uint32_t                 rkey;            /* The desired new rkey of the MW */
struct ibv_mw_bind_info  bind_info;       /* MW additional bind information */
} bind_mw;
struct {
void                    *hdr;   /* Pointer address of inline header */
uint16_t                hdr_sz; /* Inline header size */
uint16_t                mss;    /* Maximum segment size for each TSO fragment */
} tso;
};
};
struct ibv_mw_bind_info {
struct ibv_mr            *mr;             /* The Memory region (MR) to bind the MW to */
uint64_t                 addr;           /* The address the MW should start at */
uint64_t                 length;          /* The length (in bytes) the MW should span */
unsigned int             mw_access_flags; /* Access flags to the MW. Use ibv_access_flags */
};
struct ibv_sge {
uint64_t                addr;                   /* Start address of the local memory buffer or number of bytes from the
                                                   start of the MR for MRs which are IBV_ZERO_BASED */
uint32_t                length;                 /* Length of the buffer */
uint32_t                lkey;                   /* Key of the local Memory Region */
};
Each QP Transport Service Type supports a specific set of opcodes, as shown in the following table:
OPCODE | IBV_QPT_UD | IBV_QPT_UC | IBV_QPT_RC | IBV_QPT_XRC_SEND | IBV_QPT_RAW_PACKET ----------------------------+------------+------------+------------+------------------+-------------------- IBV_WR_SEND | X | X | X | X | X IBV_WR_SEND_WITH_IMM | X | X | X | X | IBV_WR_RDMA_WRITE | | X | X | X | IBV_WR_RDMA_WRITE_WITH_IMM | | X | X | X | IBV_WR_RDMA_READ | | | X | X | IBV_WR_ATOMIC_CMP_AND_SWP | | | X | X | IBV_WR_ATOMIC_FETCH_AND_ADD | | | X | X | IBV_WR_LOCAL_INV | | X | X | X | IBV_WR_BIND_MW | | X | X | X | IBV_WR_SEND_WITH_INV | | X | X | X | IBV_WR_TSO | X | | | | X
The attribute send_flags describes the properties of the WR. It is either 0 or the bitwise OR of one or more of the following flags:
The buffers used by a WR can only be safely reused after WR the request is fully executed and a work completion has been retrieved from the corresponding completion queue (CQ). However, if the IBV_SEND_INLINE flag was set, the buffer can be reused immediately after the call returns.
IBV_WR_DRIVER1 is an opcode that should be used to issue a specific driver operation.