aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/iwpm_util.h
diff options
context:
space:
mode:
authorTatyana Nikolova <Tatyana.E.Nikolova@intel.com>2014-03-26 18:07:35 -0400
committerRoland Dreier <roland@purestorage.com>2014-06-10 13:11:45 -0400
commit30dc5e63d6a5ad24894b5512d10b228d73645a44 (patch)
treecbb54ab8d06b165dbbd83a243cf743c8b6ad64da /drivers/infiniband/core/iwpm_util.h
parentd6d211db37e75de2ddc3a4f979038c40df7cc79c (diff)
RDMA/core: Add support for iWARP Port Mapper user space service
This patch adds iWARP Port Mapper (IWPM) Version 2 support. The iWARP Port Mapper implementation is based on the port mapper specification section in the Sockets Direct Protocol paper - http://www.rdmaconsortium.org/home/draft-pinkerton-iwarp-sdp-v1.0.pdf Existing iWARP RDMA providers use the same IP address as the native TCP/IP stack when creating RDMA connections. They need a mechanism to claim the TCP ports used for RDMA connections to prevent TCP port collisions when other host applications use TCP ports. The iWARP Port Mapper provides a standard mechanism to accomplish this. Without this service it is possible for RDMA application to bind/listen on the same port which is already being used by native TCP host application. If that happens the incoming TCP connection data can be passed to the RDMA stack with error. The iWARP Port Mapper solution doesn't contain any changes to the existing network stack in the kernel space. All the changes are contained with the infiniband tree and also in user space. The iWARP Port Mapper service is implemented as a user space daemon process. Source for the IWPM service is located at http://git.openfabrics.org/git?p=~tnikolova/libiwpm-1.0.0/.git;a=summary The iWARP driver (port mapper client) sends to the IWPM service the local IP address and TCP port it has received from the RDMA application, when starting a connection. The IWPM service performs a socket bind from user space to get an available TCP port, called a mapped port, and communicates it back to the client. In that sense, the IWPM service is used to map the TCP port, which the RDMA application uses to any port available from the host TCP port space. The mapped ports are used in iWARP RDMA connections to avoid collisions with native TCP stack which is aware that these ports are taken. When an RDMA connection using a mapped port is terminated, the client notifies the IWPM service, which then releases the TCP port. The message exchange between the IWPM service and the iWARP drivers (between user space and kernel space) is implemented using netlink sockets. 1) Netlink interface functions are added: ibnl_unicast() and ibnl_mulitcast() for sending netlink messages to user space 2) The signature of the existing ibnl_put_msg() is changed to be more generic 3) Two netlink clients are added: RDMA_NL_NES, RDMA_NL_C4IW corresponding to the two iWarp drivers - nes and cxgb4 which use the IWPM service 4) Enums are added to enumerate the attributes in the netlink messages, which are exchanged between the user space IWPM service and the iWARP drivers Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com> Signed-off-by: Steve Wise <swise@opengridcomputing.com> Reviewed-by: PJ Waskiewicz <pj.waskiewicz@solidfire.com> [ Fold in range checking fixes and nlh_next removal as suggested by Dan Carpenter and Steve Wise. Fix sparse endianness in hash. - Roland ] Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core/iwpm_util.h')
-rw-r--r--drivers/infiniband/core/iwpm_util.h238
1 files changed, 238 insertions, 0 deletions
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h
new file mode 100644
index 000000000000..9777c869a140
--- /dev/null
+++ b/drivers/infiniband/core/iwpm_util.h
@@ -0,0 +1,238 @@
1/*
2 * Copyright (c) 2014 Intel Corporation. All rights reserved.
3 * Copyright (c) 2014 Chelsio, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#ifndef _IWPM_UTIL_H
34#define _IWPM_UTIL_H
35
36#include <linux/module.h>
37#include <linux/io.h>
38#include <linux/in.h>
39#include <linux/in6.h>
40#include <linux/spinlock.h>
41#include <linux/kernel.h>
42#include <linux/netdevice.h>
43#include <linux/delay.h>
44#include <linux/workqueue.h>
45#include <linux/mutex.h>
46#include <linux/jhash.h>
47#include <linux/kref.h>
48#include <net/netlink.h>
49#include <linux/errno.h>
50#include <rdma/iw_portmap.h>
51#include <rdma/rdma_netlink.h>
52
53
54#define IWPM_NL_RETRANS 3
55#define IWPM_NL_TIMEOUT (10*HZ)
56#define IWPM_MAPINFO_SKB_COUNT 20
57
58#define IWPM_PID_UNDEFINED -1
59#define IWPM_PID_UNAVAILABLE -2
60
61struct iwpm_nlmsg_request {
62 struct list_head inprocess_list;
63 __u32 nlmsg_seq;
64 void *req_buffer;
65 u8 nl_client;
66 u8 request_done;
67 u16 err_code;
68 wait_queue_head_t waitq;
69 struct kref kref;
70};
71
72struct iwpm_mapping_info {
73 struct hlist_node hlist_node;
74 struct sockaddr_storage local_sockaddr;
75 struct sockaddr_storage mapped_sockaddr;
76 u8 nl_client;
77};
78
79struct iwpm_admin_data {
80 atomic_t refcount;
81 atomic_t nlmsg_seq;
82 int client_list[RDMA_NL_NUM_CLIENTS];
83 int reg_list[RDMA_NL_NUM_CLIENTS];
84};
85
86/**
87 * iwpm_get_nlmsg_request - Allocate and initialize netlink message request
88 * @nlmsg_seq: Sequence number of the netlink message
89 * @nl_client: The index of the netlink client
90 * @gfp: Indicates how the memory for the request should be allocated
91 *
92 * Returns the newly allocated netlink request object if successful,
93 * otherwise returns NULL
94 */
95struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
96 u8 nl_client, gfp_t gfp);
97
98/**
99 * iwpm_free_nlmsg_request - Deallocate netlink message request
100 * @kref: Holds reference of netlink message request
101 */
102void iwpm_free_nlmsg_request(struct kref *kref);
103
104/**
105 * iwpm_find_nlmsg_request - Find netlink message request in the request list
106 * @echo_seq: Sequence number of the netlink request to find
107 *
108 * Returns the found netlink message request,
109 * if not found, returns NULL
110 */
111struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq);
112
113/**
114 * iwpm_wait_complete_req - Block while servicing the netlink request
115 * @nlmsg_request: Netlink message request to service
116 *
117 * Wakes up, after the request is completed or expired
118 * Returns 0 if the request is complete without error
119 */
120int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request);
121
122/**
123 * iwpm_get_nlmsg_seq - Get the sequence number for a netlink
124 * message to send to the port mapper
125 *
126 * Returns the sequence number for the netlink message.
127 */
128int iwpm_get_nlmsg_seq(void);
129
130/**
131 * iwpm_valid_client - Check if the port mapper client is valid
132 * @nl_client: The index of the netlink client
133 *
134 * Valid clients need to call iwpm_init() before using
135 * the port mapper
136 */
137int iwpm_valid_client(u8 nl_client);
138
139/**
140 * iwpm_set_valid - Set the port mapper client to valid or not
141 * @nl_client: The index of the netlink client
142 * @valid: 1 if valid or 0 if invalid
143 */
144void iwpm_set_valid(u8 nl_client, int valid);
145
146/**
147 * iwpm_registered_client - Check if the port mapper client is registered
148 * @nl_client: The index of the netlink client
149 *
150 * Call iwpm_register_pid() to register a client
151 */
152int iwpm_registered_client(u8 nl_client);
153
154/**
155 * iwpm_set_registered - Set the port mapper client to registered or not
156 * @nl_client: The index of the netlink client
157 * @reg: 1 if registered or 0 if not
158 */
159void iwpm_set_registered(u8 nl_client, int reg);
160
161/**
162 * iwpm_send_mapinfo - Send local and mapped IPv4/IPv6 address info of
163 * a client to the user space port mapper
164 * @nl_client: The index of the netlink client
165 * @iwpm_pid: The pid of the user space port mapper
166 *
167 * If successful, returns the number of sent mapping info records
168 */
169int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid);
170
171/**
172 * iwpm_mapinfo_available - Check if any mapping info records is available
173 * in the hash table
174 *
175 * Returns 1 if mapping information is available, otherwise returns 0
176 */
177int iwpm_mapinfo_available(void);
178
179/**
180 * iwpm_compare_sockaddr - Compare two sockaddr storage structs
181 *
182 * Returns 0 if they are holding the same ip/tcp address info,
183 * otherwise returns 1
184 */
185int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr,
186 struct sockaddr_storage *b_sockaddr);
187
188/**
189 * iwpm_validate_nlmsg_attr - Check for NULL netlink attributes
190 * @nltb: Holds address of each netlink message attributes
191 * @nla_count: Number of netlink message attributes
192 *
193 * Returns error if any of the nla_count attributes is NULL
194 */
195static inline int iwpm_validate_nlmsg_attr(struct nlattr *nltb[],
196 int nla_count)
197{
198 int i;
199 for (i = 1; i < nla_count; i++) {
200 if (!nltb[i])
201 return -EINVAL;
202 }
203 return 0;
204}
205
206/**
207 * iwpm_create_nlmsg - Allocate skb and form a netlink message
208 * @nl_op: Netlink message opcode
209 * @nlh: Holds address of the netlink message header in skb
210 * @nl_client: The index of the netlink client
211 *
212 * Returns the newly allcated skb, or NULL if the tailroom of the skb
213 * is insufficient to store the message header and payload
214 */
215struct sk_buff *iwpm_create_nlmsg(u32 nl_op, struct nlmsghdr **nlh,
216 int nl_client);
217
218/**
219 * iwpm_parse_nlmsg - Validate and parse the received netlink message
220 * @cb: Netlink callback structure
221 * @policy_max: Maximum attribute type to be expected
222 * @nlmsg_policy: Validation policy
223 * @nltb: Array to store policy_max parsed elements
224 * @msg_type: Type of netlink message
225 *
226 * Returns 0 on success or a negative error code
227 */
228int iwpm_parse_nlmsg(struct netlink_callback *cb, int policy_max,
229 const struct nla_policy *nlmsg_policy,
230 struct nlattr *nltb[], const char *msg_type);
231
232/**
233 * iwpm_print_sockaddr - Print IPv4/IPv6 address and TCP port
234 * @sockaddr: Socket address to print
235 * @msg: Message to print
236 */
237void iwpm_print_sockaddr(struct sockaddr_storage *sockaddr, char *msg);
238#endif