FYI - I don't track the ewg mail list, so I missed any discussion there.
See my detailed comments inline. I track the librdmacm against Roland's
libibverbs releases and upstream kernel features, rather than against OFED
features. As a result, I do think there's some functionality missing in both
the upstream libibverbs and kernel that need to be resolved. I tried to
identify these below.
The patch adds a new test application describing a usage of the
IBV_QPT_RAW_ETH
Where is IBV_QPT_RAW_ETH defined?
Roland's version of verbs.h only defines IBV_QPT_RC/UC/UD. I think we need to
get this defined there first, then figure out if anything new is needed for the
librdmacm.
Also, if I understand this correctly, a RAW_ETH QP exposes the contents of the
Ethernet frame and header to the user. This should be restricted to privileged
applications, and I'm guessing uverbs should verify that before allocating a
RAW_ETH QP for the user.
+struct cmatest {
+ struct rdma_event_channel *channel;
+ struct cmatest_node *nodes;
+ int conn_index;
+ int connects_left;
+
+ struct sockaddr_in6 dst_in;
+ struct sockaddr *dst_addr;
+ struct sockaddr_in6 src_in;
+ struct sockaddr *src_addr;
+ int fd[1024];
See comments below regarding the fd array usage.
+};
+
+static struct cmatest test;
+static int connections = 1;
+static int message_size = 100;
+static int message_count = 10;
+static int is_sender;
+static int unmapped_addr;
+static char *dst_addr;
+static char *src_addr;
+static enum rdma_port_space port_space = RDMA_PS_UDP;
+
+int vlan_flag;
+int vlan_ident;
+
+static int cq_len = 512;
+static int qp_len = 256;
+
+uint16_t IP_CRC(void *buf, int hdr_len)
+{
+ unsigned long sum = 0;
+ const uint16_t *ip1;
+
+ ip1 = (uint16_t *)buf;
+ while (hdr_len 1) {
+ sum += *ip1++;
+ if (sum 0x8000)
+ sum = (sum 0x) + (sum 16);
+ hdr_len -= 2;
+ }
+
+ while (sum 16)
+ sum = (sum 0x) + (sum 16);
+
+ return ~sum;
+}
+
+uint16_t udp_checksum(struct udphdr *udp_head,
+ int header_size,
+ int pay_load_size,
+ uint32_t src_addr,
+ uint32_t dest_addr,
+ unsigned char *payload)
+{
+ uint16_t *buf = (void *)udp_head;
+ uint16_t *ip_src = (void *)src_addr;
+ uint16_t *ip_dst = (void *)dest_addr;
+ uint32_t sum;
+ size_t len = header_size;
+
+ sum = 0;
+ while (len 1) {
+ sum += *buf++;
+ if (sum 0x8000)
+ sum = (sum 0x) + (sum 16);
+ len -= 2;
+ }
+
+ buf = (void *)payload;
+ len = pay_load_size;
+ while (len 1) {
+ sum += *buf++;
+ if (sum 0x8000)
+ sum = (sum 0x) + (sum 16);
+ len -= 2;
+ }
+
+ if (len 1)
+ sum += *((uint8_t *)buf);
+ sum += *(ip_src++);
+ sum += *ip_src;
+
+ sum += *(ip_dst++);
+ sum += *ip_dst;
+
+ sum += htons(IPPROTO_UDP);
+ len = (header_size + pay_load_size);
+ sum += htons(len);
+
+ while (sum 16)
+ sum = (sum 0x) + (sum 16);
+
+ return (uint16_t)(~sum);
+}
The above two calls look like candidates for common code - not part of
librdmacm, but common to some other library that provides functionality similar
to: ip_crc(), udp_checksum(), format_eth_hdr(), format_ip_hdr(),
format_udp_hdr(), etc. Even separating that functionality out into another
source file would make it easier for another application to pick up and reuse.
+static int create_message(struct cmatest_node *node)
+{
+ if (!message_size)
+ message_count = 0;
+
+ if (!message_count)
+ return 0;
+
+ node-mem = NULL;
+ posix_memalign((void *)node-mem, 4096,
+ (message_size + HEADER_LEN ) * sizeof(char));
+ if (node-mem == NULL) {
+ printf(failed message allocation\n);
+ return -1;
+ }
+
+ node-mr = ibv_reg_mr(node-pd, node-mem,
+ message_size + HEADER_LEN,
+ IBV_ACCESS_LOCAL_WRITE);
+ if (!node-mr) {
+ printf(failed to reg MR\n);
+ goto err;
+ }
+ return 0;
+err:
+ free(node-mem);
+ return -1;
+}
+
+static int verify_test_params(struct cmatest_node *node)
+{
+ struct ibv_port_attr port_attr;
+ int ret;
+
+ ret = ibv_query_port(node-cma_id-verbs, node-cma_id-port_num,
+ port_attr);
+ if (ret)
+ return ret;
+
+ printf(\nibv_query_port %x\n, node-cma_id-port_num);
+ if (message_count message_size (1