History

IB/uverbs: Add flow_action create and destroy verbs

A verbs application may receive and transmits packets using a data path pipeline. Sometimes, the first stage in the receive pipeline or the last stage in the transmit pipeline involves transforming a packet, either in order to make it easier for later stages to process it or to prepare it for transmission over the wire. Such transformation could be stripping/encapsulating the packet (i.e. vxlan), decrypting/encrypting it (i.e. ipsec), altering headers, doing some complex FPGA changes, etc. Some hardware could do such transformations without software data path intervention at all. The flow steering API supports steering a packet (either to a QP or dropping it) and some simple packet immutable actions (i.e. tagging a packet). Complex actions, that may change the packet, could bloat the flow steering API extensively. Sometimes the same action should be applied to several flows. In this case, it's easier to bind several flows to the same action and modify it than change all matching flows. Introducing a new flow_action object that abstracts any packet transformation (out of a standard and well defined set of actions). This flow_action object could be tied to a flow steering rule via a new specification. Currently, we support esp flow_action, which encrypts or decrypts a packet according to the given parameters. However, we present a flexible schema that could be used to other transformation actions tied to flow rules.

Matan Barak committed 8 years ago

Commit 2eb9bea1 parent 766d8557 files · +506 −2Browse files

Unified · Split

7 files
  1. drivers/infiniband/core/Makefile +2 −1
  2. drivers/infiniband/core/uverbs.h +4 −0
  3. drivers/infiniband/core/uverbs_std_types.c +9 −1
  4. drivers/infiniband/core/uverbs_std_types_flow_action.c +348 −0
  5. include/rdma/ib_verbs.h +65 −0
  6. include/uapi/rdma/ib_user_ioctl_cmds.h +19 −0
  7. include/uapi/rdma/ib_user_ioctl_verbs.h +59 −0
drivers/infiniband/core/Makefile+2−1
@@ -34,4 +34,5 @@ ib_ucm-y := ucm.o · 33 unmodified lines
3434
3535 ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \
3636 rdma_core.o uverbs_std_types.o uverbs_ioctl.o \
37− uverbs_ioctl_merge.o uverbs_std_types_cq.o
37+ uverbs_ioctl_merge.o uverbs_std_types_cq.o \
38+ uverbs_std_types_flow_action.o
drivers/infiniband/core/uverbs.h+4−0
@@ -234,6 +234,9 @@ void create_udata(struct uverbs_attr_bundle *ctx, struct ib_udata *udata); · 233 unmodified lines
234234 extern const struct uverbs_attr_def uverbs_uhw_compat_in;
235235 extern const struct uverbs_attr_def uverbs_uhw_compat_out;
236236 long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
237+int uverbs_destroy_def_handler(struct ib_device *ib_dev,
238+ struct ib_uverbs_file *file,
239+ struct uverbs_attr_bundle *attrs);
237240
238241 struct ib_uverbs_flow_spec {
239242 union {
@@ -273,6 +276,7 @@ extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_FLOW); · 33 unmodified lines
273276 extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_WQ);
274277 extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_RWQ_IND_TBL);
275278 extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_XRCD);
279+extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_FLOW_ACTION);
276280
277281 #define IB_UVERBS_DECLARE_CMD(name) \
278282 ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \
drivers/infiniband/core/uverbs_std_types.c+9−1
@@ -191,6 +191,13 @@ static int uverbs_hot_unplug_completion_event_file(struct ib_uobject_file *uobj_ · 190 unmodified lines
191191 return 0;
192192 };
193193
194+int uverbs_destroy_def_handler(struct ib_device *ib_dev,
195+ struct ib_uverbs_file *file,
196+ struct uverbs_attr_bundle *attrs)
197+{
198+ return 0;
199+}
200+
194201 /*
195202 * This spec is used in order to pass information to the hardware driver in a
196203 * legacy way. Every verb that could get driver specific data should get this
@@ -293,7 +300,8 @@ static DECLARE_UVERBS_OBJECT_TREE(uverbs_default_objects, · 96 unmodified lines
293300 &UVERBS_OBJECT(UVERBS_OBJECT_FLOW),
294301 &UVERBS_OBJECT(UVERBS_OBJECT_WQ),
295302 &UVERBS_OBJECT(UVERBS_OBJECT_RWQ_IND_TBL),
296− &UVERBS_OBJECT(UVERBS_OBJECT_XRCD));
303+ &UVERBS_OBJECT(UVERBS_OBJECT_XRCD),
304+ &UVERBS_OBJECT(UVERBS_OBJECT_FLOW_ACTION));
297305
298306 const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
299307 {
drivers/infiniband/core/uverbs_std_types_flow_action.c+348−0
@@ -0,0 +1,348 @@
1+/*
2+ * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
3+ *
4+ * This software is available to you under a choice of one of two
5+ * licenses. You may choose to be licensed under the terms of the GNU
6+ * General Public License (GPL) Version 2, available from the file
7+ * COPYING in the main directory of this source tree, or the
8+ * OpenIB.org BSD license below:
9+ *
10+ * Redistribution and use in source and binary forms, with or
11+ * without modification, are permitted provided that the following
12+ * conditions are met:
13+ *
14+ * - Redistributions of source code must retain the above
15+ * copyright notice, this list of conditions and the following
16+ * disclaimer.
17+ *
18+ * - Redistributions in binary form must reproduce the above
19+ * copyright notice, this list of conditions and the following
20+ * disclaimer in the documentation and/or other materials
21+ * provided with the distribution.
22+ *
23+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30+ * SOFTWARE.
31+ */
32+
33+#include "uverbs.h"
34+#include <rdma/uverbs_std_types.h>
35+
36+static int uverbs_free_flow_action(struct ib_uobject *uobject,
37+ enum rdma_remove_reason why)
38+{
39+ struct ib_flow_action *action = uobject->object;
40+
41+ if (why == RDMA_REMOVE_DESTROY &&
42+ atomic_read(&action->usecnt))
43+ return -EBUSY;
44+
45+ return action->device->destroy_flow_action(action);
46+}
47+
48+static u64 esp_flags_uverbs_to_verbs(struct uverbs_attr_bundle *attrs,
49+ u32 flags)
50+{
51+ u64 verbs_flags = flags;
52+
53+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ESN))
54+ verbs_flags |= IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED;
55+
56+ return verbs_flags;
57+};
58+
59+static int validate_flow_action_esp_keymat_aes_gcm(struct ib_flow_action_attrs_esp_keymats *keymat)
60+{
61+ struct ib_uverbs_flow_action_esp_keymat_aes_gcm *aes_gcm =
62+ &keymat->keymat.aes_gcm;
63+
64+ if (aes_gcm->iv_algo > IB_UVERBS_FLOW_ACTION_IV_ALGO_SEQ)
65+ return -EOPNOTSUPP;
66+
67+ if (aes_gcm->key_len != 32 &&
68+ aes_gcm->key_len != 24 &&
69+ aes_gcm->key_len != 16)
70+ return -EINVAL;
71+
72+ if (aes_gcm->icv_len != 16 &&
73+ aes_gcm->icv_len != 8 &&
74+ aes_gcm->icv_len != 12)
75+ return -EINVAL;
76+
77+ return 0;
78+}
79+
80+static int (* const flow_action_esp_keymat_validate[])(struct ib_flow_action_attrs_esp_keymats *keymat) = {
81+ [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = validate_flow_action_esp_keymat_aes_gcm,
82+};
83+
84+static int parse_esp_ip(enum ib_flow_spec_type proto,
85+ const void __user *val_ptr,
86+ size_t len, union ib_flow_spec *out)
87+{
88+ int ret;
89+ const struct ib_uverbs_flow_ipv4_filter ipv4 = {
90+ .src_ip = cpu_to_be32(0xffffffffUL),
91+ .dst_ip = cpu_to_be32(0xffffffffUL),
92+ .proto = 0xff,
93+ .tos = 0xff,
94+ .ttl = 0xff,
95+ .flags = 0xff,
96+ };
97+ const struct ib_uverbs_flow_ipv6_filter ipv6 = {
98+ .src_ip = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
100+ .dst_ip = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
102+ .flow_label = cpu_to_be32(0xffffffffUL),
103+ .next_hdr = 0xff,
104+ .traffic_class = 0xff,
105+ .hop_limit = 0xff,
106+ };
107+ union {
108+ struct ib_uverbs_flow_ipv4_filter ipv4;
109+ struct ib_uverbs_flow_ipv6_filter ipv6;
110+ } user_val = {};
111+ const void *user_pmask;
112+ size_t val_len;
113+
114+ /* If the flow IPv4/IPv6 flow specifications are extended, the mask
115+ * should be changed as well.
116+ */
117+ BUILD_BUG_ON(offsetof(struct ib_uverbs_flow_ipv4_filter, flags) +
118+ sizeof(ipv4.flags) != sizeof(ipv4));
119+ BUILD_BUG_ON(offsetof(struct ib_uverbs_flow_ipv6_filter, reserved) +
120+ sizeof(ipv6.reserved) != sizeof(ipv6));
121+
122+ switch (proto) {
123+ case IB_FLOW_SPEC_IPV4:
124+ if (len > sizeof(user_val.ipv4) &&
125+ !ib_is_buffer_cleared(val_ptr + sizeof(user_val.ipv4),
126+ len - sizeof(user_val.ipv4)))
127+ return -EOPNOTSUPP;
128+
129+ val_len = min_t(size_t, len, sizeof(user_val.ipv4));
130+ ret = copy_from_user(&user_val.ipv4, val_ptr,
131+ val_len);
132+ if (ret)
133+ return -EFAULT;
134+
135+ user_pmask = &ipv4;
136+ break;
137+ case IB_FLOW_SPEC_IPV6:
138+ if (len > sizeof(user_val.ipv6) &&
139+ !ib_is_buffer_cleared(val_ptr + sizeof(user_val.ipv6),
140+ len - sizeof(user_val.ipv6)))
141+ return -EOPNOTSUPP;
142+
143+ val_len = min_t(size_t, len, sizeof(user_val.ipv6));
144+ ret = copy_from_user(&user_val.ipv6, val_ptr,
145+ val_len);
146+ if (ret)
147+ return -EFAULT;
148+
149+ user_pmask = &ipv6;
150+ break;
151+ default:
152+ return -EOPNOTSUPP;
153+ }
154+
155+ return ib_uverbs_kern_spec_to_ib_spec_filter(proto, user_pmask,
156+ &user_val,
157+ val_len, out);
158+}
159+
160+static int flow_action_esp_get_encap(struct ib_flow_spec_list *out,
161+ struct uverbs_attr_bundle *attrs)
162+{
163+ struct ib_uverbs_flow_action_esp_encap uverbs_encap;
164+ int ret;
165+
166+ ret = uverbs_copy_from(&uverbs_encap, attrs,
167+ UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP);
168+ if (ret)
169+ return ret;
170+
171+ /* We currently support only one encap */
172+ if (uverbs_encap.next_ptr)
173+ return -EOPNOTSUPP;
174+
175+ if (uverbs_encap.type != IB_FLOW_SPEC_IPV4 &&
176+ uverbs_encap.type != IB_FLOW_SPEC_IPV6)
177+ return -EOPNOTSUPP;
178+
179+ return parse_esp_ip(uverbs_encap.type,
180+ u64_to_user_ptr(uverbs_encap.val_ptr),
181+ uverbs_encap.len,
182+ &out->spec);
183+}
184+
185+struct ib_flow_action_esp_attr {
186+ struct ib_flow_action_attrs_esp hdr;
187+ struct ib_flow_action_attrs_esp_keymats keymat;
188+ struct ib_flow_action_attrs_esp_replays replay;
189+ /* We currently support only one spec */
190+ struct ib_flow_spec_list encap;
191+};
192+
193+#define ESP_LAST_SUPPORTED_FLAG IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW
194+static int parse_flow_action_esp(struct ib_device *ib_dev,
195+ struct ib_uverbs_file *file,
196+ struct uverbs_attr_bundle *attrs,
197+ struct ib_flow_action_esp_attr *esp_attr)
198+{
199+ struct ib_uverbs_flow_action_esp uverbs_esp = {};
200+ int ret;
201+
202+ /* Optional param, if it doesn't exist, we get -ENOENT and skip it */
203+ ret = uverbs_copy_from(&esp_attr->hdr.esn, attrs,
204+ UVERBS_ATTR_FLOW_ACTION_ESP_ESN);
205+ if (IS_UVERBS_COPY_ERR(ret))
206+ return ret;
207+
208+ /* This can be called from FLOW_ACTION_ESP_MODIFY where
209+ * UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS is optional
210+ */
211+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS)) {
212+ ret = uverbs_copy_from_or_zero(&uverbs_esp, attrs,
213+ UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS);
214+ if (ret)
215+ return ret;
216+
217+ if (uverbs_esp.flags & ~((ESP_LAST_SUPPORTED_FLAG << 1) - 1))
218+ return -EOPNOTSUPP;
219+
220+ esp_attr->hdr.spi = uverbs_esp.spi;
221+ esp_attr->hdr.seq = uverbs_esp.seq;
222+ esp_attr->hdr.tfc_pad = uverbs_esp.tfc_pad;
223+ esp_attr->hdr.hard_limit_pkts = uverbs_esp.hard_limit_pkts;
224+ }
225+ esp_attr->hdr.flags = esp_flags_uverbs_to_verbs(attrs, uverbs_esp.flags);
226+
227+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT)) {
228+ esp_attr->keymat.protocol =
229+ uverbs_attr_get_enum_id(attrs,
230+ UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT);
231+ ret = uverbs_copy_from_or_zero(&esp_attr->keymat.keymat,
232+ attrs,
233+ UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT);
234+ if (ret)
235+ return ret;
236+
237+ ret = flow_action_esp_keymat_validate[esp_attr->keymat.protocol](&esp_attr->keymat);
238+ if (ret)
239+ return ret;
240+
241+ esp_attr->hdr.keymat = &esp_attr->keymat;
242+ }
243+
244+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY)) {
245+ esp_attr->replay.protocol =
246+ uverbs_attr_get_enum_id(attrs,
247+ UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY);
248+
249+ ret = uverbs_copy_from_or_zero(&esp_attr->replay.replay,
250+ attrs,
251+ UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY);
252+ if (ret)
253+ return ret;
254+
255+ esp_attr->hdr.replay = &esp_attr->replay;
256+ }
257+
258+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP)) {
259+ ret = flow_action_esp_get_encap(&esp_attr->encap, attrs);
260+ if (ret)
261+ return ret;
262+
263+ esp_attr->hdr.encap = &esp_attr->encap;
264+ }
265+
266+ return 0;
267+}
268+
269+static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE)(struct ib_device *ib_dev,
270+ struct ib_uverbs_file *file,
271+ struct uverbs_attr_bundle *attrs)
272+{
273+ int ret;
274+ struct ib_uobject *uobj;
275+ struct ib_flow_action *action;
276+ struct ib_flow_action_esp_attr esp_attr = {};
277+
278+ if (!ib_dev->create_flow_action_esp)
279+ return -EOPNOTSUPP;
280+
281+ ret = parse_flow_action_esp(ib_dev, file, attrs, &esp_attr);
282+ if (ret)
283+ return ret;
284+
285+ /* No need to check as this attribute is marked as MANDATORY */
286+ uobj = uverbs_attr_get(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE)->obj_attr.uobject;
287+ action = ib_dev->create_flow_action_esp(ib_dev, &esp_attr.hdr, attrs);
288+ if (IS_ERR(action))
289+ return PTR_ERR(action);
290+
291+ atomic_set(&action->usecnt, 0);
292+ action->device = ib_dev;
293+ action->type = IB_FLOW_ACTION_ESP;
294+ action->uobject = uobj;
295+ uobj->object = action;
296+
297+ return 0;
298+}
299+
300+static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = {
301+ [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = {
302+ .ptr = {
303+ .type = UVERBS_ATTR_TYPE_PTR_IN,
304+ UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm),
305+ .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
306+ },
307+ },
308+};
309+
310+static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
311+ [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
312+ .ptr = {
313+ .type = UVERBS_ATTR_TYPE_PTR_IN,
314+ UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size),
315+ .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
316+ }
317+ },
318+};
319+
320+static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE,
321+ &UVERBS_ATTR_IDR(UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE, UVERBS_OBJECT_FLOW_ACTION,
322+ UVERBS_ACCESS_NEW,
323+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
324+ &UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS,
325+ UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp, hard_limit_pkts),
326+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
327+ UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)),
328+ &UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ESN, UVERBS_ATTR_TYPE(__u32)),
329+ &UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT,
330+ uverbs_flow_action_esp_keymat,
331+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
332+ &UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY,
333+ uverbs_flow_action_esp_replay),
334+ &UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP,
335+ UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_encap, type)));
336+
337+static DECLARE_UVERBS_NAMED_METHOD_WITH_HANDLER(UVERBS_METHOD_FLOW_ACTION_DESTROY,
338+ uverbs_destroy_def_handler,
339+ &UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE,
340+ UVERBS_OBJECT_FLOW_ACTION,
341+ UVERBS_ACCESS_DESTROY,
342+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
343+
344+DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_FLOW_ACTION,
345+ &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_flow_action),
346+ &UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE),
347+ &UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_DESTROY));
348+
include/rdma/ib_verbs.h+65−0
@@ -65,6 +65,7 @@ · 64 unmodified lines
6565 #include <uapi/rdma/ib_user_verbs.h>
6666 #include <rdma/restrack.h>
6767 #include <uapi/rdma/rdma_user_ioctl.h>
68+#include <uapi/rdma/ib_user_ioctl_verbs.h>
6869
6970 #define IB_FW_VERSION_NAME_MAX ETHTOOL_FWVERS_LEN
7071
@@ -2001,6 +2002,63 @@ struct ib_flow { · 1930 unmodified lines
20012002 struct ib_uobject *uobject;
20022003 };
20032004
2005+enum ib_flow_action_type {
2006+ IB_FLOW_ACTION_UNSPECIFIED,
2007+ IB_FLOW_ACTION_ESP = 1,
2008+};
2009+
2010+struct ib_flow_action_attrs_esp_keymats {
2011+ enum ib_uverbs_flow_action_esp_keymat protocol;
2012+ union {
2013+ struct ib_uverbs_flow_action_esp_keymat_aes_gcm aes_gcm;
2014+ } keymat;
2015+};
2016+
2017+struct ib_flow_action_attrs_esp_replays {
2018+ enum ib_uverbs_flow_action_esp_replay protocol;
2019+ union {
2020+ struct ib_uverbs_flow_action_esp_replay_bmp bmp;
2021+ } replay;
2022+};
2023+
2024+enum ib_flow_action_attrs_esp_flags {
2025+ /* All user-space flags at the top: Use enum ib_uverbs_flow_action_esp_flags
2026+ * This is done in order to share the same flags between user-space and
2027+ * kernel and spare an unnecessary translation.
2028+ */
2029+
2030+ /* Kernel flags */
2031+ IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED = 1ULL << 32,
2032+};
2033+
2034+struct ib_flow_spec_list {
2035+ struct ib_flow_spec_list *next;
2036+ union ib_flow_spec spec;
2037+};
2038+
2039+struct ib_flow_action_attrs_esp {
2040+ struct ib_flow_action_attrs_esp_keymats *keymat;
2041+ struct ib_flow_action_attrs_esp_replays *replay;
2042+ struct ib_flow_spec_list *encap;
2043+ /* Used only if IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED is enabled.
2044+ * Value of 0 is a valid value.
2045+ */
2046+ u32 esn;
2047+ u32 spi;
2048+ u32 seq;
2049+ u32 tfc_pad;
2050+ /* Use enum ib_flow_action_attrs_esp_flags */
2051+ u64 flags;
2052+ u64 hard_limit_pkts;
2053+};
2054+
2055+struct ib_flow_action {
2056+ struct ib_device *device;
2057+ struct ib_uobject *uobject;
2058+ enum ib_flow_action_type type;
2059+ atomic_t usecnt;
2060+};
2061+
20042062 struct ib_mad_hdr;
20052063 struct ib_grh;
20062064
@@ -2077,6 +2135,8 @@ struct ib_port_pkey_list { · 70 unmodified lines
20772135 struct list_head pkey_list;
20782136 };
20792137
2138+struct uverbs_attr_bundle;
2139+
20802140 struct ib_device {
20812141 /* Do not access @dma_device directly from ULP nor from HW drivers. */
20822142 struct device *dma_device;
@@ -2331,6 +2391,11 @@ struct ib_device { · 248 unmodified lines
23312391 struct ib_rwq_ind_table_init_attr *init_attr,
23322392 struct ib_udata *udata);
23332393 int (*destroy_rwq_ind_table)(struct ib_rwq_ind_table *wq_ind_table);
2394+ struct ib_flow_action * (*create_flow_action_esp)(struct ib_device *device,
2395+ const struct ib_flow_action_attrs_esp *attr,
2396+ struct uverbs_attr_bundle *attrs);
2397+ int (*destroy_flow_action)(struct ib_flow_action *action);
2398+
23342399 /**
23352400 * rdma netdev operation
23362401 *
include/uapi/rdma/ib_user_ioctl_cmds.h+19−0
@@ -53,6 +53,7 @@ enum uverbs_default_objects { · 52 unmodified lines
5353 UVERBS_OBJECT_XRCD,
5454 UVERBS_OBJECT_RWQ_IND_TBL,
5555 UVERBS_OBJECT_WQ,
56+ UVERBS_OBJECT_FLOW_ACTION,
5657 };
5758
5859 enum {
@@ -75,9 +76,27 @@ enum uverbs_attrs_destroy_cq_cmd_attr_ids { · 16 unmodified lines
7576 UVERBS_ATTR_DESTROY_CQ_RESP,
7677 };
7778
79+enum uverbs_attrs_create_flow_action_esp {
80+ UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE,
81+ UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS,
82+ UVERBS_ATTR_FLOW_ACTION_ESP_ESN,
83+ UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT,
84+ UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY,
85+ UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP,
86+};
87+
88+enum uverbs_attrs_destroy_flow_action_esp {
89+ UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE,
90+};
91+
7892 enum uverbs_methods_cq {
7993 UVERBS_METHOD_CQ_CREATE,
8094 UVERBS_METHOD_CQ_DESTROY,
8195 };
8296
97+enum uverbs_methods_actions_flow_action_ops {
98+ UVERBS_METHOD_FLOW_ACTION_ESP_CREATE,
99+ UVERBS_METHOD_FLOW_ACTION_DESTROY,
100+};
101+
83102 #endif
include/uapi/rdma/ib_user_ioctl_verbs.h+59−0
@@ -40,4 +40,63 @@ · 39 unmodified lines
4040 #define RDMA_UAPI_PTR(_type, _name) __aligned_u64 _name
4141 #endif
4242
43+enum ib_uverbs_flow_action_esp_keymat {
44+ IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM,
45+};
46+
47+enum ib_uverbs_flow_action_esp_keymat_aes_gcm_iv_algo {
48+ IB_UVERBS_FLOW_ACTION_IV_ALGO_SEQ,
49+};
50+
51+struct ib_uverbs_flow_action_esp_keymat_aes_gcm {
52+ __aligned_u64 iv;
53+ __u32 iv_algo; /* Use enum ib_uverbs_flow_action_esp_keymat_aes_gcm_iv_algo */
54+
55+ __u32 salt;
56+ __u32 icv_len;
57+
58+ __u32 key_len;
59+ __u32 aes_key[256 / 32];
60+};
61+
62+enum ib_uverbs_flow_action_esp_replay {
63+ IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE,
64+ IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP,
65+};
66+
67+struct ib_uverbs_flow_action_esp_replay_bmp {
68+ __u32 size;
69+};
70+
71+enum ib_uverbs_flow_action_esp_flags {
72+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_INLINE_CRYPTO = 0UL << 0, /* Default */
73+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_FULL_OFFLOAD = 1UL << 0,
74+
75+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_TUNNEL = 0UL << 1, /* Default */
76+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_TRANSPORT = 1UL << 1,
77+
78+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_DECRYPT = 0UL << 2, /* Default */
79+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ENCRYPT = 1UL << 2,
80+
81+ IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW = 1UL << 3,
82+};
83+
84+struct ib_uverbs_flow_action_esp_encap {
85+ /* This struct represents a list of pointers to flow_xxxx_filter that
86+ * encapsulates the payload in ESP tunnel mode.
87+ */
88+ RDMA_UAPI_PTR(void *, val_ptr); /* pointer to a flow_xxxx_filter */
89+ RDMA_UAPI_PTR(struct ib_uverbs_flow_action_esp_encap *, next_ptr);
90+ __u16 len; /* Len of the filter struct val_ptr points to */
91+ __u16 type; /* Use flow_spec_type enum */
92+};
93+
94+struct ib_uverbs_flow_action_esp {
95+ __u32 spi;
96+ __u32 seq;
97+ __u32 tfc_pad;
98+ __u32 flags;
99+ __aligned_u64 hard_limit_pkts;
100+};
101+
43102 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t