#include #include #include #include #define SERVER_PORT 1234 #define my_printk(level, format, arg...) printk(level KBUILD_MODNAME \ " %s(), %d: " \ format, __func__, __LINE__, ## arg) #define LOG(format, arg...) my_printk(KERN_INFO, format, ## arg) static const char msg[] = "WHAZ UP SERVER?"; static struct rdma_cm_id *cm_ip; static struct rdma_cm_id *cm_ib; #define XX(a) case (a): return #a static inline const char *rdma_event_str(enum rdma_cm_event_type event) { switch (event) { XX(RDMA_CM_EVENT_ADDR_RESOLVED); XX(RDMA_CM_EVENT_ADDR_ERROR); XX(RDMA_CM_EVENT_ROUTE_RESOLVED); XX(RDMA_CM_EVENT_ROUTE_ERROR); XX(RDMA_CM_EVENT_CONNECT_REQUEST); XX(RDMA_CM_EVENT_CONNECT_RESPONSE); XX(RDMA_CM_EVENT_CONNECT_ERROR); XX(RDMA_CM_EVENT_UNREACHABLE); XX(RDMA_CM_EVENT_REJECTED); XX(RDMA_CM_EVENT_ESTABLISHED); XX(RDMA_CM_EVENT_DISCONNECTED); XX(RDMA_CM_EVENT_DEVICE_REMOVAL); XX(RDMA_CM_EVENT_MULTICAST_JOIN); XX(RDMA_CM_EVENT_MULTICAST_ERROR); XX(RDMA_CM_EVENT_ADDR_CHANGE); XX(RDMA_CM_EVENT_TIMEWAIT_EXIT); default: return "RDMA_CM_UNKNOWN"; } } static int rdma_cm_ev_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) { LOG("CM event %s, error %d\n", rdma_event_str(event->event), event->status); switch (event->event) { case RDMA_CM_EVENT_CONNECT_REQUEST: print_hex_dump(KERN_INFO, "private_data", DUMP_PREFIX_ADDRESS, 16, 1, event->param.conn.private_data, event->param.conn.private_data_len, true); return rdma_reject(cm_id, NULL, 0); return 0; default: return 0; } } static int ibtrs_srv_cm_init(struct rdma_cm_id **cm_id, struct sockaddr *addr, enum rdma_port_space ps) { int ret; *cm_id = rdma_create_id(rdma_cm_ev_handler, NULL, ps, IB_QPT_RC); if (IS_ERR(*cm_id)) { ret = PTR_ERR(*cm_id); goto err_out; } ret = rdma_bind_addr(*cm_id, addr); if (ret) goto err_cm; ret = rdma_listen(*cm_id, 64); if (ret) { LOG("rdma_listen() return %d\n", ret); goto err_cm; } switch (addr->sa_family) { case AF_INET: LOG("listening on port %u\n", ((struct sockaddr_in *)addr)->sin_port); break; case AF_INET6: LOG("listening on port %u\n", ((struct sockaddr_in6 *)addr)->sin6_port); break; case AF_IB: LOG("listening on service id 0x%016llx\n", be64_to_cpu(rdma_get_service_id(*cm_id, addr))); break; default: LOG("listening on address family %u\n", addr->sa_family); } return 0; err_cm: rdma_destroy_id(*cm_id); err_out: return ret; } static int gogo(void) { int ret; struct sockaddr_in6 sin = { .sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(SERVER_PORT), }; struct sockaddr_ib sib = { .sib_family = AF_IB, .sib_addr.sib_subnet_prefix = 0ULL, .sib_addr.sib_interface_id = 0ULL, .sib_sid = cpu_to_be64(RDMA_IB_IP_PS_IB | SERVER_PORT), .sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL), .sib_pkey = cpu_to_be16(0xffff), }; ret = ibtrs_srv_cm_init(&cm_ip, (struct sockaddr *)&sin, RDMA_PS_TCP); if (ret) return ret; return ibtrs_srv_cm_init(&cm_ib, (struct sockaddr *)&sib, RDMA_PS_IB); } static int __init in(void) { return gogo(); } static void __exit out(void) { rdma_disconnect(cm_ip); rdma_disconnect(cm_ib); rdma_destroy_id(cm_ip); rdma_destroy_id(cm_ib); return; } module_init(in); module_exit(out);