rdma: add rdma_create_v4 that handles flags properly
[vpp.git] / src / plugins / rdma / api.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2019 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20
21 #include <rdma/rdma.h>
22
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25
26 /* define message IDs */
27 #include <rdma/rdma.api_enum.h>
28 #include <rdma/rdma.api_types.h>
29
30 #define REPLY_MSG_ID_BASE (rm->msg_id_base)
31 #include <vlibapi/api_helper_macros.h>
32
33 static rdma_mode_t
34 rdma_api_mode (vl_api_rdma_mode_t mode)
35 {
36   switch (mode)
37     {
38     case RDMA_API_MODE_AUTO:
39       return RDMA_MODE_AUTO;
40     case RDMA_API_MODE_IBV:
41       return RDMA_MODE_IBV;
42     case RDMA_API_MODE_DV:
43       return RDMA_MODE_DV;
44     }
45   /* Fail the debug build. Useful for investigating endian issues. */
46   ASSERT (0);
47   return RDMA_MODE_AUTO;
48 }
49
50 static rdma_rss4_t
51 rdma_api_rss4 (const vl_api_rdma_rss4_t rss4)
52 {
53   switch (rss4)
54     {
55     case RDMA_API_RSS4_AUTO:
56       return RDMA_RSS4_AUTO;
57     case RDMA_API_RSS4_IP:
58       return RDMA_RSS4_IP;
59     case RDMA_API_RSS4_IP_UDP:
60       return RDMA_RSS4_IP_UDP;
61     case RDMA_API_RSS4_IP_TCP:
62       return RDMA_RSS4_IP_TCP;
63     }
64   return RDMA_RSS4_AUTO;
65 }
66
67 static rdma_rss6_t
68 rdma_api_rss6 (const vl_api_rdma_rss6_t rss6)
69 {
70   switch (rss6)
71     {
72     case RDMA_API_RSS6_AUTO:
73       return RDMA_RSS6_AUTO;
74     case RDMA_API_RSS6_IP:
75       return RDMA_RSS6_IP;
76     case RDMA_API_RSS6_IP_UDP:
77       return RDMA_RSS6_IP_UDP;
78     case RDMA_API_RSS6_IP_TCP:
79       return RDMA_RSS6_IP_TCP;
80     }
81   return RDMA_RSS6_AUTO;
82 }
83
84 static void
85 vl_api_rdma_create_v4_t_handler (vl_api_rdma_create_v4_t *mp)
86 {
87   vlib_main_t *vm = vlib_get_main ();
88   rdma_main_t *rm = &rdma_main;
89   vl_api_rdma_create_v4_reply_t *rmp;
90   rdma_create_if_args_t args;
91   int rv;
92
93   clib_memset (&args, 0, sizeof (rdma_create_if_args_t));
94
95   args.ifname = mp->host_if;
96   args.name = mp->name;
97   args.rxq_num = mp->rxq_num;
98   args.rxq_size = mp->rxq_size;
99   args.txq_size = mp->txq_size;
100   args.mode = rdma_api_mode (mp->mode);
101   args.disable_striding_rq = 0;
102   args.no_multi_seg = mp->no_multi_seg;
103   args.max_pktlen = mp->max_pktlen;
104   args.rss4 = rdma_api_rss4 (mp->rss4);
105   args.rss6 = rdma_api_rss6 (mp->rss6);
106   rdma_create_if (vm, &args);
107   rv = args.rv;
108
109   REPLY_MACRO2_END (VL_API_RDMA_CREATE_V4_REPLY,
110                     ({ rmp->sw_if_index = args.sw_if_index; }));
111 }
112
113 static void
114 vl_api_rdma_create_v3_t_handler (vl_api_rdma_create_v3_t *mp)
115 {
116   vlib_main_t *vm = vlib_get_main ();
117   rdma_main_t *rm = &rdma_main;
118   vl_api_rdma_create_v3_reply_t *rmp;
119   rdma_create_if_args_t args;
120   int rv;
121
122   clib_memset (&args, 0, sizeof (rdma_create_if_args_t));
123
124   args.ifname = mp->host_if;
125   args.name = mp->name;
126   args.rxq_num = ntohs (mp->rxq_num);
127   args.rxq_size = ntohs (mp->rxq_size);
128   args.txq_size = ntohs (mp->txq_size);
129   args.mode = rdma_api_mode (mp->mode);
130   args.disable_striding_rq = 0;
131   args.no_multi_seg = mp->no_multi_seg;
132   args.max_pktlen = ntohs (mp->max_pktlen);
133   args.rss4 = rdma_api_rss4 (mp->rss4);
134   args.rss6 = rdma_api_rss6 (mp->rss6);
135   rdma_create_if (vm, &args);
136   rv = args.rv;
137
138   REPLY_MACRO2 (VL_API_RDMA_CREATE_V3_REPLY,
139                 ({ rmp->sw_if_index = ntohl (args.sw_if_index); }));
140 }
141
142 static void
143 vl_api_rdma_create_v2_t_handler (vl_api_rdma_create_v2_t * mp)
144 {
145   vlib_main_t *vm = vlib_get_main ();
146   rdma_main_t *rm = &rdma_main;
147   vl_api_rdma_create_v2_reply_t *rmp;
148   rdma_create_if_args_t args;
149   int rv;
150
151   clib_memset (&args, 0, sizeof (rdma_create_if_args_t));
152
153   args.ifname = mp->host_if;
154   args.name = mp->name;
155   args.rxq_num = ntohs (mp->rxq_num);
156   args.rxq_size = ntohs (mp->rxq_size);
157   args.txq_size = ntohs (mp->txq_size);
158   args.mode = rdma_api_mode (mp->mode);
159   args.disable_striding_rq = 0;
160   args.no_multi_seg = mp->no_multi_seg;
161   args.max_pktlen = ntohs (mp->max_pktlen);
162   rdma_create_if (vm, &args);
163   rv = args.rv;
164
165   /* *INDENT-OFF* */
166   REPLY_MACRO2 (VL_API_RDMA_CREATE_V2_REPLY,
167                 ({ rmp->sw_if_index = ntohl (args.sw_if_index); }));
168   /* *INDENT-ON* */
169 }
170
171 static void
172 vl_api_rdma_create_t_handler (vl_api_rdma_create_t * mp)
173 {
174   vlib_main_t *vm = vlib_get_main ();
175   rdma_main_t *rm = &rdma_main;
176   vl_api_rdma_create_reply_t *rmp;
177   rdma_create_if_args_t args;
178   int rv;
179
180   clib_memset (&args, 0, sizeof (rdma_create_if_args_t));
181
182   args.ifname = mp->host_if;
183   args.name = mp->name;
184   args.rxq_num = ntohs (mp->rxq_num);
185   args.rxq_size = ntohs (mp->rxq_size);
186   args.txq_size = ntohs (mp->txq_size);
187   args.mode = rdma_api_mode (mp->mode);
188   args.disable_striding_rq = 0;
189   args.no_multi_seg = 1;
190   args.max_pktlen = 0;
191
192   rdma_create_if (vm, &args);
193   rv = args.rv;
194
195   /* *INDENT-OFF* */
196   REPLY_MACRO2 (VL_API_RDMA_CREATE_REPLY,
197                 ({ rmp->sw_if_index = ntohl (args.sw_if_index); }));
198   /* *INDENT-ON* */
199 }
200
201 static void
202 vl_api_rdma_delete_t_handler (vl_api_rdma_delete_t * mp)
203 {
204   vlib_main_t *vm = vlib_get_main ();
205   vnet_main_t *vnm = vnet_get_main ();
206   rdma_main_t *rm = &rdma_main;
207   vl_api_rdma_delete_reply_t *rmp;
208   rdma_device_t *rd;
209   vnet_hw_interface_t *hw;
210   int rv = 0;
211
212   hw =
213     vnet_get_sup_hw_interface_api_visible_or_null (vnm,
214                                                    htonl (mp->sw_if_index));
215   if (hw == NULL || rdma_device_class.index != hw->dev_class_index)
216     {
217       rv = VNET_API_ERROR_INVALID_INTERFACE;
218       goto reply;
219     }
220
221   rd = pool_elt_at_index (rm->devices, hw->dev_instance);
222
223   rdma_delete_if (vm, rd);
224
225 reply:
226   REPLY_MACRO (VL_API_RDMA_DELETE_REPLY);
227 }
228
229 /* set tup the API message handling tables */
230 #include <rdma/rdma.api.c>
231 static clib_error_t *
232 rdma_plugin_api_hookup (vlib_main_t * vm)
233 {
234   rdma_main_t *rm = &rdma_main;
235
236   /* ask for a correctly-sized block of API message decode slots */
237   rm->msg_id_base = setup_message_id_table ();
238   return 0;
239 }
240
241 VLIB_API_INIT_FUNCTION (rdma_plugin_api_hookup);
242
243 /*
244  * fd.io coding-style-patch-verification: ON
245  *
246  * Local Variables:
247  * eval: (c-set-style "gnu")
248  * End:
249  */