1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip VCAP API
3 *
4 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
5 */
6
7 #include <linux/types.h>
8
9 #include "vcap_api_private.h"
10
11 static int keyfield_size_table[] = {
12 [VCAP_FIELD_BIT] = sizeof(struct vcap_u1_key),
13 [VCAP_FIELD_U32] = sizeof(struct vcap_u32_key),
14 [VCAP_FIELD_U48] = sizeof(struct vcap_u48_key),
15 [VCAP_FIELD_U56] = sizeof(struct vcap_u56_key),
16 [VCAP_FIELD_U64] = sizeof(struct vcap_u64_key),
17 [VCAP_FIELD_U72] = sizeof(struct vcap_u72_key),
18 [VCAP_FIELD_U112] = sizeof(struct vcap_u112_key),
19 [VCAP_FIELD_U128] = sizeof(struct vcap_u128_key),
20 };
21
22 static int actionfield_size_table[] = {
23 [VCAP_FIELD_BIT] = sizeof(struct vcap_u1_action),
24 [VCAP_FIELD_U32] = sizeof(struct vcap_u32_action),
25 [VCAP_FIELD_U48] = sizeof(struct vcap_u48_action),
26 [VCAP_FIELD_U56] = sizeof(struct vcap_u56_action),
27 [VCAP_FIELD_U64] = sizeof(struct vcap_u64_action),
28 [VCAP_FIELD_U72] = sizeof(struct vcap_u72_action),
29 [VCAP_FIELD_U112] = sizeof(struct vcap_u112_action),
30 [VCAP_FIELD_U128] = sizeof(struct vcap_u128_action),
31 };
32
33 /* Moving a rule in the VCAP address space */
34 struct vcap_rule_move {
35 int addr; /* address to move */
36 int offset; /* change in address */
37 int count; /* blocksize of addresses to move */
38 };
39
40 /* Stores the filter cookie and chain id that enabled the port */
41 struct vcap_enabled_port {
42 struct list_head list; /* for insertion in enabled ports list */
43 struct net_device *ndev; /* the enabled port */
44 unsigned long cookie; /* filter that enabled the port */
45 int src_cid; /* source chain id */
46 int dst_cid; /* destination chain id */
47 };
48
vcap_iter_set(struct vcap_stream_iter * itr,int sw_width,const struct vcap_typegroup * tg,u32 offset)49 void vcap_iter_set(struct vcap_stream_iter *itr, int sw_width,
50 const struct vcap_typegroup *tg, u32 offset)
51 {
52 memset(itr, 0, sizeof(*itr));
53 itr->offset = offset;
54 itr->sw_width = sw_width;
55 itr->regs_per_sw = DIV_ROUND_UP(sw_width, 32);
56 itr->tg = tg;
57 }
58
vcap_iter_skip_tg(struct vcap_stream_iter * itr)59 static void vcap_iter_skip_tg(struct vcap_stream_iter *itr)
60 {
61 /* Compensate the field offset for preceding typegroups.
62 * A typegroup table ends with an all-zero terminator.
63 */
64 while (itr->tg->width && itr->offset >= itr->tg->offset) {
65 itr->offset += itr->tg->width;
66 itr->tg++; /* next typegroup */
67 }
68 }
69
vcap_iter_update(struct vcap_stream_iter * itr)70 void vcap_iter_update(struct vcap_stream_iter *itr)
71 {
72 int sw_idx, sw_bitpos;
73
74 /* Calculate the subword index and bitposition for current bit */
75 sw_idx = itr->offset / itr->sw_width;
76 sw_bitpos = itr->offset % itr->sw_width;
77 /* Calculate the register index and bitposition for current bit */
78 itr->reg_idx = (sw_idx * itr->regs_per_sw) + (sw_bitpos / 32);
79 itr->reg_bitpos = sw_bitpos % 32;
80 }
81
vcap_iter_init(struct vcap_stream_iter * itr,int sw_width,const struct vcap_typegroup * tg,u32 offset)82 void vcap_iter_init(struct vcap_stream_iter *itr, int sw_width,
83 const struct vcap_typegroup *tg, u32 offset)
84 {
85 vcap_iter_set(itr, sw_width, tg, offset);
86 vcap_iter_skip_tg(itr);
87 vcap_iter_update(itr);
88 }
89
vcap_iter_next(struct vcap_stream_iter * itr)90 void vcap_iter_next(struct vcap_stream_iter *itr)
91 {
92 itr->offset++;
93 vcap_iter_skip_tg(itr);
94 vcap_iter_update(itr);
95 }
96
vcap_set_bit(u32 * stream,struct vcap_stream_iter * itr,bool value)97 static void vcap_set_bit(u32 *stream, struct vcap_stream_iter *itr, bool value)
98 {
99 u32 mask = BIT(itr->reg_bitpos);
100 u32 *p = &stream[itr->reg_idx];
101
102 if (value)
103 *p |= mask;
104 else
105 *p &= ~mask;
106 }
107
vcap_encode_bit(u32 * stream,struct vcap_stream_iter * itr,bool val)108 static void vcap_encode_bit(u32 *stream, struct vcap_stream_iter *itr, bool val)
109 {
110 /* When intersected by a type group field, stream the type group bits
111 * before continuing with the value bit
112 */
113 while (itr->tg->width &&
114 itr->offset >= itr->tg->offset &&
115 itr->offset < itr->tg->offset + itr->tg->width) {
116 int tg_bitpos = itr->tg->offset - itr->offset;
117
118 vcap_set_bit(stream, itr, (itr->tg->value >> tg_bitpos) & 0x1);
119 itr->offset++;
120 vcap_iter_update(itr);
121 }
122 vcap_set_bit(stream, itr, val);
123 }
124
vcap_encode_field(u32 * stream,struct vcap_stream_iter * itr,int width,const u8 * value)125 static void vcap_encode_field(u32 *stream, struct vcap_stream_iter *itr,
126 int width, const u8 *value)
127 {
128 int idx;
129
130 /* Loop over the field value bits and add the value bits one by one to
131 * the output stream.
132 */
133 for (idx = 0; idx < width; idx++) {
134 u8 bidx = idx & GENMASK(2, 0);
135
136 /* Encode one field value bit */
137 vcap_encode_bit(stream, itr, (value[idx / 8] >> bidx) & 0x1);
138 vcap_iter_next(itr);
139 }
140 }
141
vcap_encode_typegroups(u32 * stream,int sw_width,const struct vcap_typegroup * tg,bool mask)142 static void vcap_encode_typegroups(u32 *stream, int sw_width,
143 const struct vcap_typegroup *tg,
144 bool mask)
145 {
146 struct vcap_stream_iter iter;
147 int idx;
148
149 /* Mask bits must be set to zeros (inverted later when writing to the
150 * mask cache register), so that the mask typegroup bits consist of
151 * match-1 or match-0, or both
152 */
153 vcap_iter_set(&iter, sw_width, tg, 0);
154 while (iter.tg->width) {
155 /* Set position to current typegroup bit */
156 iter.offset = iter.tg->offset;
157 vcap_iter_update(&iter);
158 for (idx = 0; idx < iter.tg->width; idx++) {
159 /* Iterate over current typegroup bits. Mask typegroup
160 * bits are always set
161 */
162 if (mask)
163 vcap_set_bit(stream, &iter, 0x1);
164 else
165 vcap_set_bit(stream, &iter,
166 (iter.tg->value >> idx) & 0x1);
167 iter.offset++;
168 vcap_iter_update(&iter);
169 }
170 iter.tg++; /* next typegroup */
171 }
172 }
173
vcap_bitarray_zero(int width,u8 * value)174 static bool vcap_bitarray_zero(int width, u8 *value)
175 {
176 int bytes = DIV_ROUND_UP(width, BITS_PER_BYTE);
177 u8 total = 0, bmask = 0xff;
178 int rwidth = width;
179 int idx;
180
181 for (idx = 0; idx < bytes; ++idx, rwidth -= BITS_PER_BYTE) {
182 if (rwidth && rwidth < BITS_PER_BYTE)
183 bmask = (1 << rwidth) - 1;
184 total += value[idx] & bmask;
185 }
186 return total == 0;
187 }
188
vcap_get_bit(u32 * stream,struct vcap_stream_iter * itr)189 static bool vcap_get_bit(u32 *stream, struct vcap_stream_iter *itr)
190 {
191 u32 mask = BIT(itr->reg_bitpos);
192 u32 *p = &stream[itr->reg_idx];
193
194 return !!(*p & mask);
195 }
196
vcap_decode_field(u32 * stream,struct vcap_stream_iter * itr,int width,u8 * value)197 static void vcap_decode_field(u32 *stream, struct vcap_stream_iter *itr,
198 int width, u8 *value)
199 {
200 int idx;
201
202 /* Loop over the field value bits and get the field bits and
203 * set them in the output value byte array
204 */
205 for (idx = 0; idx < width; idx++) {
206 u8 bidx = idx & 0x7;
207
208 /* Decode one field value bit */
209 if (vcap_get_bit(stream, itr))
210 *value |= 1 << bidx;
211 vcap_iter_next(itr);
212 if (bidx == 7)
213 value++;
214 }
215 }
216
217 /* Verify that the type id in the stream matches the type id of the keyset */
vcap_verify_keystream_keyset(struct vcap_control * vctrl,enum vcap_type vt,u32 * keystream,u32 * mskstream,enum vcap_keyfield_set keyset)218 static bool vcap_verify_keystream_keyset(struct vcap_control *vctrl,
219 enum vcap_type vt,
220 u32 *keystream,
221 u32 *mskstream,
222 enum vcap_keyfield_set keyset)
223 {
224 const struct vcap_info *vcap = &vctrl->vcaps[vt];
225 const struct vcap_field *typefld;
226 const struct vcap_typegroup *tgt;
227 const struct vcap_field *fields;
228 struct vcap_stream_iter iter;
229 const struct vcap_set *info;
230 u32 value = 0;
231 u32 mask = 0;
232
233 if (vcap_keyfield_count(vctrl, vt, keyset) == 0)
234 return false;
235
236 info = vcap_keyfieldset(vctrl, vt, keyset);
237 /* Check that the keyset is valid */
238 if (!info)
239 return false;
240
241 /* a type_id of value -1 means that there is no type field */
242 if (info->type_id == (u8)-1)
243 return true;
244
245 /* Get a valid typegroup for the specific keyset */
246 tgt = vcap_keyfield_typegroup(vctrl, vt, keyset);
247 if (!tgt)
248 return false;
249
250 fields = vcap_keyfields(vctrl, vt, keyset);
251 if (!fields)
252 return false;
253
254 typefld = &fields[VCAP_KF_TYPE];
255 vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset);
256 vcap_decode_field(mskstream, &iter, typefld->width, (u8 *)&mask);
257 /* no type info if there are no mask bits */
258 if (vcap_bitarray_zero(typefld->width, (u8 *)&mask))
259 return false;
260
261 /* Get the value of the type field in the stream and compare to the
262 * one define in the vcap keyset
263 */
264 vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset);
265 vcap_decode_field(keystream, &iter, typefld->width, (u8 *)&value);
266
267 return (value & mask) == (info->type_id & mask);
268 }
269
270 /* Verify that the typegroup bits have the correct values */
vcap_verify_typegroups(u32 * stream,int sw_width,const struct vcap_typegroup * tgt,bool mask,int sw_max)271 static int vcap_verify_typegroups(u32 *stream, int sw_width,
272 const struct vcap_typegroup *tgt, bool mask,
273 int sw_max)
274 {
275 struct vcap_stream_iter iter;
276 int sw_cnt, idx;
277
278 vcap_iter_set(&iter, sw_width, tgt, 0);
279 sw_cnt = 0;
280 while (iter.tg->width) {
281 u32 value = 0;
282 u32 tg_value = iter.tg->value;
283
284 if (mask)
285 tg_value = (1 << iter.tg->width) - 1;
286 /* Set position to current typegroup bit */
287 iter.offset = iter.tg->offset;
288 vcap_iter_update(&iter);
289 for (idx = 0; idx < iter.tg->width; idx++) {
290 /* Decode one typegroup bit */
291 if (vcap_get_bit(stream, &iter))
292 value |= 1 << idx;
293 iter.offset++;
294 vcap_iter_update(&iter);
295 }
296 if (value != tg_value)
297 return -EINVAL;
298 iter.tg++; /* next typegroup */
299 sw_cnt++;
300 /* Stop checking more typegroups */
301 if (sw_max && sw_cnt >= sw_max)
302 break;
303 }
304 return 0;
305 }
306
307 /* Find the subword width of the key typegroup that matches the stream data */
vcap_find_keystream_typegroup_sw(struct vcap_control * vctrl,enum vcap_type vt,u32 * stream,bool mask,int sw_max)308 static int vcap_find_keystream_typegroup_sw(struct vcap_control *vctrl,
309 enum vcap_type vt, u32 *stream,
310 bool mask, int sw_max)
311 {
312 const struct vcap_typegroup **tgt;
313 int sw_idx, res;
314
315 tgt = vctrl->vcaps[vt].keyfield_set_typegroups;
316 /* Try the longest subword match first */
317 for (sw_idx = vctrl->vcaps[vt].sw_count; sw_idx >= 0; sw_idx--) {
318 if (!tgt[sw_idx])
319 continue;
320
321 res = vcap_verify_typegroups(stream, vctrl->vcaps[vt].sw_width,
322 tgt[sw_idx], mask, sw_max);
323 if (res == 0)
324 return sw_idx;
325 }
326 return -EINVAL;
327 }
328
329 /* Verify that the typegroup information, subword count, keyset and type id
330 * are in sync and correct, return the list of matchin keysets
331 */
332 int
vcap_find_keystream_keysets(struct vcap_control * vctrl,enum vcap_type vt,u32 * keystream,u32 * mskstream,bool mask,int sw_max,struct vcap_keyset_list * kslist)333 vcap_find_keystream_keysets(struct vcap_control *vctrl,
334 enum vcap_type vt,
335 u32 *keystream,
336 u32 *mskstream,
337 bool mask, int sw_max,
338 struct vcap_keyset_list *kslist)
339 {
340 const struct vcap_set *keyfield_set;
341 int sw_count, idx;
342
343 sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask,
344 sw_max);
345 if (sw_count < 0)
346 return sw_count;
347
348 keyfield_set = vctrl->vcaps[vt].keyfield_set;
349 for (idx = 0; idx < vctrl->vcaps[vt].keyfield_set_size; ++idx) {
350 if (keyfield_set[idx].sw_per_item != sw_count)
351 continue;
352
353 if (vcap_verify_keystream_keyset(vctrl, vt, keystream,
354 mskstream, idx))
355 vcap_keyset_list_add(kslist, idx);
356 }
357 if (kslist->cnt > 0)
358 return 0;
359 return -EINVAL;
360 }
361 EXPORT_SYMBOL_GPL(vcap_find_keystream_keysets);
362
363 /* Read key data from a VCAP address and discover if there are any rule keysets
364 * here
365 */
vcap_addr_keysets(struct vcap_control * vctrl,struct net_device * ndev,struct vcap_admin * admin,int addr,struct vcap_keyset_list * kslist)366 int vcap_addr_keysets(struct vcap_control *vctrl,
367 struct net_device *ndev,
368 struct vcap_admin *admin,
369 int addr,
370 struct vcap_keyset_list *kslist)
371 {
372 enum vcap_type vt = admin->vtype;
373 int keyset_sw_regs, idx;
374 u32 key = 0, mask = 0;
375
376 /* Read the cache at the specified address */
377 keyset_sw_regs = DIV_ROUND_UP(vctrl->vcaps[vt].sw_width, 32);
378 vctrl->ops->update(ndev, admin, VCAP_CMD_READ, VCAP_SEL_ALL, addr);
379 vctrl->ops->cache_read(ndev, admin, VCAP_SEL_ENTRY, 0,
380 keyset_sw_regs);
381 /* Skip uninitialized key/mask entries */
382 for (idx = 0; idx < keyset_sw_regs; ++idx) {
383 key |= ~admin->cache.keystream[idx];
384 mask |= admin->cache.maskstream[idx];
385 }
386 if (key == 0 && mask == 0)
387 return -EINVAL;
388 /* Decode and locate the keysets */
389 return vcap_find_keystream_keysets(vctrl, vt, admin->cache.keystream,
390 admin->cache.maskstream, false, 0,
391 kslist);
392 }
393 EXPORT_SYMBOL_GPL(vcap_addr_keysets);
394
395 /* Return the list of keyfields for the keyset */
vcap_keyfields(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_keyfield_set keyset)396 const struct vcap_field *vcap_keyfields(struct vcap_control *vctrl,
397 enum vcap_type vt,
398 enum vcap_keyfield_set keyset)
399 {
400 /* Check that the keyset exists in the vcap keyset list */
401 if (keyset >= vctrl->vcaps[vt].keyfield_set_size)
402 return NULL;
403 return vctrl->vcaps[vt].keyfield_set_map[keyset];
404 }
405
406 /* Return the keyset information for the keyset */
vcap_keyfieldset(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_keyfield_set keyset)407 const struct vcap_set *vcap_keyfieldset(struct vcap_control *vctrl,
408 enum vcap_type vt,
409 enum vcap_keyfield_set keyset)
410 {
411 const struct vcap_set *kset;
412
413 /* Check that the keyset exists in the vcap keyset list */
414 if (keyset >= vctrl->vcaps[vt].keyfield_set_size)
415 return NULL;
416 kset = &vctrl->vcaps[vt].keyfield_set[keyset];
417 if (kset->sw_per_item == 0 || kset->sw_per_item > vctrl->vcaps[vt].sw_count)
418 return NULL;
419 return kset;
420 }
421 EXPORT_SYMBOL_GPL(vcap_keyfieldset);
422
423 /* Return the typegroup table for the matching keyset (using subword size) */
424 const struct vcap_typegroup *
vcap_keyfield_typegroup(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_keyfield_set keyset)425 vcap_keyfield_typegroup(struct vcap_control *vctrl,
426 enum vcap_type vt, enum vcap_keyfield_set keyset)
427 {
428 const struct vcap_set *kset = vcap_keyfieldset(vctrl, vt, keyset);
429
430 /* Check that the keyset is valid */
431 if (!kset)
432 return NULL;
433 return vctrl->vcaps[vt].keyfield_set_typegroups[kset->sw_per_item];
434 }
435
436 /* Return the number of keyfields in the keyset */
vcap_keyfield_count(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_keyfield_set keyset)437 int vcap_keyfield_count(struct vcap_control *vctrl,
438 enum vcap_type vt, enum vcap_keyfield_set keyset)
439 {
440 /* Check that the keyset exists in the vcap keyset list */
441 if (keyset >= vctrl->vcaps[vt].keyfield_set_size)
442 return 0;
443 return vctrl->vcaps[vt].keyfield_set_map_size[keyset];
444 }
445
vcap_encode_keyfield(struct vcap_rule_internal * ri,const struct vcap_client_keyfield * kf,const struct vcap_field * rf,const struct vcap_typegroup * tgt)446 static void vcap_encode_keyfield(struct vcap_rule_internal *ri,
447 const struct vcap_client_keyfield *kf,
448 const struct vcap_field *rf,
449 const struct vcap_typegroup *tgt)
450 {
451 int sw_width = ri->vctrl->vcaps[ri->admin->vtype].sw_width;
452 struct vcap_cache_data *cache = &ri->admin->cache;
453 struct vcap_stream_iter iter;
454 const u8 *value, *mask;
455
456 /* Encode the fields for the key and the mask in their respective
457 * streams, respecting the subword width.
458 */
459 switch (kf->ctrl.type) {
460 case VCAP_FIELD_BIT:
461 value = &kf->data.u1.value;
462 mask = &kf->data.u1.mask;
463 break;
464 case VCAP_FIELD_U32:
465 value = (const u8 *)&kf->data.u32.value;
466 mask = (const u8 *)&kf->data.u32.mask;
467 break;
468 case VCAP_FIELD_U48:
469 value = kf->data.u48.value;
470 mask = kf->data.u48.mask;
471 break;
472 case VCAP_FIELD_U56:
473 value = kf->data.u56.value;
474 mask = kf->data.u56.mask;
475 break;
476 case VCAP_FIELD_U64:
477 value = kf->data.u64.value;
478 mask = kf->data.u64.mask;
479 break;
480 case VCAP_FIELD_U72:
481 value = kf->data.u72.value;
482 mask = kf->data.u72.mask;
483 break;
484 case VCAP_FIELD_U112:
485 value = kf->data.u112.value;
486 mask = kf->data.u112.mask;
487 break;
488 case VCAP_FIELD_U128:
489 value = kf->data.u128.value;
490 mask = kf->data.u128.mask;
491 break;
492 }
493 vcap_iter_init(&iter, sw_width, tgt, rf->offset);
494 vcap_encode_field(cache->keystream, &iter, rf->width, value);
495 vcap_iter_init(&iter, sw_width, tgt, rf->offset);
496 vcap_encode_field(cache->maskstream, &iter, rf->width, mask);
497 }
498
vcap_encode_keyfield_typegroups(struct vcap_control * vctrl,struct vcap_rule_internal * ri,const struct vcap_typegroup * tgt)499 static void vcap_encode_keyfield_typegroups(struct vcap_control *vctrl,
500 struct vcap_rule_internal *ri,
501 const struct vcap_typegroup *tgt)
502 {
503 int sw_width = vctrl->vcaps[ri->admin->vtype].sw_width;
504 struct vcap_cache_data *cache = &ri->admin->cache;
505
506 /* Encode the typegroup bits for the key and the mask in their streams,
507 * respecting the subword width.
508 */
509 vcap_encode_typegroups(cache->keystream, sw_width, tgt, false);
510 vcap_encode_typegroups(cache->maskstream, sw_width, tgt, true);
511 }
512
513 /* Copy data from src to dst but reverse the data in chunks of 32bits.
514 * For example if src is 00:11:22:33:44:55 where 55 is LSB the dst will
515 * have the value 22:33:44:55:00:11.
516 */
vcap_copy_to_w32be(u8 * dst,const u8 * src,int size)517 static void vcap_copy_to_w32be(u8 *dst, const u8 *src, int size)
518 {
519 for (int idx = 0; idx < size; ++idx) {
520 int first_byte_index = 0;
521 int nidx;
522
523 first_byte_index = size - (((idx >> 2) + 1) << 2);
524 if (first_byte_index < 0)
525 first_byte_index = 0;
526 nidx = idx + first_byte_index - (idx & ~0x3);
527 dst[nidx] = src[idx];
528 }
529 }
530
531 static void
vcap_copy_from_client_keyfield(struct vcap_rule * rule,struct vcap_client_keyfield * dst,const struct vcap_client_keyfield * src)532 vcap_copy_from_client_keyfield(struct vcap_rule *rule,
533 struct vcap_client_keyfield *dst,
534 const struct vcap_client_keyfield *src)
535 {
536 struct vcap_rule_internal *ri = to_intrule(rule);
537 const struct vcap_client_keyfield_data *sdata;
538 struct vcap_client_keyfield_data *ddata;
539 int size;
540
541 dst->ctrl.type = src->ctrl.type;
542 dst->ctrl.key = src->ctrl.key;
543 INIT_LIST_HEAD(&dst->ctrl.list);
544 sdata = &src->data;
545 ddata = &dst->data;
546
547 if (!ri->admin->w32be) {
548 memcpy(ddata, sdata, sizeof(dst->data));
549 return;
550 }
551
552 size = keyfield_size_table[dst->ctrl.type] / 2;
553
554 switch (dst->ctrl.type) {
555 case VCAP_FIELD_BIT:
556 case VCAP_FIELD_U32:
557 memcpy(ddata, sdata, sizeof(dst->data));
558 break;
559 case VCAP_FIELD_U48:
560 vcap_copy_to_w32be(ddata->u48.value, src->data.u48.value, size);
561 vcap_copy_to_w32be(ddata->u48.mask, src->data.u48.mask, size);
562 break;
563 case VCAP_FIELD_U56:
564 vcap_copy_to_w32be(ddata->u56.value, sdata->u56.value, size);
565 vcap_copy_to_w32be(ddata->u56.mask, sdata->u56.mask, size);
566 break;
567 case VCAP_FIELD_U64:
568 vcap_copy_to_w32be(ddata->u64.value, sdata->u64.value, size);
569 vcap_copy_to_w32be(ddata->u64.mask, sdata->u64.mask, size);
570 break;
571 case VCAP_FIELD_U72:
572 vcap_copy_to_w32be(ddata->u72.value, sdata->u72.value, size);
573 vcap_copy_to_w32be(ddata->u72.mask, sdata->u72.mask, size);
574 break;
575 case VCAP_FIELD_U112:
576 vcap_copy_to_w32be(ddata->u112.value, sdata->u112.value, size);
577 vcap_copy_to_w32be(ddata->u112.mask, sdata->u112.mask, size);
578 break;
579 case VCAP_FIELD_U128:
580 vcap_copy_to_w32be(ddata->u128.value, sdata->u128.value, size);
581 vcap_copy_to_w32be(ddata->u128.mask, sdata->u128.mask, size);
582 break;
583 }
584 }
585
586 static void
vcap_copy_from_client_actionfield(struct vcap_rule * rule,struct vcap_client_actionfield * dst,const struct vcap_client_actionfield * src)587 vcap_copy_from_client_actionfield(struct vcap_rule *rule,
588 struct vcap_client_actionfield *dst,
589 const struct vcap_client_actionfield *src)
590 {
591 struct vcap_rule_internal *ri = to_intrule(rule);
592 const struct vcap_client_actionfield_data *sdata;
593 struct vcap_client_actionfield_data *ddata;
594 int size;
595
596 dst->ctrl.type = src->ctrl.type;
597 dst->ctrl.action = src->ctrl.action;
598 INIT_LIST_HEAD(&dst->ctrl.list);
599 sdata = &src->data;
600 ddata = &dst->data;
601
602 if (!ri->admin->w32be) {
603 memcpy(ddata, sdata, sizeof(dst->data));
604 return;
605 }
606
607 size = actionfield_size_table[dst->ctrl.type];
608
609 switch (dst->ctrl.type) {
610 case VCAP_FIELD_BIT:
611 case VCAP_FIELD_U32:
612 memcpy(ddata, sdata, sizeof(dst->data));
613 break;
614 case VCAP_FIELD_U48:
615 vcap_copy_to_w32be(ddata->u48.value, sdata->u48.value, size);
616 break;
617 case VCAP_FIELD_U56:
618 vcap_copy_to_w32be(ddata->u56.value, sdata->u56.value, size);
619 break;
620 case VCAP_FIELD_U64:
621 vcap_copy_to_w32be(ddata->u64.value, sdata->u64.value, size);
622 break;
623 case VCAP_FIELD_U72:
624 vcap_copy_to_w32be(ddata->u72.value, sdata->u72.value, size);
625 break;
626 case VCAP_FIELD_U112:
627 vcap_copy_to_w32be(ddata->u112.value, sdata->u112.value, size);
628 break;
629 case VCAP_FIELD_U128:
630 vcap_copy_to_w32be(ddata->u128.value, sdata->u128.value, size);
631 break;
632 }
633 }
634
vcap_encode_rule_keyset(struct vcap_rule_internal * ri)635 static int vcap_encode_rule_keyset(struct vcap_rule_internal *ri)
636 {
637 const struct vcap_client_keyfield *ckf;
638 const struct vcap_typegroup *tg_table;
639 struct vcap_client_keyfield tempkf;
640 const struct vcap_field *kf_table;
641 int keyset_size;
642
643 /* Get a valid set of fields for the specific keyset */
644 kf_table = vcap_keyfields(ri->vctrl, ri->admin->vtype, ri->data.keyset);
645 if (!kf_table) {
646 pr_err("%s:%d: no fields available for this keyset: %d\n",
647 __func__, __LINE__, ri->data.keyset);
648 return -EINVAL;
649 }
650 /* Get a valid typegroup for the specific keyset */
651 tg_table = vcap_keyfield_typegroup(ri->vctrl, ri->admin->vtype,
652 ri->data.keyset);
653 if (!tg_table) {
654 pr_err("%s:%d: no typegroups available for this keyset: %d\n",
655 __func__, __LINE__, ri->data.keyset);
656 return -EINVAL;
657 }
658 /* Get a valid size for the specific keyset */
659 keyset_size = vcap_keyfield_count(ri->vctrl, ri->admin->vtype,
660 ri->data.keyset);
661 if (keyset_size == 0) {
662 pr_err("%s:%d: zero field count for this keyset: %d\n",
663 __func__, __LINE__, ri->data.keyset);
664 return -EINVAL;
665 }
666 /* Iterate over the keyfields (key, mask) in the rule
667 * and encode these bits
668 */
669 if (list_empty(&ri->data.keyfields)) {
670 pr_err("%s:%d: no keyfields in the rule\n", __func__, __LINE__);
671 return -EINVAL;
672 }
673 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {
674 /* Check that the client entry exists in the keyset */
675 if (ckf->ctrl.key >= keyset_size) {
676 pr_err("%s:%d: key %d is not in vcap\n",
677 __func__, __LINE__, ckf->ctrl.key);
678 return -EINVAL;
679 }
680 vcap_copy_from_client_keyfield(&ri->data, &tempkf, ckf);
681 vcap_encode_keyfield(ri, &tempkf, &kf_table[ckf->ctrl.key],
682 tg_table);
683 }
684 /* Add typegroup bits to the key/mask bitstreams */
685 vcap_encode_keyfield_typegroups(ri->vctrl, ri, tg_table);
686 return 0;
687 }
688
689 /* Return the list of actionfields for the actionset */
690 const struct vcap_field *
vcap_actionfields(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_actionfield_set actionset)691 vcap_actionfields(struct vcap_control *vctrl,
692 enum vcap_type vt, enum vcap_actionfield_set actionset)
693 {
694 /* Check that the actionset exists in the vcap actionset list */
695 if (actionset >= vctrl->vcaps[vt].actionfield_set_size)
696 return NULL;
697 return vctrl->vcaps[vt].actionfield_set_map[actionset];
698 }
699
700 const struct vcap_set *
vcap_actionfieldset(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_actionfield_set actionset)701 vcap_actionfieldset(struct vcap_control *vctrl,
702 enum vcap_type vt, enum vcap_actionfield_set actionset)
703 {
704 const struct vcap_set *aset;
705
706 /* Check that the actionset exists in the vcap actionset list */
707 if (actionset >= vctrl->vcaps[vt].actionfield_set_size)
708 return NULL;
709 aset = &vctrl->vcaps[vt].actionfield_set[actionset];
710 if (aset->sw_per_item == 0 || aset->sw_per_item > vctrl->vcaps[vt].sw_count)
711 return NULL;
712 return aset;
713 }
714
715 /* Return the typegroup table for the matching actionset (using subword size) */
716 const struct vcap_typegroup *
vcap_actionfield_typegroup(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_actionfield_set actionset)717 vcap_actionfield_typegroup(struct vcap_control *vctrl,
718 enum vcap_type vt, enum vcap_actionfield_set actionset)
719 {
720 const struct vcap_set *aset = vcap_actionfieldset(vctrl, vt, actionset);
721
722 /* Check that the actionset is valid */
723 if (!aset)
724 return NULL;
725 return vctrl->vcaps[vt].actionfield_set_typegroups[aset->sw_per_item];
726 }
727
728 /* Return the number of actionfields in the actionset */
vcap_actionfield_count(struct vcap_control * vctrl,enum vcap_type vt,enum vcap_actionfield_set actionset)729 int vcap_actionfield_count(struct vcap_control *vctrl,
730 enum vcap_type vt,
731 enum vcap_actionfield_set actionset)
732 {
733 /* Check that the actionset exists in the vcap actionset list */
734 if (actionset >= vctrl->vcaps[vt].actionfield_set_size)
735 return 0;
736 return vctrl->vcaps[vt].actionfield_set_map_size[actionset];
737 }
738
vcap_encode_actionfield(struct vcap_rule_internal * ri,const struct vcap_client_actionfield * af,const struct vcap_field * rf,const struct vcap_typegroup * tgt)739 static void vcap_encode_actionfield(struct vcap_rule_internal *ri,
740 const struct vcap_client_actionfield *af,
741 const struct vcap_field *rf,
742 const struct vcap_typegroup *tgt)
743 {
744 int act_width = ri->vctrl->vcaps[ri->admin->vtype].act_width;
745
746 struct vcap_cache_data *cache = &ri->admin->cache;
747 struct vcap_stream_iter iter;
748 const u8 *value;
749
750 /* Encode the action field in the stream, respecting the subword width */
751 switch (af->ctrl.type) {
752 case VCAP_FIELD_BIT:
753 value = &af->data.u1.value;
754 break;
755 case VCAP_FIELD_U32:
756 value = (const u8 *)&af->data.u32.value;
757 break;
758 case VCAP_FIELD_U48:
759 value = af->data.u48.value;
760 break;
761 case VCAP_FIELD_U56:
762 value = af->data.u56.value;
763 break;
764 case VCAP_FIELD_U64:
765 value = af->data.u64.value;
766 break;
767 case VCAP_FIELD_U72:
768 value = af->data.u72.value;
769 break;
770 case VCAP_FIELD_U112:
771 value = af->data.u112.value;
772 break;
773 case VCAP_FIELD_U128:
774 value = af->data.u128.value;
775 break;
776 }
777 vcap_iter_init(&iter, act_width, tgt, rf->offset);
778 vcap_encode_field(cache->actionstream, &iter, rf->width, value);
779 }
780
vcap_encode_actionfield_typegroups(struct vcap_rule_internal * ri,const struct vcap_typegroup * tgt)781 static void vcap_encode_actionfield_typegroups(struct vcap_rule_internal *ri,
782 const struct vcap_typegroup *tgt)
783 {
784 int sw_width = ri->vctrl->vcaps[ri->admin->vtype].act_width;
785 struct vcap_cache_data *cache = &ri->admin->cache;
786
787 /* Encode the typegroup bits for the actionstream respecting the subword
788 * width.
789 */
790 vcap_encode_typegroups(cache->actionstream, sw_width, tgt, false);
791 }
792
vcap_encode_rule_actionset(struct vcap_rule_internal * ri)793 static int vcap_encode_rule_actionset(struct vcap_rule_internal *ri)
794 {
795 const struct vcap_client_actionfield *caf;
796 const struct vcap_typegroup *tg_table;
797 struct vcap_client_actionfield tempaf;
798 const struct vcap_field *af_table;
799 int actionset_size;
800
801 /* Get a valid set of actionset fields for the specific actionset */
802 af_table = vcap_actionfields(ri->vctrl, ri->admin->vtype,
803 ri->data.actionset);
804 if (!af_table) {
805 pr_err("%s:%d: no fields available for this actionset: %d\n",
806 __func__, __LINE__, ri->data.actionset);
807 return -EINVAL;
808 }
809 /* Get a valid typegroup for the specific actionset */
810 tg_table = vcap_actionfield_typegroup(ri->vctrl, ri->admin->vtype,
811 ri->data.actionset);
812 if (!tg_table) {
813 pr_err("%s:%d: no typegroups available for this actionset: %d\n",
814 __func__, __LINE__, ri->data.actionset);
815 return -EINVAL;
816 }
817 /* Get a valid actionset size for the specific actionset */
818 actionset_size = vcap_actionfield_count(ri->vctrl, ri->admin->vtype,
819 ri->data.actionset);
820 if (actionset_size == 0) {
821 pr_err("%s:%d: zero field count for this actionset: %d\n",
822 __func__, __LINE__, ri->data.actionset);
823 return -EINVAL;
824 }
825 /* Iterate over the actionfields in the rule
826 * and encode these bits
827 */
828 if (list_empty(&ri->data.actionfields))
829 pr_warn("%s:%d: no actionfields in the rule\n",
830 __func__, __LINE__);
831 list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {
832 /* Check that the client action exists in the actionset */
833 if (caf->ctrl.action >= actionset_size) {
834 pr_err("%s:%d: action %d is not in vcap\n",
835 __func__, __LINE__, caf->ctrl.action);
836 return -EINVAL;
837 }
838 vcap_copy_from_client_actionfield(&ri->data, &tempaf, caf);
839 vcap_encode_actionfield(ri, &tempaf,
840 &af_table[caf->ctrl.action], tg_table);
841 }
842 /* Add typegroup bits to the entry bitstreams */
843 vcap_encode_actionfield_typegroups(ri, tg_table);
844 return 0;
845 }
846
vcap_encode_rule(struct vcap_rule_internal * ri)847 static int vcap_encode_rule(struct vcap_rule_internal *ri)
848 {
849 int err;
850
851 err = vcap_encode_rule_keyset(ri);
852 if (err)
853 return err;
854 err = vcap_encode_rule_actionset(ri);
855 if (err)
856 return err;
857 return 0;
858 }
859
vcap_api_check(struct vcap_control * ctrl)860 int vcap_api_check(struct vcap_control *ctrl)
861 {
862 if (!ctrl) {
863 pr_err("%s:%d: vcap control is missing\n", __func__, __LINE__);
864 return -EINVAL;
865 }
866 if (!ctrl->ops || !ctrl->ops->validate_keyset ||
867 !ctrl->ops->add_default_fields || !ctrl->ops->cache_erase ||
868 !ctrl->ops->cache_write || !ctrl->ops->cache_read ||
869 !ctrl->ops->init || !ctrl->ops->update || !ctrl->ops->move ||
870 !ctrl->ops->port_info) {
871 pr_err("%s:%d: client operations are missing\n",
872 __func__, __LINE__);
873 return -ENOENT;
874 }
875 return 0;
876 }
877
vcap_erase_cache(struct vcap_rule_internal * ri)878 void vcap_erase_cache(struct vcap_rule_internal *ri)
879 {
880 ri->vctrl->ops->cache_erase(ri->admin);
881 }
882
883 /* Update the keyset for the rule */
vcap_set_rule_set_keyset(struct vcap_rule * rule,enum vcap_keyfield_set keyset)884 int vcap_set_rule_set_keyset(struct vcap_rule *rule,
885 enum vcap_keyfield_set keyset)
886 {
887 struct vcap_rule_internal *ri = to_intrule(rule);
888 const struct vcap_set *kset;
889 int sw_width;
890
891 kset = vcap_keyfieldset(ri->vctrl, ri->admin->vtype, keyset);
892 /* Check that the keyset is valid */
893 if (!kset)
894 return -EINVAL;
895 ri->keyset_sw = kset->sw_per_item;
896 sw_width = ri->vctrl->vcaps[ri->admin->vtype].sw_width;
897 ri->keyset_sw_regs = DIV_ROUND_UP(sw_width, 32);
898 ri->data.keyset = keyset;
899 return 0;
900 }
901 EXPORT_SYMBOL_GPL(vcap_set_rule_set_keyset);
902
903 /* Update the actionset for the rule */
vcap_set_rule_set_actionset(struct vcap_rule * rule,enum vcap_actionfield_set actionset)904 int vcap_set_rule_set_actionset(struct vcap_rule *rule,
905 enum vcap_actionfield_set actionset)
906 {
907 struct vcap_rule_internal *ri = to_intrule(rule);
908 const struct vcap_set *aset;
909 int act_width;
910
911 aset = vcap_actionfieldset(ri->vctrl, ri->admin->vtype, actionset);
912 /* Check that the actionset is valid */
913 if (!aset)
914 return -EINVAL;
915 ri->actionset_sw = aset->sw_per_item;
916 act_width = ri->vctrl->vcaps[ri->admin->vtype].act_width;
917 ri->actionset_sw_regs = DIV_ROUND_UP(act_width, 32);
918 ri->data.actionset = actionset;
919 return 0;
920 }
921 EXPORT_SYMBOL_GPL(vcap_set_rule_set_actionset);
922
923 /* Check if a rule with this id exists */
vcap_rule_exists(struct vcap_control * vctrl,u32 id)924 static bool vcap_rule_exists(struct vcap_control *vctrl, u32 id)
925 {
926 struct vcap_rule_internal *ri;
927 struct vcap_admin *admin;
928
929 /* Look for the rule id in all vcaps */
930 list_for_each_entry(admin, &vctrl->list, list)
931 list_for_each_entry(ri, &admin->rules, list)
932 if (ri->data.id == id)
933 return true;
934 return false;
935 }
936
937 /* Find a rule with a provided rule id return a locked vcap */
938 static struct vcap_rule_internal *
vcap_get_locked_rule(struct vcap_control * vctrl,u32 id)939 vcap_get_locked_rule(struct vcap_control *vctrl, u32 id)
940 {
941 struct vcap_rule_internal *ri;
942 struct vcap_admin *admin;
943
944 /* Look for the rule id in all vcaps */
945 list_for_each_entry(admin, &vctrl->list, list) {
946 mutex_lock(&admin->lock);
947 list_for_each_entry(ri, &admin->rules, list)
948 if (ri->data.id == id)
949 return ri;
950 mutex_unlock(&admin->lock);
951 }
952 return NULL;
953 }
954
955 /* Find a rule id with a provided cookie */
vcap_lookup_rule_by_cookie(struct vcap_control * vctrl,u64 cookie)956 int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie)
957 {
958 struct vcap_rule_internal *ri;
959 struct vcap_admin *admin;
960 int id = 0;
961
962 /* Look for the rule id in all vcaps */
963 list_for_each_entry(admin, &vctrl->list, list) {
964 mutex_lock(&admin->lock);
965 list_for_each_entry(ri, &admin->rules, list) {
966 if (ri->data.cookie == cookie) {
967 id = ri->data.id;
968 break;
969 }
970 }
971 mutex_unlock(&admin->lock);
972 if (id)
973 return id;
974 }
975 return -ENOENT;
976 }
977 EXPORT_SYMBOL_GPL(vcap_lookup_rule_by_cookie);
978
979 /* Make a copy of the rule, shallow or full */
vcap_dup_rule(struct vcap_rule_internal * ri,bool full)980 static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri,
981 bool full)
982 {
983 struct vcap_client_actionfield *caf, *newcaf;
984 struct vcap_client_keyfield *ckf, *newckf;
985 struct vcap_rule_internal *duprule;
986
987 /* Allocate the client part */
988 duprule = kzalloc(sizeof(*duprule), GFP_KERNEL);
989 if (!duprule)
990 return ERR_PTR(-ENOMEM);
991 *duprule = *ri;
992 /* Not inserted in the VCAP */
993 INIT_LIST_HEAD(&duprule->list);
994 /* No elements in these lists */
995 INIT_LIST_HEAD(&duprule->data.keyfields);
996 INIT_LIST_HEAD(&duprule->data.actionfields);
997
998 /* A full rule copy includes keys and actions */
999 if (!full)
1000 return duprule;
1001
1002 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {
1003 newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL);
1004 if (!newckf)
1005 return ERR_PTR(-ENOMEM);
1006 list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields);
1007 }
1008
1009 list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {
1010 newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL);
1011 if (!newcaf)
1012 return ERR_PTR(-ENOMEM);
1013 list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields);
1014 }
1015
1016 return duprule;
1017 }
1018
vcap_apply_width(u8 * dst,int width,int bytes)1019 static void vcap_apply_width(u8 *dst, int width, int bytes)
1020 {
1021 u8 bmask;
1022 int idx;
1023
1024 for (idx = 0; idx < bytes; idx++) {
1025 if (width > 0)
1026 if (width < 8)
1027 bmask = (1 << width) - 1;
1028 else
1029 bmask = ~0;
1030 else
1031 bmask = 0;
1032 dst[idx] &= bmask;
1033 width -= 8;
1034 }
1035 }
1036
vcap_copy_from_w32be(u8 * dst,u8 * src,int size,int width)1037 static void vcap_copy_from_w32be(u8 *dst, u8 *src, int size, int width)
1038 {
1039 int idx, ridx, wstart, nidx;
1040 int tail_bytes = (((size + 4) >> 2) << 2) - size;
1041
1042 for (idx = 0, ridx = size - 1; idx < size; ++idx, --ridx) {
1043 wstart = (idx >> 2) << 2;
1044 nidx = wstart + 3 - (idx & 0x3);
1045 if (nidx >= size)
1046 nidx -= tail_bytes;
1047 dst[nidx] = src[ridx];
1048 }
1049
1050 vcap_apply_width(dst, width, size);
1051 }
1052
vcap_copy_action_bit_field(struct vcap_u1_action * field,u8 * value)1053 static void vcap_copy_action_bit_field(struct vcap_u1_action *field, u8 *value)
1054 {
1055 field->value = (*value) & 0x1;
1056 }
1057
vcap_copy_limited_actionfield(u8 * dstvalue,u8 * srcvalue,int width,int bytes)1058 static void vcap_copy_limited_actionfield(u8 *dstvalue, u8 *srcvalue,
1059 int width, int bytes)
1060 {
1061 memcpy(dstvalue, srcvalue, bytes);
1062 vcap_apply_width(dstvalue, width, bytes);
1063 }
1064
vcap_copy_to_client_actionfield(struct vcap_rule_internal * ri,struct vcap_client_actionfield * field,u8 * value,u16 width)1065 static void vcap_copy_to_client_actionfield(struct vcap_rule_internal *ri,
1066 struct vcap_client_actionfield *field,
1067 u8 *value, u16 width)
1068 {
1069 int field_size = actionfield_size_table[field->ctrl.type];
1070
1071 if (ri->admin->w32be) {
1072 switch (field->ctrl.type) {
1073 case VCAP_FIELD_BIT:
1074 vcap_copy_action_bit_field(&field->data.u1, value);
1075 break;
1076 case VCAP_FIELD_U32:
1077 vcap_copy_limited_actionfield((u8 *)&field->data.u32.value,
1078 value,
1079 width, field_size);
1080 break;
1081 case VCAP_FIELD_U48:
1082 vcap_copy_from_w32be(field->data.u48.value, value,
1083 field_size, width);
1084 break;
1085 case VCAP_FIELD_U56:
1086 vcap_copy_from_w32be(field->data.u56.value, value,
1087 field_size, width);
1088 break;
1089 case VCAP_FIELD_U64:
1090 vcap_copy_from_w32be(field->data.u64.value, value,
1091 field_size, width);
1092 break;
1093 case VCAP_FIELD_U72:
1094 vcap_copy_from_w32be(field->data.u72.value, value,
1095 field_size, width);
1096 break;
1097 case VCAP_FIELD_U112:
1098 vcap_copy_from_w32be(field->data.u112.value, value,
1099 field_size, width);
1100 break;
1101 case VCAP_FIELD_U128:
1102 vcap_copy_from_w32be(field->data.u128.value, value,
1103 field_size, width);
1104 break;
1105 };
1106 } else {
1107 switch (field->ctrl.type) {
1108 case VCAP_FIELD_BIT:
1109 vcap_copy_action_bit_field(&field->data.u1, value);
1110 break;
1111 case VCAP_FIELD_U32:
1112 vcap_copy_limited_actionfield((u8 *)&field->data.u32.value,
1113 value,
1114 width, field_size);
1115 break;
1116 case VCAP_FIELD_U48:
1117 vcap_copy_limited_actionfield(field->data.u48.value,
1118 value,
1119 width, field_size);
1120 break;
1121 case VCAP_FIELD_U56:
1122 vcap_copy_limited_actionfield(field->data.u56.value,
1123 value,
1124 width, field_size);
1125 break;
1126 case VCAP_FIELD_U64:
1127 vcap_copy_limited_actionfield(field->data.u64.value,
1128 value,
1129 width, field_size);
1130 break;
1131 case VCAP_FIELD_U72:
1132 vcap_copy_limited_actionfield(field->data.u72.value,
1133 value,
1134 width, field_size);
1135 break;
1136 case VCAP_FIELD_U112:
1137 vcap_copy_limited_actionfield(field->data.u112.value,
1138 value,
1139 width, field_size);
1140 break;
1141 case VCAP_FIELD_U128:
1142 vcap_copy_limited_actionfield(field->data.u128.value,
1143 value,
1144 width, field_size);
1145 break;
1146 };
1147 }
1148 }
1149
vcap_copy_key_bit_field(struct vcap_u1_key * field,u8 * value,u8 * mask)1150 static void vcap_copy_key_bit_field(struct vcap_u1_key *field,
1151 u8 *value, u8 *mask)
1152 {
1153 field->value = (*value) & 0x1;
1154 field->mask = (*mask) & 0x1;
1155 }
1156
vcap_copy_limited_keyfield(u8 * dstvalue,u8 * dstmask,u8 * srcvalue,u8 * srcmask,int width,int bytes)1157 static void vcap_copy_limited_keyfield(u8 *dstvalue, u8 *dstmask,
1158 u8 *srcvalue, u8 *srcmask,
1159 int width, int bytes)
1160 {
1161 memcpy(dstvalue, srcvalue, bytes);
1162 vcap_apply_width(dstvalue, width, bytes);
1163 memcpy(dstmask, srcmask, bytes);
1164 vcap_apply_width(dstmask, width, bytes);
1165 }
1166
vcap_copy_to_client_keyfield(struct vcap_rule_internal * ri,struct vcap_client_keyfield * field,u8 * value,u8 * mask,u16 width)1167 static void vcap_copy_to_client_keyfield(struct vcap_rule_internal *ri,
1168 struct vcap_client_keyfield *field,
1169 u8 *value, u8 *mask, u16 width)
1170 {
1171 int field_size = keyfield_size_table[field->ctrl.type] / 2;
1172
1173 if (ri->admin->w32be) {
1174 switch (field->ctrl.type) {
1175 case VCAP_FIELD_BIT:
1176 vcap_copy_key_bit_field(&field->data.u1, value, mask);
1177 break;
1178 case VCAP_FIELD_U32:
1179 vcap_copy_limited_keyfield((u8 *)&field->data.u32.value,
1180 (u8 *)&field->data.u32.mask,
1181 value, mask,
1182 width, field_size);
1183 break;
1184 case VCAP_FIELD_U48:
1185 vcap_copy_from_w32be(field->data.u48.value, value,
1186 field_size, width);
1187 vcap_copy_from_w32be(field->data.u48.mask, mask,
1188 field_size, width);
1189 break;
1190 case VCAP_FIELD_U56:
1191 vcap_copy_from_w32be(field->data.u56.value, value,
1192 field_size, width);
1193 vcap_copy_from_w32be(field->data.u56.mask, mask,
1194 field_size, width);
1195 break;
1196 case VCAP_FIELD_U64:
1197 vcap_copy_from_w32be(field->data.u64.value, value,
1198 field_size, width);
1199 vcap_copy_from_w32be(field->data.u64.mask, mask,
1200 field_size, width);
1201 break;
1202 case VCAP_FIELD_U72:
1203 vcap_copy_from_w32be(field->data.u72.value, value,
1204 field_size, width);
1205 vcap_copy_from_w32be(field->data.u72.mask, mask,
1206 field_size, width);
1207 break;
1208 case VCAP_FIELD_U112:
1209 vcap_copy_from_w32be(field->data.u112.value, value,
1210 field_size, width);
1211 vcap_copy_from_w32be(field->data.u112.mask, mask,
1212 field_size, width);
1213 break;
1214 case VCAP_FIELD_U128:
1215 vcap_copy_from_w32be(field->data.u128.value, value,
1216 field_size, width);
1217 vcap_copy_from_w32be(field->data.u128.mask, mask,
1218 field_size, width);
1219 break;
1220 };
1221 } else {
1222 switch (field->ctrl.type) {
1223 case VCAP_FIELD_BIT:
1224 vcap_copy_key_bit_field(&field->data.u1, value, mask);
1225 break;
1226 case VCAP_FIELD_U32:
1227 vcap_copy_limited_keyfield((u8 *)&field->data.u32.value,
1228 (u8 *)&field->data.u32.mask,
1229 value, mask,
1230 width, field_size);
1231 break;
1232 case VCAP_FIELD_U48:
1233 vcap_copy_limited_keyfield(field->data.u48.value,
1234 field->data.u48.mask,
1235 value, mask,
1236 width, field_size);
1237 break;
1238 case VCAP_FIELD_U56:
1239 vcap_copy_limited_keyfield(field->data.u56.value,
1240 field->data.u56.mask,
1241 value, mask,
1242 width, field_size);
1243 break;
1244 case VCAP_FIELD_U64:
1245 vcap_copy_limited_keyfield(field->data.u64.value,
1246 field->data.u64.mask,
1247 value, mask,
1248 width, field_size);
1249 break;
1250 case VCAP_FIELD_U72:
1251 vcap_copy_limited_keyfield(field->data.u72.value,
1252 field->data.u72.mask,
1253 value, mask,
1254 width, field_size);
1255 break;
1256 case VCAP_FIELD_U112:
1257 vcap_copy_limited_keyfield(field->data.u112.value,
1258 field->data.u112.mask,
1259 value, mask,
1260 width, field_size);
1261 break;
1262 case VCAP_FIELD_U128:
1263 vcap_copy_limited_keyfield(field->data.u128.value,
1264 field->data.u128.mask,
1265 value, mask,
1266 width, field_size);
1267 break;
1268 };
1269 }
1270 }
1271
vcap_rule_alloc_keyfield(struct vcap_rule_internal * ri,const struct vcap_field * keyfield,enum vcap_key_field key,u8 * value,u8 * mask)1272 static void vcap_rule_alloc_keyfield(struct vcap_rule_internal *ri,
1273 const struct vcap_field *keyfield,
1274 enum vcap_key_field key,
1275 u8 *value, u8 *mask)
1276 {
1277 struct vcap_client_keyfield *field;
1278
1279 field = kzalloc(sizeof(*field), GFP_KERNEL);
1280 if (!field)
1281 return;
1282 INIT_LIST_HEAD(&field->ctrl.list);
1283 field->ctrl.key = key;
1284 field->ctrl.type = keyfield->type;
1285 vcap_copy_to_client_keyfield(ri, field, value, mask, keyfield->width);
1286 list_add_tail(&field->ctrl.list, &ri->data.keyfields);
1287 }
1288
1289 /* Read key data from a VCAP address and discover if there is a rule keyset
1290 * here
1291 */
1292 static bool
vcap_verify_actionstream_actionset(struct vcap_control * vctrl,enum vcap_type vt,u32 * actionstream,enum vcap_actionfield_set actionset)1293 vcap_verify_actionstream_actionset(struct vcap_control *vctrl,
1294 enum vcap_type vt,
1295 u32 *actionstream,
1296 enum vcap_actionfield_set actionset)
1297 {
1298 const struct vcap_typegroup *tgt;
1299 const struct vcap_field *fields;
1300 const struct vcap_set *info;
1301
1302 if (vcap_actionfield_count(vctrl, vt, actionset) == 0)
1303 return false;
1304
1305 info = vcap_actionfieldset(vctrl, vt, actionset);
1306 /* Check that the actionset is valid */
1307 if (!info)
1308 return false;
1309
1310 /* a type_id of value -1 means that there is no type field */
1311 if (info->type_id == (u8)-1)
1312 return true;
1313
1314 /* Get a valid typegroup for the specific actionset */
1315 tgt = vcap_actionfield_typegroup(vctrl, vt, actionset);
1316 if (!tgt)
1317 return false;
1318
1319 fields = vcap_actionfields(vctrl, vt, actionset);
1320 if (!fields)
1321 return false;
1322
1323 /* Later this will be expanded with a check of the type id */
1324 return true;
1325 }
1326
1327 /* Find the subword width of the action typegroup that matches the stream data
1328 */
vcap_find_actionstream_typegroup_sw(struct vcap_control * vctrl,enum vcap_type vt,u32 * stream,int sw_max)1329 static int vcap_find_actionstream_typegroup_sw(struct vcap_control *vctrl,
1330 enum vcap_type vt, u32 *stream,
1331 int sw_max)
1332 {
1333 const struct vcap_typegroup **tgt;
1334 int sw_idx, res;
1335
1336 tgt = vctrl->vcaps[vt].actionfield_set_typegroups;
1337 /* Try the longest subword match first */
1338 for (sw_idx = vctrl->vcaps[vt].sw_count; sw_idx >= 0; sw_idx--) {
1339 if (!tgt[sw_idx])
1340 continue;
1341 res = vcap_verify_typegroups(stream, vctrl->vcaps[vt].act_width,
1342 tgt[sw_idx], false, sw_max);
1343 if (res == 0)
1344 return sw_idx;
1345 }
1346 return -EINVAL;
1347 }
1348
1349 /* Verify that the typegroup information, subword count, actionset and type id
1350 * are in sync and correct, return the actionset
1351 */
1352 static enum vcap_actionfield_set
vcap_find_actionstream_actionset(struct vcap_control * vctrl,enum vcap_type vt,u32 * stream,int sw_max)1353 vcap_find_actionstream_actionset(struct vcap_control *vctrl,
1354 enum vcap_type vt,
1355 u32 *stream,
1356 int sw_max)
1357 {
1358 const struct vcap_set *actionfield_set;
1359 int sw_count, idx;
1360 bool res;
1361
1362 sw_count = vcap_find_actionstream_typegroup_sw(vctrl, vt, stream,
1363 sw_max);
1364 if (sw_count < 0)
1365 return sw_count;
1366
1367 actionfield_set = vctrl->vcaps[vt].actionfield_set;
1368 for (idx = 0; idx < vctrl->vcaps[vt].actionfield_set_size; ++idx) {
1369 if (actionfield_set[idx].sw_per_item != sw_count)
1370 continue;
1371
1372 res = vcap_verify_actionstream_actionset(vctrl, vt,
1373 stream, idx);
1374 if (res)
1375 return idx;
1376 }
1377 return -EINVAL;
1378 }
1379
1380 /* Store action value in an element in a list for the client */
vcap_rule_alloc_actionfield(struct vcap_rule_internal * ri,const struct vcap_field * actionfield,enum vcap_action_field action,u8 * value)1381 static void vcap_rule_alloc_actionfield(struct vcap_rule_internal *ri,
1382 const struct vcap_field *actionfield,
1383 enum vcap_action_field action,
1384 u8 *value)
1385 {
1386 struct vcap_client_actionfield *field;
1387
1388 field = kzalloc(sizeof(*field), GFP_KERNEL);
1389 if (!field)
1390 return;
1391 INIT_LIST_HEAD(&field->ctrl.list);
1392 field->ctrl.action = action;
1393 field->ctrl.type = actionfield->type;
1394 vcap_copy_to_client_actionfield(ri, field, value, actionfield->width);
1395 list_add_tail(&field->ctrl.list, &ri->data.actionfields);
1396 }
1397
vcap_decode_actionset(struct vcap_rule_internal * ri)1398 static int vcap_decode_actionset(struct vcap_rule_internal *ri)
1399 {
1400 struct vcap_control *vctrl = ri->vctrl;
1401 struct vcap_admin *admin = ri->admin;
1402 const struct vcap_field *actionfield;
1403 enum vcap_actionfield_set actionset;
1404 enum vcap_type vt = admin->vtype;
1405 const struct vcap_typegroup *tgt;
1406 struct vcap_stream_iter iter;
1407 int idx, res, actfield_count;
1408 u32 *actstream;
1409 u8 value[16];
1410
1411 actstream = admin->cache.actionstream;
1412 res = vcap_find_actionstream_actionset(vctrl, vt, actstream, 0);
1413 if (res < 0) {
1414 pr_err("%s:%d: could not find valid actionset: %d\n",
1415 __func__, __LINE__, res);
1416 return -EINVAL;
1417 }
1418 actionset = res;
1419 actfield_count = vcap_actionfield_count(vctrl, vt, actionset);
1420 actionfield = vcap_actionfields(vctrl, vt, actionset);
1421 tgt = vcap_actionfield_typegroup(vctrl, vt, actionset);
1422 /* Start decoding the stream */
1423 for (idx = 0; idx < actfield_count; ++idx) {
1424 if (actionfield[idx].width <= 0)
1425 continue;
1426 /* Get the action */
1427 memset(value, 0, DIV_ROUND_UP(actionfield[idx].width, 8));
1428 vcap_iter_init(&iter, vctrl->vcaps[vt].act_width, tgt,
1429 actionfield[idx].offset);
1430 vcap_decode_field(actstream, &iter, actionfield[idx].width,
1431 value);
1432 /* Skip if no bits are set */
1433 if (vcap_bitarray_zero(actionfield[idx].width, value))
1434 continue;
1435 vcap_rule_alloc_actionfield(ri, &actionfield[idx], idx, value);
1436 /* Later the action id will also be checked */
1437 }
1438 return vcap_set_rule_set_actionset((struct vcap_rule *)ri, actionset);
1439 }
1440
vcap_decode_keyset(struct vcap_rule_internal * ri)1441 static int vcap_decode_keyset(struct vcap_rule_internal *ri)
1442 {
1443 struct vcap_control *vctrl = ri->vctrl;
1444 struct vcap_stream_iter kiter, miter;
1445 struct vcap_admin *admin = ri->admin;
1446 enum vcap_keyfield_set keysets[10];
1447 const struct vcap_field *keyfield;
1448 enum vcap_type vt = admin->vtype;
1449 const struct vcap_typegroup *tgt;
1450 struct vcap_keyset_list matches;
1451 enum vcap_keyfield_set keyset;
1452 int idx, res, keyfield_count;
1453 u32 *maskstream;
1454 u32 *keystream;
1455 u8 value[16];
1456 u8 mask[16];
1457
1458 keystream = admin->cache.keystream;
1459 maskstream = admin->cache.maskstream;
1460 matches.keysets = keysets;
1461 matches.cnt = 0;
1462 matches.max = ARRAY_SIZE(keysets);
1463 res = vcap_find_keystream_keysets(vctrl, vt, keystream, maskstream,
1464 false, 0, &matches);
1465 if (res < 0) {
1466 pr_err("%s:%d: could not find valid keysets: %d\n",
1467 __func__, __LINE__, res);
1468 return -EINVAL;
1469 }
1470 keyset = matches.keysets[0];
1471 keyfield_count = vcap_keyfield_count(vctrl, vt, keyset);
1472 keyfield = vcap_keyfields(vctrl, vt, keyset);
1473 tgt = vcap_keyfield_typegroup(vctrl, vt, keyset);
1474 /* Start decoding the streams */
1475 for (idx = 0; idx < keyfield_count; ++idx) {
1476 if (keyfield[idx].width <= 0)
1477 continue;
1478 /* First get the mask */
1479 memset(mask, 0, DIV_ROUND_UP(keyfield[idx].width, 8));
1480 vcap_iter_init(&miter, vctrl->vcaps[vt].sw_width, tgt,
1481 keyfield[idx].offset);
1482 vcap_decode_field(maskstream, &miter, keyfield[idx].width,
1483 mask);
1484 /* Skip if no mask bits are set */
1485 if (vcap_bitarray_zero(keyfield[idx].width, mask))
1486 continue;
1487 /* Get the key */
1488 memset(value, 0, DIV_ROUND_UP(keyfield[idx].width, 8));
1489 vcap_iter_init(&kiter, vctrl->vcaps[vt].sw_width, tgt,
1490 keyfield[idx].offset);
1491 vcap_decode_field(keystream, &kiter, keyfield[idx].width,
1492 value);
1493 vcap_rule_alloc_keyfield(ri, &keyfield[idx], idx, value, mask);
1494 }
1495 return vcap_set_rule_set_keyset((struct vcap_rule *)ri, keyset);
1496 }
1497
1498 /* Read VCAP content into the VCAP cache */
vcap_read_rule(struct vcap_rule_internal * ri)1499 static int vcap_read_rule(struct vcap_rule_internal *ri)
1500 {
1501 struct vcap_admin *admin = ri->admin;
1502 int sw_idx, ent_idx = 0, act_idx = 0;
1503 u32 addr = ri->addr;
1504
1505 if (!ri->size || !ri->keyset_sw_regs || !ri->actionset_sw_regs) {
1506 pr_err("%s:%d: rule is empty\n", __func__, __LINE__);
1507 return -EINVAL;
1508 }
1509 vcap_erase_cache(ri);
1510 /* Use the values in the streams to read the VCAP cache */
1511 for (sw_idx = 0; sw_idx < ri->size; sw_idx++, addr++) {
1512 ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ,
1513 VCAP_SEL_ALL, addr);
1514 ri->vctrl->ops->cache_read(ri->ndev, admin,
1515 VCAP_SEL_ENTRY, ent_idx,
1516 ri->keyset_sw_regs);
1517 ri->vctrl->ops->cache_read(ri->ndev, admin,
1518 VCAP_SEL_ACTION, act_idx,
1519 ri->actionset_sw_regs);
1520 if (sw_idx == 0)
1521 ri->vctrl->ops->cache_read(ri->ndev, admin,
1522 VCAP_SEL_COUNTER,
1523 ri->counter_id, 0);
1524 ent_idx += ri->keyset_sw_regs;
1525 act_idx += ri->actionset_sw_regs;
1526 }
1527 return 0;
1528 }
1529
1530 /* Write VCAP cache content to the VCAP HW instance */
vcap_write_rule(struct vcap_rule_internal * ri)1531 static int vcap_write_rule(struct vcap_rule_internal *ri)
1532 {
1533 struct vcap_admin *admin = ri->admin;
1534 int sw_idx, ent_idx = 0, act_idx = 0;
1535 u32 addr = ri->addr;
1536
1537 if (!ri->size || !ri->keyset_sw_regs || !ri->actionset_sw_regs) {
1538 pr_err("%s:%d: rule is empty\n", __func__, __LINE__);
1539 return -EINVAL;
1540 }
1541 /* Use the values in the streams to write the VCAP cache */
1542 for (sw_idx = 0; sw_idx < ri->size; sw_idx++, addr++) {
1543 ri->vctrl->ops->cache_write(ri->ndev, admin,
1544 VCAP_SEL_ENTRY, ent_idx,
1545 ri->keyset_sw_regs);
1546 ri->vctrl->ops->cache_write(ri->ndev, admin,
1547 VCAP_SEL_ACTION, act_idx,
1548 ri->actionset_sw_regs);
1549 ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_WRITE,
1550 VCAP_SEL_ALL, addr);
1551 ent_idx += ri->keyset_sw_regs;
1552 act_idx += ri->actionset_sw_regs;
1553 }
1554 return 0;
1555 }
1556
vcap_write_counter(struct vcap_rule_internal * ri,struct vcap_counter * ctr)1557 static int vcap_write_counter(struct vcap_rule_internal *ri,
1558 struct vcap_counter *ctr)
1559 {
1560 struct vcap_admin *admin = ri->admin;
1561
1562 admin->cache.counter = ctr->value;
1563 admin->cache.sticky = ctr->sticky;
1564 ri->vctrl->ops->cache_write(ri->ndev, admin, VCAP_SEL_COUNTER,
1565 ri->counter_id, 0);
1566 ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_WRITE,
1567 VCAP_SEL_COUNTER, ri->addr);
1568 return 0;
1569 }
1570
1571 /* Convert a chain id to a VCAP lookup index */
vcap_chain_id_to_lookup(struct vcap_admin * admin,int cur_cid)1572 int vcap_chain_id_to_lookup(struct vcap_admin *admin, int cur_cid)
1573 {
1574 int lookup_first = admin->vinst * admin->lookups_per_instance;
1575 int lookup_last = lookup_first + admin->lookups_per_instance;
1576 int cid_next = admin->first_cid + VCAP_CID_LOOKUP_SIZE;
1577 int cid = admin->first_cid;
1578 int lookup;
1579
1580 for (lookup = lookup_first; lookup < lookup_last; ++lookup,
1581 cid += VCAP_CID_LOOKUP_SIZE, cid_next += VCAP_CID_LOOKUP_SIZE)
1582 if (cur_cid >= cid && cur_cid < cid_next)
1583 return lookup;
1584 return 0;
1585 }
1586 EXPORT_SYMBOL_GPL(vcap_chain_id_to_lookup);
1587
1588 /* Lookup a vcap instance using chain id */
vcap_find_admin(struct vcap_control * vctrl,int cid)1589 struct vcap_admin *vcap_find_admin(struct vcap_control *vctrl, int cid)
1590 {
1591 struct vcap_admin *admin;
1592
1593 if (vcap_api_check(vctrl))
1594 return NULL;
1595
1596 list_for_each_entry(admin, &vctrl->list, list) {
1597 if (cid >= admin->first_cid && cid <= admin->last_cid)
1598 return admin;
1599 }
1600 return NULL;
1601 }
1602 EXPORT_SYMBOL_GPL(vcap_find_admin);
1603
1604 /* Is this the last admin instance ordered by chain id and direction */
vcap_admin_is_last(struct vcap_control * vctrl,struct vcap_admin * admin,bool ingress)1605 static bool vcap_admin_is_last(struct vcap_control *vctrl,
1606 struct vcap_admin *admin,
1607 bool ingress)
1608 {
1609 struct vcap_admin *iter, *last = NULL;
1610 int max_cid = 0;
1611
1612 list_for_each_entry(iter, &vctrl->list, list) {
1613 if (iter->first_cid > max_cid &&
1614 iter->ingress == ingress) {
1615 last = iter;
1616 max_cid = iter->first_cid;
1617 }
1618 }
1619 if (!last)
1620 return false;
1621
1622 return admin == last;
1623 }
1624
1625 /* Calculate the value used for chaining VCAP rules */
vcap_chain_offset(struct vcap_control * vctrl,int from_cid,int to_cid)1626 int vcap_chain_offset(struct vcap_control *vctrl, int from_cid, int to_cid)
1627 {
1628 int diff = to_cid - from_cid;
1629
1630 if (diff < 0) /* Wrong direction */
1631 return diff;
1632 to_cid %= VCAP_CID_LOOKUP_SIZE;
1633 if (to_cid == 0) /* Destination aligned to a lookup == no chaining */
1634 return 0;
1635 diff %= VCAP_CID_LOOKUP_SIZE; /* Limit to a value within a lookup */
1636 return diff;
1637 }
1638 EXPORT_SYMBOL_GPL(vcap_chain_offset);
1639
1640 /* Is the next chain id in one of the following lookups
1641 * For now this does not support filters linked to other filters using
1642 * keys and actions. That will be added later.
1643 */
vcap_is_next_lookup(struct vcap_control * vctrl,int src_cid,int dst_cid)1644 bool vcap_is_next_lookup(struct vcap_control *vctrl, int src_cid, int dst_cid)
1645 {
1646 struct vcap_admin *admin;
1647 int next_cid;
1648
1649 if (vcap_api_check(vctrl))
1650 return false;
1651
1652 /* The offset must be at least one lookup so round up one chain */
1653 next_cid = roundup(src_cid + 1, VCAP_CID_LOOKUP_SIZE);
1654
1655 if (dst_cid < next_cid)
1656 return false;
1657
1658 admin = vcap_find_admin(vctrl, dst_cid);
1659 if (!admin)
1660 return false;
1661
1662 return true;
1663 }
1664 EXPORT_SYMBOL_GPL(vcap_is_next_lookup);
1665
1666 /* Check if there is room for a new rule */
vcap_rule_space(struct vcap_admin * admin,int size)1667 static int vcap_rule_space(struct vcap_admin *admin, int size)
1668 {
1669 if (admin->last_used_addr - size < admin->first_valid_addr) {
1670 pr_err("%s:%d: No room for rule size: %u, %u\n",
1671 __func__, __LINE__, size, admin->first_valid_addr);
1672 return -ENOSPC;
1673 }
1674 return 0;
1675 }
1676
1677 /* Add the keyset typefield to the list of rule keyfields */
vcap_add_type_keyfield(struct vcap_rule * rule)1678 static int vcap_add_type_keyfield(struct vcap_rule *rule)
1679 {
1680 struct vcap_rule_internal *ri = to_intrule(rule);
1681 enum vcap_keyfield_set keyset = rule->keyset;
1682 enum vcap_type vt = ri->admin->vtype;
1683 const struct vcap_field *fields;
1684 const struct vcap_set *kset;
1685 int ret = -EINVAL;
1686
1687 kset = vcap_keyfieldset(ri->vctrl, vt, keyset);
1688 if (!kset)
1689 return ret;
1690 if (kset->type_id == (u8)-1) /* No type field is needed */
1691 return 0;
1692
1693 fields = vcap_keyfields(ri->vctrl, vt, keyset);
1694 if (!fields)
1695 return -EINVAL;
1696 if (fields[VCAP_KF_TYPE].width > 1) {
1697 ret = vcap_rule_add_key_u32(rule, VCAP_KF_TYPE,
1698 kset->type_id, 0xff);
1699 } else {
1700 if (kset->type_id)
1701 ret = vcap_rule_add_key_bit(rule, VCAP_KF_TYPE,
1702 VCAP_BIT_1);
1703 else
1704 ret = vcap_rule_add_key_bit(rule, VCAP_KF_TYPE,
1705 VCAP_BIT_0);
1706 }
1707 return 0;
1708 }
1709
1710 /* Add the actionset typefield to the list of rule actionfields */
vcap_add_type_actionfield(struct vcap_rule * rule)1711 static int vcap_add_type_actionfield(struct vcap_rule *rule)
1712 {
1713 enum vcap_actionfield_set actionset = rule->actionset;
1714 struct vcap_rule_internal *ri = to_intrule(rule);
1715 enum vcap_type vt = ri->admin->vtype;
1716 const struct vcap_field *fields;
1717 const struct vcap_set *aset;
1718 int ret = -EINVAL;
1719
1720 aset = vcap_actionfieldset(ri->vctrl, vt, actionset);
1721 if (!aset)
1722 return ret;
1723 if (aset->type_id == (u8)-1) /* No type field is needed */
1724 return 0;
1725
1726 fields = vcap_actionfields(ri->vctrl, vt, actionset);
1727 if (!fields)
1728 return -EINVAL;
1729 if (fields[VCAP_AF_TYPE].width > 1) {
1730 ret = vcap_rule_add_action_u32(rule, VCAP_AF_TYPE,
1731 aset->type_id);
1732 } else {
1733 if (aset->type_id)
1734 ret = vcap_rule_add_action_bit(rule, VCAP_AF_TYPE,
1735 VCAP_BIT_1);
1736 else
1737 ret = vcap_rule_add_action_bit(rule, VCAP_AF_TYPE,
1738 VCAP_BIT_0);
1739 }
1740 return ret;
1741 }
1742
1743 /* Add a keyset to a keyset list */
vcap_keyset_list_add(struct vcap_keyset_list * keysetlist,enum vcap_keyfield_set keyset)1744 bool vcap_keyset_list_add(struct vcap_keyset_list *keysetlist,
1745 enum vcap_keyfield_set keyset)
1746 {
1747 int idx;
1748
1749 if (keysetlist->cnt < keysetlist->max) {
1750 /* Avoid duplicates */
1751 for (idx = 0; idx < keysetlist->cnt; ++idx)
1752 if (keysetlist->keysets[idx] == keyset)
1753 return keysetlist->cnt < keysetlist->max;
1754 keysetlist->keysets[keysetlist->cnt++] = keyset;
1755 }
1756 return keysetlist->cnt < keysetlist->max;
1757 }
1758 EXPORT_SYMBOL_GPL(vcap_keyset_list_add);
1759
1760 /* Add a actionset to a actionset list */
vcap_actionset_list_add(struct vcap_actionset_list * actionsetlist,enum vcap_actionfield_set actionset)1761 static bool vcap_actionset_list_add(struct vcap_actionset_list *actionsetlist,
1762 enum vcap_actionfield_set actionset)
1763 {
1764 int idx;
1765
1766 if (actionsetlist->cnt < actionsetlist->max) {
1767 /* Avoid duplicates */
1768 for (idx = 0; idx < actionsetlist->cnt; ++idx)
1769 if (actionsetlist->actionsets[idx] == actionset)
1770 return actionsetlist->cnt < actionsetlist->max;
1771 actionsetlist->actionsets[actionsetlist->cnt++] = actionset;
1772 }
1773 return actionsetlist->cnt < actionsetlist->max;
1774 }
1775
1776 /* map keyset id to a string with the keyset name */
vcap_keyset_name(struct vcap_control * vctrl,enum vcap_keyfield_set keyset)1777 const char *vcap_keyset_name(struct vcap_control *vctrl,
1778 enum vcap_keyfield_set keyset)
1779 {
1780 return vctrl->stats->keyfield_set_names[keyset];
1781 }
1782 EXPORT_SYMBOL_GPL(vcap_keyset_name);
1783
1784 /* map key field id to a string with the key name */
vcap_keyfield_name(struct vcap_control * vctrl,enum vcap_key_field key)1785 const char *vcap_keyfield_name(struct vcap_control *vctrl,
1786 enum vcap_key_field key)
1787 {
1788 return vctrl->stats->keyfield_names[key];
1789 }
1790 EXPORT_SYMBOL_GPL(vcap_keyfield_name);
1791
1792 /* map actionset id to a string with the actionset name */
vcap_actionset_name(struct vcap_control * vctrl,enum vcap_actionfield_set actionset)1793 const char *vcap_actionset_name(struct vcap_control *vctrl,
1794 enum vcap_actionfield_set actionset)
1795 {
1796 return vctrl->stats->actionfield_set_names[actionset];
1797 }
1798
1799 /* map action field id to a string with the action name */
vcap_actionfield_name(struct vcap_control * vctrl,enum vcap_action_field action)1800 const char *vcap_actionfield_name(struct vcap_control *vctrl,
1801 enum vcap_action_field action)
1802 {
1803 return vctrl->stats->actionfield_names[action];
1804 }
1805
1806 /* Return the keyfield that matches a key in a keyset */
1807 static const struct vcap_field *
vcap_find_keyset_keyfield(struct vcap_control * vctrl,enum vcap_type vtype,enum vcap_keyfield_set keyset,enum vcap_key_field key)1808 vcap_find_keyset_keyfield(struct vcap_control *vctrl,
1809 enum vcap_type vtype,
1810 enum vcap_keyfield_set keyset,
1811 enum vcap_key_field key)
1812 {
1813 const struct vcap_field *fields;
1814 int idx, count;
1815
1816 fields = vcap_keyfields(vctrl, vtype, keyset);
1817 if (!fields)
1818 return NULL;
1819
1820 /* Iterate the keyfields of the keyset */
1821 count = vcap_keyfield_count(vctrl, vtype, keyset);
1822 for (idx = 0; idx < count; ++idx) {
1823 if (fields[idx].width == 0)
1824 continue;
1825
1826 if (key == idx)
1827 return &fields[idx];
1828 }
1829
1830 return NULL;
1831 }
1832
1833 /* Match a list of keys against the keysets available in a vcap type */
_vcap_rule_find_keysets(struct vcap_rule_internal * ri,struct vcap_keyset_list * matches)1834 static bool _vcap_rule_find_keysets(struct vcap_rule_internal *ri,
1835 struct vcap_keyset_list *matches)
1836 {
1837 const struct vcap_client_keyfield *ckf;
1838 int keyset, found, keycount, map_size;
1839 const struct vcap_field **map;
1840 enum vcap_type vtype;
1841
1842 vtype = ri->admin->vtype;
1843 map = ri->vctrl->vcaps[vtype].keyfield_set_map;
1844 map_size = ri->vctrl->vcaps[vtype].keyfield_set_size;
1845
1846 /* Get a count of the keyfields we want to match */
1847 keycount = 0;
1848 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list)
1849 ++keycount;
1850
1851 matches->cnt = 0;
1852 /* Iterate the keysets of the VCAP */
1853 for (keyset = 0; keyset < map_size; ++keyset) {
1854 if (!map[keyset])
1855 continue;
1856
1857 /* Iterate the keys in the rule */
1858 found = 0;
1859 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list)
1860 if (vcap_find_keyset_keyfield(ri->vctrl, vtype,
1861 keyset, ckf->ctrl.key))
1862 ++found;
1863
1864 /* Save the keyset if all keyfields were found */
1865 if (found == keycount)
1866 if (!vcap_keyset_list_add(matches, keyset))
1867 /* bail out when the quota is filled */
1868 break;
1869 }
1870
1871 return matches->cnt > 0;
1872 }
1873
1874 /* Match a list of keys against the keysets available in a vcap type */
vcap_rule_find_keysets(struct vcap_rule * rule,struct vcap_keyset_list * matches)1875 bool vcap_rule_find_keysets(struct vcap_rule *rule,
1876 struct vcap_keyset_list *matches)
1877 {
1878 struct vcap_rule_internal *ri = to_intrule(rule);
1879
1880 return _vcap_rule_find_keysets(ri, matches);
1881 }
1882 EXPORT_SYMBOL_GPL(vcap_rule_find_keysets);
1883
1884 /* Return the actionfield that matches a action in a actionset */
1885 static const struct vcap_field *
vcap_find_actionset_actionfield(struct vcap_control * vctrl,enum vcap_type vtype,enum vcap_actionfield_set actionset,enum vcap_action_field action)1886 vcap_find_actionset_actionfield(struct vcap_control *vctrl,
1887 enum vcap_type vtype,
1888 enum vcap_actionfield_set actionset,
1889 enum vcap_action_field action)
1890 {
1891 const struct vcap_field *fields;
1892 int idx, count;
1893
1894 fields = vcap_actionfields(vctrl, vtype, actionset);
1895 if (!fields)
1896 return NULL;
1897
1898 /* Iterate the actionfields of the actionset */
1899 count = vcap_actionfield_count(vctrl, vtype, actionset);
1900 for (idx = 0; idx < count; ++idx) {
1901 if (fields[idx].width == 0)
1902 continue;
1903
1904 if (action == idx)
1905 return &fields[idx];
1906 }
1907
1908 return NULL;
1909 }
1910
1911 /* Match a list of actions against the actionsets available in a vcap type */
vcap_rule_find_actionsets(struct vcap_rule_internal * ri,struct vcap_actionset_list * matches)1912 static bool vcap_rule_find_actionsets(struct vcap_rule_internal *ri,
1913 struct vcap_actionset_list *matches)
1914 {
1915 int actionset, found, actioncount, map_size;
1916 const struct vcap_client_actionfield *ckf;
1917 const struct vcap_field **map;
1918 enum vcap_type vtype;
1919
1920 vtype = ri->admin->vtype;
1921 map = ri->vctrl->vcaps[vtype].actionfield_set_map;
1922 map_size = ri->vctrl->vcaps[vtype].actionfield_set_size;
1923
1924 /* Get a count of the actionfields we want to match */
1925 actioncount = 0;
1926 list_for_each_entry(ckf, &ri->data.actionfields, ctrl.list)
1927 ++actioncount;
1928
1929 matches->cnt = 0;
1930 /* Iterate the actionsets of the VCAP */
1931 for (actionset = 0; actionset < map_size; ++actionset) {
1932 if (!map[actionset])
1933 continue;
1934
1935 /* Iterate the actions in the rule */
1936 found = 0;
1937 list_for_each_entry(ckf, &ri->data.actionfields, ctrl.list)
1938 if (vcap_find_actionset_actionfield(ri->vctrl, vtype,
1939 actionset,
1940 ckf->ctrl.action))
1941 ++found;
1942
1943 /* Save the actionset if all actionfields were found */
1944 if (found == actioncount)
1945 if (!vcap_actionset_list_add(matches, actionset))
1946 /* bail out when the quota is filled */
1947 break;
1948 }
1949
1950 return matches->cnt > 0;
1951 }
1952
1953 /* Validate a rule with respect to available port keys */
vcap_val_rule(struct vcap_rule * rule,u16 l3_proto)1954 int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto)
1955 {
1956 struct vcap_rule_internal *ri = to_intrule(rule);
1957 struct vcap_keyset_list matches = {};
1958 enum vcap_keyfield_set keysets[10];
1959 int ret;
1960
1961 ret = vcap_api_check(ri->vctrl);
1962 if (ret)
1963 return ret;
1964 if (!ri->admin) {
1965 ri->data.exterr = VCAP_ERR_NO_ADMIN;
1966 return -EINVAL;
1967 }
1968 if (!ri->ndev) {
1969 ri->data.exterr = VCAP_ERR_NO_NETDEV;
1970 return -EINVAL;
1971 }
1972
1973 matches.keysets = keysets;
1974 matches.max = ARRAY_SIZE(keysets);
1975 if (ri->data.keyset == VCAP_KFS_NO_VALUE) {
1976 /* Iterate over rule keyfields and select keysets that fits */
1977 if (!_vcap_rule_find_keysets(ri, &matches)) {
1978 ri->data.exterr = VCAP_ERR_NO_KEYSET_MATCH;
1979 return -EINVAL;
1980 }
1981 } else {
1982 /* prepare for keyset validation */
1983 keysets[0] = ri->data.keyset;
1984 matches.cnt = 1;
1985 }
1986
1987 /* Pick a keyset that is supported in the port lookups */
1988 ret = ri->vctrl->ops->validate_keyset(ri->ndev, ri->admin, rule,
1989 &matches, l3_proto);
1990 if (ret < 0) {
1991 pr_err("%s:%d: keyset validation failed: %d\n",
1992 __func__, __LINE__, ret);
1993 ri->data.exterr = VCAP_ERR_NO_PORT_KEYSET_MATCH;
1994 return ret;
1995 }
1996 /* use the keyset that is supported in the port lookups */
1997 ret = vcap_set_rule_set_keyset(rule, ret);
1998 if (ret < 0) {
1999 pr_err("%s:%d: keyset was not updated: %d\n",
2000 __func__, __LINE__, ret);
2001 return ret;
2002 }
2003 if (ri->data.actionset == VCAP_AFS_NO_VALUE) {
2004 struct vcap_actionset_list matches = {};
2005 enum vcap_actionfield_set actionsets[10];
2006
2007 matches.actionsets = actionsets;
2008 matches.max = ARRAY_SIZE(actionsets);
2009
2010 /* Find an actionset that fits the rule actions */
2011 if (!vcap_rule_find_actionsets(ri, &matches)) {
2012 ri->data.exterr = VCAP_ERR_NO_ACTIONSET_MATCH;
2013 return -EINVAL;
2014 }
2015 ret = vcap_set_rule_set_actionset(rule, actionsets[0]);
2016 if (ret < 0) {
2017 pr_err("%s:%d: actionset was not updated: %d\n",
2018 __func__, __LINE__, ret);
2019 return ret;
2020 }
2021 }
2022 vcap_add_type_keyfield(rule);
2023 vcap_add_type_actionfield(rule);
2024 /* Add default fields to this rule */
2025 ri->vctrl->ops->add_default_fields(ri->ndev, ri->admin, rule);
2026
2027 /* Rule size is the maximum of the entry and action subword count */
2028 ri->size = max(ri->keyset_sw, ri->actionset_sw);
2029
2030 /* Finally check if there is room for the rule in the VCAP */
2031 return vcap_rule_space(ri->admin, ri->size);
2032 }
2033 EXPORT_SYMBOL_GPL(vcap_val_rule);
2034
2035 /* Entries are sorted with increasing values of sort_key.
2036 * I.e. Lowest numerical sort_key is first in list.
2037 * In order to locate largest keys first in list we negate the key size with
2038 * (max_size - size).
2039 */
vcap_sort_key(u32 max_size,u32 size,u8 user,u16 prio)2040 static u32 vcap_sort_key(u32 max_size, u32 size, u8 user, u16 prio)
2041 {
2042 return ((max_size - size) << 24) | (user << 16) | prio;
2043 }
2044
2045 /* calculate the address of the next rule after this (lower address and prio) */
vcap_next_rule_addr(u32 addr,struct vcap_rule_internal * ri)2046 static u32 vcap_next_rule_addr(u32 addr, struct vcap_rule_internal *ri)
2047 {
2048 return ((addr - ri->size) / ri->size) * ri->size;
2049 }
2050
2051 /* Assign a unique rule id and autogenerate one if id == 0 */
vcap_set_rule_id(struct vcap_rule_internal * ri)2052 static u32 vcap_set_rule_id(struct vcap_rule_internal *ri)
2053 {
2054 if (ri->data.id != 0)
2055 return ri->data.id;
2056
2057 for (u32 next_id = 1; next_id < ~0; ++next_id) {
2058 if (!vcap_rule_exists(ri->vctrl, next_id)) {
2059 ri->data.id = next_id;
2060 break;
2061 }
2062 }
2063 return ri->data.id;
2064 }
2065
vcap_insert_rule(struct vcap_rule_internal * ri,struct vcap_rule_move * move)2066 static int vcap_insert_rule(struct vcap_rule_internal *ri,
2067 struct vcap_rule_move *move)
2068 {
2069 int sw_count = ri->vctrl->vcaps[ri->admin->vtype].sw_count;
2070 struct vcap_rule_internal *duprule, *iter, *elem = NULL;
2071 struct vcap_admin *admin = ri->admin;
2072 u32 addr;
2073
2074 ri->sort_key = vcap_sort_key(sw_count, ri->size, ri->data.user,
2075 ri->data.priority);
2076
2077 /* Insert the new rule in the list of rule based on the sort key
2078 * If the rule needs to be inserted between existing rules then move
2079 * these rules to make room for the new rule and update their start
2080 * address.
2081 */
2082 list_for_each_entry(iter, &admin->rules, list) {
2083 if (ri->sort_key < iter->sort_key) {
2084 elem = iter;
2085 break;
2086 }
2087 }
2088
2089 if (!elem) {
2090 ri->addr = vcap_next_rule_addr(admin->last_used_addr, ri);
2091 admin->last_used_addr = ri->addr;
2092
2093 /* Add a copy of the rule to the VCAP list */
2094 duprule = vcap_dup_rule(ri, ri->state == VCAP_RS_DISABLED);
2095 if (IS_ERR(duprule))
2096 return PTR_ERR(duprule);
2097
2098 list_add_tail(&duprule->list, &admin->rules);
2099 return 0;
2100 }
2101
2102 /* Reuse the space of the current rule */
2103 addr = elem->addr + elem->size;
2104 ri->addr = vcap_next_rule_addr(addr, ri);
2105 addr = ri->addr;
2106
2107 /* Add a copy of the rule to the VCAP list */
2108 duprule = vcap_dup_rule(ri, ri->state == VCAP_RS_DISABLED);
2109 if (IS_ERR(duprule))
2110 return PTR_ERR(duprule);
2111
2112 /* Add before the current entry */
2113 list_add_tail(&duprule->list, &elem->list);
2114
2115 /* Update the current rule */
2116 elem->addr = vcap_next_rule_addr(addr, elem);
2117 addr = elem->addr;
2118
2119 /* Update the address in the remaining rules in the list */
2120 list_for_each_entry_continue(elem, &admin->rules, list) {
2121 elem->addr = vcap_next_rule_addr(addr, elem);
2122 addr = elem->addr;
2123 }
2124
2125 /* Update the move info */
2126 move->addr = admin->last_used_addr;
2127 move->count = ri->addr - addr;
2128 move->offset = admin->last_used_addr - addr;
2129 admin->last_used_addr = addr;
2130 return 0;
2131 }
2132
vcap_move_rules(struct vcap_rule_internal * ri,struct vcap_rule_move * move)2133 static void vcap_move_rules(struct vcap_rule_internal *ri,
2134 struct vcap_rule_move *move)
2135 {
2136 ri->vctrl->ops->move(ri->ndev, ri->admin, move->addr,
2137 move->offset, move->count);
2138 }
2139
2140 /* Check if the chain is already used to enable a VCAP lookup for this port */
vcap_is_chain_used(struct vcap_control * vctrl,struct net_device * ndev,int src_cid)2141 static bool vcap_is_chain_used(struct vcap_control *vctrl,
2142 struct net_device *ndev, int src_cid)
2143 {
2144 struct vcap_enabled_port *eport;
2145 struct vcap_admin *admin;
2146
2147 list_for_each_entry(admin, &vctrl->list, list)
2148 list_for_each_entry(eport, &admin->enabled, list)
2149 if (eport->src_cid == src_cid && eport->ndev == ndev)
2150 return true;
2151
2152 return false;
2153 }
2154
2155 /* Fetch the next chain in the enabled list for the port */
vcap_get_next_chain(struct vcap_control * vctrl,struct net_device * ndev,int dst_cid)2156 static int vcap_get_next_chain(struct vcap_control *vctrl,
2157 struct net_device *ndev,
2158 int dst_cid)
2159 {
2160 struct vcap_enabled_port *eport;
2161 struct vcap_admin *admin;
2162
2163 list_for_each_entry(admin, &vctrl->list, list) {
2164 list_for_each_entry(eport, &admin->enabled, list) {
2165 if (eport->ndev != ndev)
2166 continue;
2167 if (eport->src_cid == dst_cid)
2168 return eport->dst_cid;
2169 }
2170 }
2171
2172 return 0;
2173 }
2174
vcap_path_exist(struct vcap_control * vctrl,struct net_device * ndev,int dst_cid)2175 static bool vcap_path_exist(struct vcap_control *vctrl, struct net_device *ndev,
2176 int dst_cid)
2177 {
2178 int cid = rounddown(dst_cid, VCAP_CID_LOOKUP_SIZE);
2179 struct vcap_enabled_port *eport = NULL;
2180 struct vcap_enabled_port *elem;
2181 struct vcap_admin *admin;
2182 int tmp;
2183
2184 if (cid == 0) /* Chain zero is always available */
2185 return true;
2186
2187 /* Find first entry that starts from chain 0*/
2188 list_for_each_entry(admin, &vctrl->list, list) {
2189 list_for_each_entry(elem, &admin->enabled, list) {
2190 if (elem->src_cid == 0 && elem->ndev == ndev) {
2191 eport = elem;
2192 break;
2193 }
2194 }
2195 if (eport)
2196 break;
2197 }
2198
2199 if (!eport)
2200 return false;
2201
2202 tmp = eport->dst_cid;
2203 while (tmp != cid && tmp != 0)
2204 tmp = vcap_get_next_chain(vctrl, ndev, tmp);
2205
2206 return !!tmp;
2207 }
2208
2209 /* Internal clients can always store their rules in HW
2210 * External clients can store their rules if the chain is enabled all
2211 * the way from chain 0, otherwise the rule will be cached until
2212 * the chain is enabled.
2213 */
vcap_rule_set_state(struct vcap_rule_internal * ri)2214 static void vcap_rule_set_state(struct vcap_rule_internal *ri)
2215 {
2216 if (ri->data.user <= VCAP_USER_QOS)
2217 ri->state = VCAP_RS_PERMANENT;
2218 else if (vcap_path_exist(ri->vctrl, ri->ndev, ri->data.vcap_chain_id))
2219 ri->state = VCAP_RS_ENABLED;
2220 else
2221 ri->state = VCAP_RS_DISABLED;
2222 }
2223
2224 /* Encode and write a validated rule to the VCAP */
vcap_add_rule(struct vcap_rule * rule)2225 int vcap_add_rule(struct vcap_rule *rule)
2226 {
2227 struct vcap_rule_internal *ri = to_intrule(rule);
2228 struct vcap_rule_move move = {0};
2229 struct vcap_counter ctr = {0};
2230 int ret;
2231
2232 ret = vcap_api_check(ri->vctrl);
2233 if (ret)
2234 return ret;
2235 /* Insert the new rule in the list of vcap rules */
2236 mutex_lock(&ri->admin->lock);
2237
2238 vcap_rule_set_state(ri);
2239 ret = vcap_insert_rule(ri, &move);
2240 if (ret < 0) {
2241 pr_err("%s:%d: could not insert rule in vcap list: %d\n",
2242 __func__, __LINE__, ret);
2243 goto out;
2244 }
2245 if (move.count > 0)
2246 vcap_move_rules(ri, &move);
2247
2248 /* Set the counter to zero */
2249 ret = vcap_write_counter(ri, &ctr);
2250 if (ret)
2251 goto out;
2252
2253 if (ri->state == VCAP_RS_DISABLED) {
2254 /* Erase the rule area */
2255 ri->vctrl->ops->init(ri->ndev, ri->admin, ri->addr, ri->size);
2256 goto out;
2257 }
2258
2259 vcap_erase_cache(ri);
2260 ret = vcap_encode_rule(ri);
2261 if (ret) {
2262 pr_err("%s:%d: rule encoding error: %d\n", __func__, __LINE__, ret);
2263 goto out;
2264 }
2265
2266 ret = vcap_write_rule(ri);
2267 if (ret) {
2268 pr_err("%s:%d: rule write error: %d\n", __func__, __LINE__, ret);
2269 goto out;
2270 }
2271 out:
2272 mutex_unlock(&ri->admin->lock);
2273 return ret;
2274 }
2275 EXPORT_SYMBOL_GPL(vcap_add_rule);
2276
2277 /* Allocate a new rule with the provided arguments */
vcap_alloc_rule(struct vcap_control * vctrl,struct net_device * ndev,int vcap_chain_id,enum vcap_user user,u16 priority,u32 id)2278 struct vcap_rule *vcap_alloc_rule(struct vcap_control *vctrl,
2279 struct net_device *ndev, int vcap_chain_id,
2280 enum vcap_user user, u16 priority,
2281 u32 id)
2282 {
2283 struct vcap_rule_internal *ri;
2284 struct vcap_admin *admin;
2285 int err, maxsize;
2286
2287 err = vcap_api_check(vctrl);
2288 if (err)
2289 return ERR_PTR(err);
2290 if (!ndev)
2291 return ERR_PTR(-ENODEV);
2292 /* Get the VCAP instance */
2293 admin = vcap_find_admin(vctrl, vcap_chain_id);
2294 if (!admin)
2295 return ERR_PTR(-ENOENT);
2296 /* Sanity check that this VCAP is supported on this platform */
2297 if (vctrl->vcaps[admin->vtype].rows == 0)
2298 return ERR_PTR(-EINVAL);
2299
2300 mutex_lock(&admin->lock);
2301 /* Check if a rule with this id already exists */
2302 if (vcap_rule_exists(vctrl, id)) {
2303 err = -EINVAL;
2304 goto out_unlock;
2305 }
2306
2307 /* Check if there is room for the rule in the block(s) of the VCAP */
2308 maxsize = vctrl->vcaps[admin->vtype].sw_count; /* worst case rule size */
2309 if (vcap_rule_space(admin, maxsize)) {
2310 err = -ENOSPC;
2311 goto out_unlock;
2312 }
2313
2314 /* Create a container for the rule and return it */
2315 ri = kzalloc(sizeof(*ri), GFP_KERNEL);
2316 if (!ri) {
2317 err = -ENOMEM;
2318 goto out_unlock;
2319 }
2320
2321 ri->data.vcap_chain_id = vcap_chain_id;
2322 ri->data.user = user;
2323 ri->data.priority = priority;
2324 ri->data.id = id;
2325 ri->data.keyset = VCAP_KFS_NO_VALUE;
2326 ri->data.actionset = VCAP_AFS_NO_VALUE;
2327 INIT_LIST_HEAD(&ri->list);
2328 INIT_LIST_HEAD(&ri->data.keyfields);
2329 INIT_LIST_HEAD(&ri->data.actionfields);
2330 ri->ndev = ndev;
2331 ri->admin = admin; /* refer to the vcap instance */
2332 ri->vctrl = vctrl; /* refer to the client */
2333
2334 if (vcap_set_rule_id(ri) == 0) {
2335 err = -EINVAL;
2336 goto out_free;
2337 }
2338
2339 mutex_unlock(&admin->lock);
2340 return (struct vcap_rule *)ri;
2341
2342 out_free:
2343 kfree(ri);
2344 out_unlock:
2345 mutex_unlock(&admin->lock);
2346 return ERR_PTR(err);
2347
2348 }
2349 EXPORT_SYMBOL_GPL(vcap_alloc_rule);
2350
2351 /* Free mem of a rule owned by client after the rule as been added to the VCAP */
vcap_free_rule(struct vcap_rule * rule)2352 void vcap_free_rule(struct vcap_rule *rule)
2353 {
2354 struct vcap_rule_internal *ri = to_intrule(rule);
2355 struct vcap_client_actionfield *caf, *next_caf;
2356 struct vcap_client_keyfield *ckf, *next_ckf;
2357
2358 /* Deallocate the list of keys and actions */
2359 list_for_each_entry_safe(ckf, next_ckf, &ri->data.keyfields, ctrl.list) {
2360 list_del(&ckf->ctrl.list);
2361 kfree(ckf);
2362 }
2363 list_for_each_entry_safe(caf, next_caf, &ri->data.actionfields, ctrl.list) {
2364 list_del(&caf->ctrl.list);
2365 kfree(caf);
2366 }
2367 /* Deallocate the rule */
2368 kfree(rule);
2369 }
2370 EXPORT_SYMBOL_GPL(vcap_free_rule);
2371
2372 /* Decode a rule from the VCAP cache and return a copy */
vcap_decode_rule(struct vcap_rule_internal * elem)2373 struct vcap_rule *vcap_decode_rule(struct vcap_rule_internal *elem)
2374 {
2375 struct vcap_rule_internal *ri;
2376 int err;
2377
2378 ri = vcap_dup_rule(elem, elem->state == VCAP_RS_DISABLED);
2379 if (IS_ERR(ri))
2380 return ERR_PTR(PTR_ERR(ri));
2381
2382 if (ri->state == VCAP_RS_DISABLED)
2383 goto out;
2384
2385 err = vcap_read_rule(ri);
2386 if (err)
2387 return ERR_PTR(err);
2388
2389 err = vcap_decode_keyset(ri);
2390 if (err)
2391 return ERR_PTR(err);
2392
2393 err = vcap_decode_actionset(ri);
2394 if (err)
2395 return ERR_PTR(err);
2396
2397 out:
2398 return &ri->data;
2399 }
2400
vcap_get_rule(struct vcap_control * vctrl,u32 id)2401 struct vcap_rule *vcap_get_rule(struct vcap_control *vctrl, u32 id)
2402 {
2403 struct vcap_rule_internal *elem;
2404 struct vcap_rule *rule;
2405 int err;
2406
2407 err = vcap_api_check(vctrl);
2408 if (err)
2409 return ERR_PTR(err);
2410
2411 elem = vcap_get_locked_rule(vctrl, id);
2412 if (!elem)
2413 return NULL;
2414
2415 rule = vcap_decode_rule(elem);
2416 mutex_unlock(&elem->admin->lock);
2417 return rule;
2418 }
2419 EXPORT_SYMBOL_GPL(vcap_get_rule);
2420
2421 /* Update existing rule */
vcap_mod_rule(struct vcap_rule * rule)2422 int vcap_mod_rule(struct vcap_rule *rule)
2423 {
2424 struct vcap_rule_internal *ri = to_intrule(rule);
2425 struct vcap_counter ctr;
2426 int err;
2427
2428 err = vcap_api_check(ri->vctrl);
2429 if (err)
2430 return err;
2431
2432 if (!vcap_get_locked_rule(ri->vctrl, ri->data.id))
2433 return -ENOENT;
2434
2435 vcap_rule_set_state(ri);
2436 if (ri->state == VCAP_RS_DISABLED)
2437 goto out;
2438
2439 /* Encode the bitstreams to the VCAP cache */
2440 vcap_erase_cache(ri);
2441 err = vcap_encode_rule(ri);
2442 if (err)
2443 goto out;
2444
2445 err = vcap_write_rule(ri);
2446 if (err)
2447 goto out;
2448
2449 memset(&ctr, 0, sizeof(ctr));
2450 err = vcap_write_counter(ri, &ctr);
2451
2452 out:
2453 mutex_unlock(&ri->admin->lock);
2454 return err;
2455 }
2456 EXPORT_SYMBOL_GPL(vcap_mod_rule);
2457
2458 /* Return the alignment offset for a new rule address */
vcap_valid_rule_move(struct vcap_rule_internal * el,int offset)2459 static int vcap_valid_rule_move(struct vcap_rule_internal *el, int offset)
2460 {
2461 return (el->addr + offset) % el->size;
2462 }
2463
2464 /* Update the rule address with an offset */
vcap_adjust_rule_addr(struct vcap_rule_internal * el,int offset)2465 static void vcap_adjust_rule_addr(struct vcap_rule_internal *el, int offset)
2466 {
2467 el->addr += offset;
2468 }
2469
2470 /* Rules needs to be moved to fill the gap of the deleted rule */
vcap_fill_rule_gap(struct vcap_rule_internal * ri)2471 static int vcap_fill_rule_gap(struct vcap_rule_internal *ri)
2472 {
2473 struct vcap_admin *admin = ri->admin;
2474 struct vcap_rule_internal *elem;
2475 struct vcap_rule_move move;
2476 int gap = 0, offset = 0;
2477
2478 /* If the first rule is deleted: Move other rules to the top */
2479 if (list_is_first(&ri->list, &admin->rules))
2480 offset = admin->last_valid_addr + 1 - ri->addr - ri->size;
2481
2482 /* Locate gaps between odd size rules and adjust the move */
2483 elem = ri;
2484 list_for_each_entry_continue(elem, &admin->rules, list)
2485 gap += vcap_valid_rule_move(elem, ri->size);
2486
2487 /* Update the address in the remaining rules in the list */
2488 elem = ri;
2489 list_for_each_entry_continue(elem, &admin->rules, list)
2490 vcap_adjust_rule_addr(elem, ri->size + gap + offset);
2491
2492 /* Update the move info */
2493 move.addr = admin->last_used_addr;
2494 move.count = ri->addr - admin->last_used_addr - gap;
2495 move.offset = -(ri->size + gap + offset);
2496
2497 /* Do the actual move operation */
2498 vcap_move_rules(ri, &move);
2499
2500 return gap + offset;
2501 }
2502
2503 /* Delete rule in a VCAP instance */
vcap_del_rule(struct vcap_control * vctrl,struct net_device * ndev,u32 id)2504 int vcap_del_rule(struct vcap_control *vctrl, struct net_device *ndev, u32 id)
2505 {
2506 struct vcap_rule_internal *ri, *elem;
2507 struct vcap_admin *admin;
2508 int gap = 0, err;
2509
2510 /* This will later also handle rule moving */
2511 if (!ndev)
2512 return -ENODEV;
2513 err = vcap_api_check(vctrl);
2514 if (err)
2515 return err;
2516 /* Look for the rule id in all vcaps */
2517 ri = vcap_get_locked_rule(vctrl, id);
2518 if (!ri)
2519 return -ENOENT;
2520
2521 admin = ri->admin;
2522
2523 if (ri->addr > admin->last_used_addr)
2524 gap = vcap_fill_rule_gap(ri);
2525
2526 /* Delete the rule from the list of rules and the cache */
2527 list_del(&ri->list);
2528 vctrl->ops->init(ndev, admin, admin->last_used_addr, ri->size + gap);
2529 vcap_free_rule(&ri->data);
2530
2531 /* Update the last used address, set to default when no rules */
2532 if (list_empty(&admin->rules)) {
2533 admin->last_used_addr = admin->last_valid_addr + 1;
2534 } else {
2535 elem = list_last_entry(&admin->rules, struct vcap_rule_internal,
2536 list);
2537 admin->last_used_addr = elem->addr;
2538 }
2539
2540 mutex_unlock(&admin->lock);
2541 return err;
2542 }
2543 EXPORT_SYMBOL_GPL(vcap_del_rule);
2544
2545 /* Delete all rules in the VCAP instance */
vcap_del_rules(struct vcap_control * vctrl,struct vcap_admin * admin)2546 int vcap_del_rules(struct vcap_control *vctrl, struct vcap_admin *admin)
2547 {
2548 struct vcap_enabled_port *eport, *next_eport;
2549 struct vcap_rule_internal *ri, *next_ri;
2550 int ret = vcap_api_check(vctrl);
2551
2552 if (ret)
2553 return ret;
2554
2555 mutex_lock(&admin->lock);
2556 list_for_each_entry_safe(ri, next_ri, &admin->rules, list) {
2557 vctrl->ops->init(ri->ndev, admin, ri->addr, ri->size);
2558 list_del(&ri->list);
2559 vcap_free_rule(&ri->data);
2560 }
2561 admin->last_used_addr = admin->last_valid_addr;
2562
2563 /* Remove list of enabled ports */
2564 list_for_each_entry_safe(eport, next_eport, &admin->enabled, list) {
2565 list_del(&eport->list);
2566 kfree(eport);
2567 }
2568 mutex_unlock(&admin->lock);
2569
2570 return 0;
2571 }
2572 EXPORT_SYMBOL_GPL(vcap_del_rules);
2573
2574 /* Find a client key field in a rule */
2575 static struct vcap_client_keyfield *
vcap_find_keyfield(struct vcap_rule * rule,enum vcap_key_field key)2576 vcap_find_keyfield(struct vcap_rule *rule, enum vcap_key_field key)
2577 {
2578 struct vcap_rule_internal *ri = to_intrule(rule);
2579 struct vcap_client_keyfield *ckf;
2580
2581 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list)
2582 if (ckf->ctrl.key == key)
2583 return ckf;
2584 return NULL;
2585 }
2586
2587 /* Find information on a key field in a rule */
vcap_lookup_keyfield(struct vcap_rule * rule,enum vcap_key_field key)2588 const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule,
2589 enum vcap_key_field key)
2590 {
2591 struct vcap_rule_internal *ri = to_intrule(rule);
2592 enum vcap_keyfield_set keyset = rule->keyset;
2593 enum vcap_type vt = ri->admin->vtype;
2594 const struct vcap_field *fields;
2595
2596 if (keyset == VCAP_KFS_NO_VALUE)
2597 return NULL;
2598 fields = vcap_keyfields(ri->vctrl, vt, keyset);
2599 if (!fields)
2600 return NULL;
2601 return &fields[key];
2602 }
2603 EXPORT_SYMBOL_GPL(vcap_lookup_keyfield);
2604
2605 /* Check if the keyfield is already in the rule */
vcap_keyfield_unique(struct vcap_rule * rule,enum vcap_key_field key)2606 static bool vcap_keyfield_unique(struct vcap_rule *rule,
2607 enum vcap_key_field key)
2608 {
2609 struct vcap_rule_internal *ri = to_intrule(rule);
2610 const struct vcap_client_keyfield *ckf;
2611
2612 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list)
2613 if (ckf->ctrl.key == key)
2614 return false;
2615 return true;
2616 }
2617
2618 /* Check if the keyfield is in the keyset */
vcap_keyfield_match_keyset(struct vcap_rule * rule,enum vcap_key_field key)2619 static bool vcap_keyfield_match_keyset(struct vcap_rule *rule,
2620 enum vcap_key_field key)
2621 {
2622 struct vcap_rule_internal *ri = to_intrule(rule);
2623 enum vcap_keyfield_set keyset = rule->keyset;
2624 enum vcap_type vt = ri->admin->vtype;
2625 const struct vcap_field *fields;
2626
2627 /* the field is accepted if the rule has no keyset yet */
2628 if (keyset == VCAP_KFS_NO_VALUE)
2629 return true;
2630 fields = vcap_keyfields(ri->vctrl, vt, keyset);
2631 if (!fields)
2632 return false;
2633 /* if there is a width there is a way */
2634 return fields[key].width > 0;
2635 }
2636
vcap_rule_add_key(struct vcap_rule * rule,enum vcap_key_field key,enum vcap_field_type ftype,struct vcap_client_keyfield_data * data)2637 static int vcap_rule_add_key(struct vcap_rule *rule,
2638 enum vcap_key_field key,
2639 enum vcap_field_type ftype,
2640 struct vcap_client_keyfield_data *data)
2641 {
2642 struct vcap_rule_internal *ri = to_intrule(rule);
2643 struct vcap_client_keyfield *field;
2644
2645 if (!vcap_keyfield_unique(rule, key)) {
2646 pr_warn("%s:%d: keyfield %s is already in the rule\n",
2647 __func__, __LINE__,
2648 vcap_keyfield_name(ri->vctrl, key));
2649 return -EINVAL;
2650 }
2651
2652 if (!vcap_keyfield_match_keyset(rule, key)) {
2653 pr_err("%s:%d: keyfield %s does not belong in the rule keyset\n",
2654 __func__, __LINE__,
2655 vcap_keyfield_name(ri->vctrl, key));
2656 return -EINVAL;
2657 }
2658
2659 field = kzalloc(sizeof(*field), GFP_KERNEL);
2660 if (!field)
2661 return -ENOMEM;
2662 memcpy(&field->data, data, sizeof(field->data));
2663 field->ctrl.key = key;
2664 field->ctrl.type = ftype;
2665 list_add_tail(&field->ctrl.list, &rule->keyfields);
2666 return 0;
2667 }
2668
vcap_rule_set_key_bitsize(struct vcap_u1_key * u1,enum vcap_bit val)2669 static void vcap_rule_set_key_bitsize(struct vcap_u1_key *u1, enum vcap_bit val)
2670 {
2671 switch (val) {
2672 case VCAP_BIT_0:
2673 u1->value = 0;
2674 u1->mask = 1;
2675 break;
2676 case VCAP_BIT_1:
2677 u1->value = 1;
2678 u1->mask = 1;
2679 break;
2680 case VCAP_BIT_ANY:
2681 u1->value = 0;
2682 u1->mask = 0;
2683 break;
2684 }
2685 }
2686
2687 /* Add a bit key with value and mask to the rule */
vcap_rule_add_key_bit(struct vcap_rule * rule,enum vcap_key_field key,enum vcap_bit val)2688 int vcap_rule_add_key_bit(struct vcap_rule *rule, enum vcap_key_field key,
2689 enum vcap_bit val)
2690 {
2691 struct vcap_client_keyfield_data data;
2692
2693 vcap_rule_set_key_bitsize(&data.u1, val);
2694 return vcap_rule_add_key(rule, key, VCAP_FIELD_BIT, &data);
2695 }
2696 EXPORT_SYMBOL_GPL(vcap_rule_add_key_bit);
2697
2698 /* Add a 32 bit key field with value and mask to the rule */
vcap_rule_add_key_u32(struct vcap_rule * rule,enum vcap_key_field key,u32 value,u32 mask)2699 int vcap_rule_add_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
2700 u32 value, u32 mask)
2701 {
2702 struct vcap_client_keyfield_data data;
2703
2704 data.u32.value = value;
2705 data.u32.mask = mask;
2706 return vcap_rule_add_key(rule, key, VCAP_FIELD_U32, &data);
2707 }
2708 EXPORT_SYMBOL_GPL(vcap_rule_add_key_u32);
2709
2710 /* Add a 48 bit key with value and mask to the rule */
vcap_rule_add_key_u48(struct vcap_rule * rule,enum vcap_key_field key,struct vcap_u48_key * fieldval)2711 int vcap_rule_add_key_u48(struct vcap_rule *rule, enum vcap_key_field key,
2712 struct vcap_u48_key *fieldval)
2713 {
2714 struct vcap_client_keyfield_data data;
2715
2716 memcpy(&data.u48, fieldval, sizeof(data.u48));
2717 return vcap_rule_add_key(rule, key, VCAP_FIELD_U48, &data);
2718 }
2719 EXPORT_SYMBOL_GPL(vcap_rule_add_key_u48);
2720
2721 /* Add a 72 bit key with value and mask to the rule */
vcap_rule_add_key_u72(struct vcap_rule * rule,enum vcap_key_field key,struct vcap_u72_key * fieldval)2722 int vcap_rule_add_key_u72(struct vcap_rule *rule, enum vcap_key_field key,
2723 struct vcap_u72_key *fieldval)
2724 {
2725 struct vcap_client_keyfield_data data;
2726
2727 memcpy(&data.u72, fieldval, sizeof(data.u72));
2728 return vcap_rule_add_key(rule, key, VCAP_FIELD_U72, &data);
2729 }
2730 EXPORT_SYMBOL_GPL(vcap_rule_add_key_u72);
2731
2732 /* Add a 128 bit key with value and mask to the rule */
vcap_rule_add_key_u128(struct vcap_rule * rule,enum vcap_key_field key,struct vcap_u128_key * fieldval)2733 int vcap_rule_add_key_u128(struct vcap_rule *rule, enum vcap_key_field key,
2734 struct vcap_u128_key *fieldval)
2735 {
2736 struct vcap_client_keyfield_data data;
2737
2738 memcpy(&data.u128, fieldval, sizeof(data.u128));
2739 return vcap_rule_add_key(rule, key, VCAP_FIELD_U128, &data);
2740 }
2741 EXPORT_SYMBOL_GPL(vcap_rule_add_key_u128);
2742
vcap_rule_get_key_u32(struct vcap_rule * rule,enum vcap_key_field key,u32 * value,u32 * mask)2743 int vcap_rule_get_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
2744 u32 *value, u32 *mask)
2745 {
2746 struct vcap_client_keyfield *ckf;
2747
2748 ckf = vcap_find_keyfield(rule, key);
2749 if (!ckf)
2750 return -ENOENT;
2751
2752 *value = ckf->data.u32.value;
2753 *mask = ckf->data.u32.mask;
2754
2755 return 0;
2756 }
2757 EXPORT_SYMBOL_GPL(vcap_rule_get_key_u32);
2758
2759 /* Find a client action field in a rule */
2760 struct vcap_client_actionfield *
vcap_find_actionfield(struct vcap_rule * rule,enum vcap_action_field act)2761 vcap_find_actionfield(struct vcap_rule *rule, enum vcap_action_field act)
2762 {
2763 struct vcap_rule_internal *ri = (struct vcap_rule_internal *)rule;
2764 struct vcap_client_actionfield *caf;
2765
2766 list_for_each_entry(caf, &ri->data.actionfields, ctrl.list)
2767 if (caf->ctrl.action == act)
2768 return caf;
2769 return NULL;
2770 }
2771 EXPORT_SYMBOL_GPL(vcap_find_actionfield);
2772
2773 /* Check if the actionfield is already in the rule */
vcap_actionfield_unique(struct vcap_rule * rule,enum vcap_action_field act)2774 static bool vcap_actionfield_unique(struct vcap_rule *rule,
2775 enum vcap_action_field act)
2776 {
2777 struct vcap_rule_internal *ri = to_intrule(rule);
2778 const struct vcap_client_actionfield *caf;
2779
2780 list_for_each_entry(caf, &ri->data.actionfields, ctrl.list)
2781 if (caf->ctrl.action == act)
2782 return false;
2783 return true;
2784 }
2785
2786 /* Check if the actionfield is in the actionset */
vcap_actionfield_match_actionset(struct vcap_rule * rule,enum vcap_action_field action)2787 static bool vcap_actionfield_match_actionset(struct vcap_rule *rule,
2788 enum vcap_action_field action)
2789 {
2790 enum vcap_actionfield_set actionset = rule->actionset;
2791 struct vcap_rule_internal *ri = to_intrule(rule);
2792 enum vcap_type vt = ri->admin->vtype;
2793 const struct vcap_field *fields;
2794
2795 /* the field is accepted if the rule has no actionset yet */
2796 if (actionset == VCAP_AFS_NO_VALUE)
2797 return true;
2798 fields = vcap_actionfields(ri->vctrl, vt, actionset);
2799 if (!fields)
2800 return false;
2801 /* if there is a width there is a way */
2802 return fields[action].width > 0;
2803 }
2804
vcap_rule_add_action(struct vcap_rule * rule,enum vcap_action_field action,enum vcap_field_type ftype,struct vcap_client_actionfield_data * data)2805 static int vcap_rule_add_action(struct vcap_rule *rule,
2806 enum vcap_action_field action,
2807 enum vcap_field_type ftype,
2808 struct vcap_client_actionfield_data *data)
2809 {
2810 struct vcap_rule_internal *ri = to_intrule(rule);
2811 struct vcap_client_actionfield *field;
2812
2813 if (!vcap_actionfield_unique(rule, action)) {
2814 pr_warn("%s:%d: actionfield %s is already in the rule\n",
2815 __func__, __LINE__,
2816 vcap_actionfield_name(ri->vctrl, action));
2817 return -EINVAL;
2818 }
2819
2820 if (!vcap_actionfield_match_actionset(rule, action)) {
2821 pr_err("%s:%d: actionfield %s does not belong in the rule actionset\n",
2822 __func__, __LINE__,
2823 vcap_actionfield_name(ri->vctrl, action));
2824 return -EINVAL;
2825 }
2826
2827 field = kzalloc(sizeof(*field), GFP_KERNEL);
2828 if (!field)
2829 return -ENOMEM;
2830 memcpy(&field->data, data, sizeof(field->data));
2831 field->ctrl.action = action;
2832 field->ctrl.type = ftype;
2833 list_add_tail(&field->ctrl.list, &rule->actionfields);
2834 return 0;
2835 }
2836
vcap_rule_set_action_bitsize(struct vcap_u1_action * u1,enum vcap_bit val)2837 static void vcap_rule_set_action_bitsize(struct vcap_u1_action *u1,
2838 enum vcap_bit val)
2839 {
2840 switch (val) {
2841 case VCAP_BIT_0:
2842 u1->value = 0;
2843 break;
2844 case VCAP_BIT_1:
2845 u1->value = 1;
2846 break;
2847 case VCAP_BIT_ANY:
2848 u1->value = 0;
2849 break;
2850 }
2851 }
2852
2853 /* Add a bit action with value to the rule */
vcap_rule_add_action_bit(struct vcap_rule * rule,enum vcap_action_field action,enum vcap_bit val)2854 int vcap_rule_add_action_bit(struct vcap_rule *rule,
2855 enum vcap_action_field action,
2856 enum vcap_bit val)
2857 {
2858 struct vcap_client_actionfield_data data;
2859
2860 vcap_rule_set_action_bitsize(&data.u1, val);
2861 return vcap_rule_add_action(rule, action, VCAP_FIELD_BIT, &data);
2862 }
2863 EXPORT_SYMBOL_GPL(vcap_rule_add_action_bit);
2864
2865 /* Add a 32 bit action field with value to the rule */
vcap_rule_add_action_u32(struct vcap_rule * rule,enum vcap_action_field action,u32 value)2866 int vcap_rule_add_action_u32(struct vcap_rule *rule,
2867 enum vcap_action_field action,
2868 u32 value)
2869 {
2870 struct vcap_client_actionfield_data data;
2871
2872 data.u32.value = value;
2873 return vcap_rule_add_action(rule, action, VCAP_FIELD_U32, &data);
2874 }
2875 EXPORT_SYMBOL_GPL(vcap_rule_add_action_u32);
2876
vcap_read_counter(struct vcap_rule_internal * ri,struct vcap_counter * ctr)2877 static int vcap_read_counter(struct vcap_rule_internal *ri,
2878 struct vcap_counter *ctr)
2879 {
2880 struct vcap_admin *admin = ri->admin;
2881
2882 ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ, VCAP_SEL_COUNTER,
2883 ri->addr);
2884 ri->vctrl->ops->cache_read(ri->ndev, admin, VCAP_SEL_COUNTER,
2885 ri->counter_id, 0);
2886 ctr->value = admin->cache.counter;
2887 ctr->sticky = admin->cache.sticky;
2888 return 0;
2889 }
2890
2891 /* Copy to host byte order */
vcap_netbytes_copy(u8 * dst,u8 * src,int count)2892 void vcap_netbytes_copy(u8 *dst, u8 *src, int count)
2893 {
2894 int idx;
2895
2896 for (idx = 0; idx < count; ++idx, ++dst)
2897 *dst = src[count - idx - 1];
2898 }
2899 EXPORT_SYMBOL_GPL(vcap_netbytes_copy);
2900
2901 /* Convert validation error code into tc extact error message */
vcap_set_tc_exterr(struct flow_cls_offload * fco,struct vcap_rule * vrule)2902 void vcap_set_tc_exterr(struct flow_cls_offload *fco, struct vcap_rule *vrule)
2903 {
2904 switch (vrule->exterr) {
2905 case VCAP_ERR_NONE:
2906 break;
2907 case VCAP_ERR_NO_ADMIN:
2908 NL_SET_ERR_MSG_MOD(fco->common.extack,
2909 "Missing VCAP instance");
2910 break;
2911 case VCAP_ERR_NO_NETDEV:
2912 NL_SET_ERR_MSG_MOD(fco->common.extack,
2913 "Missing network interface");
2914 break;
2915 case VCAP_ERR_NO_KEYSET_MATCH:
2916 NL_SET_ERR_MSG_MOD(fco->common.extack,
2917 "No keyset matched the filter keys");
2918 break;
2919 case VCAP_ERR_NO_ACTIONSET_MATCH:
2920 NL_SET_ERR_MSG_MOD(fco->common.extack,
2921 "No actionset matched the filter actions");
2922 break;
2923 case VCAP_ERR_NO_PORT_KEYSET_MATCH:
2924 NL_SET_ERR_MSG_MOD(fco->common.extack,
2925 "No port keyset matched the filter keys");
2926 break;
2927 }
2928 }
2929 EXPORT_SYMBOL_GPL(vcap_set_tc_exterr);
2930
2931 /* Write a rule to VCAP HW to enable it */
vcap_enable_rule(struct vcap_rule_internal * ri)2932 static int vcap_enable_rule(struct vcap_rule_internal *ri)
2933 {
2934 struct vcap_client_actionfield *af, *naf;
2935 struct vcap_client_keyfield *kf, *nkf;
2936 int err;
2937
2938 vcap_erase_cache(ri);
2939 err = vcap_encode_rule(ri);
2940 if (err)
2941 goto out;
2942 err = vcap_write_rule(ri);
2943 if (err)
2944 goto out;
2945
2946 /* Deallocate the list of keys and actions */
2947 list_for_each_entry_safe(kf, nkf, &ri->data.keyfields, ctrl.list) {
2948 list_del(&kf->ctrl.list);
2949 kfree(kf);
2950 }
2951 list_for_each_entry_safe(af, naf, &ri->data.actionfields, ctrl.list) {
2952 list_del(&af->ctrl.list);
2953 kfree(af);
2954 }
2955 ri->state = VCAP_RS_ENABLED;
2956 out:
2957 return err;
2958 }
2959
2960 /* Enable all disabled rules for a specific chain/port in the VCAP HW */
vcap_enable_rules(struct vcap_control * vctrl,struct net_device * ndev,int chain)2961 static int vcap_enable_rules(struct vcap_control *vctrl,
2962 struct net_device *ndev, int chain)
2963 {
2964 int next_chain = chain + VCAP_CID_LOOKUP_SIZE;
2965 struct vcap_rule_internal *ri;
2966 struct vcap_admin *admin;
2967 int err = 0;
2968
2969 list_for_each_entry(admin, &vctrl->list, list) {
2970 if (!(chain >= admin->first_cid && chain <= admin->last_cid))
2971 continue;
2972
2973 /* Found the admin, now find the offloadable rules */
2974 mutex_lock(&admin->lock);
2975 list_for_each_entry(ri, &admin->rules, list) {
2976 /* Is the rule in the lookup defined by the chain */
2977 if (!(ri->data.vcap_chain_id >= chain &&
2978 ri->data.vcap_chain_id < next_chain)) {
2979 continue;
2980 }
2981
2982 if (ri->ndev != ndev)
2983 continue;
2984
2985 if (ri->state != VCAP_RS_DISABLED)
2986 continue;
2987
2988 err = vcap_enable_rule(ri);
2989 if (err)
2990 break;
2991 }
2992 mutex_unlock(&admin->lock);
2993 if (err)
2994 break;
2995 }
2996 return err;
2997 }
2998
2999 /* Read and erase a rule from VCAP HW to disable it */
vcap_disable_rule(struct vcap_rule_internal * ri)3000 static int vcap_disable_rule(struct vcap_rule_internal *ri)
3001 {
3002 int err;
3003
3004 err = vcap_read_rule(ri);
3005 if (err)
3006 return err;
3007 err = vcap_decode_keyset(ri);
3008 if (err)
3009 return err;
3010 err = vcap_decode_actionset(ri);
3011 if (err)
3012 return err;
3013
3014 ri->state = VCAP_RS_DISABLED;
3015 ri->vctrl->ops->init(ri->ndev, ri->admin, ri->addr, ri->size);
3016 return 0;
3017 }
3018
3019 /* Disable all enabled rules for a specific chain/port in the VCAP HW */
vcap_disable_rules(struct vcap_control * vctrl,struct net_device * ndev,int chain)3020 static int vcap_disable_rules(struct vcap_control *vctrl,
3021 struct net_device *ndev, int chain)
3022 {
3023 struct vcap_rule_internal *ri;
3024 struct vcap_admin *admin;
3025 int err = 0;
3026
3027 list_for_each_entry(admin, &vctrl->list, list) {
3028 if (!(chain >= admin->first_cid && chain <= admin->last_cid))
3029 continue;
3030
3031 /* Found the admin, now find the rules on the chain */
3032 mutex_lock(&admin->lock);
3033 list_for_each_entry(ri, &admin->rules, list) {
3034 if (ri->data.vcap_chain_id != chain)
3035 continue;
3036
3037 if (ri->ndev != ndev)
3038 continue;
3039
3040 if (ri->state != VCAP_RS_ENABLED)
3041 continue;
3042
3043 err = vcap_disable_rule(ri);
3044 if (err)
3045 break;
3046 }
3047 mutex_unlock(&admin->lock);
3048 if (err)
3049 break;
3050 }
3051 return err;
3052 }
3053
3054 /* Check if this port is already enabled for this VCAP instance */
vcap_is_enabled(struct vcap_control * vctrl,struct net_device * ndev,int dst_cid)3055 static bool vcap_is_enabled(struct vcap_control *vctrl, struct net_device *ndev,
3056 int dst_cid)
3057 {
3058 struct vcap_enabled_port *eport;
3059 struct vcap_admin *admin;
3060
3061 list_for_each_entry(admin, &vctrl->list, list)
3062 list_for_each_entry(eport, &admin->enabled, list)
3063 if (eport->dst_cid == dst_cid && eport->ndev == ndev)
3064 return true;
3065
3066 return false;
3067 }
3068
3069 /* Enable this port and chain id in a VCAP instance */
vcap_enable(struct vcap_control * vctrl,struct net_device * ndev,unsigned long cookie,int src_cid,int dst_cid)3070 static int vcap_enable(struct vcap_control *vctrl, struct net_device *ndev,
3071 unsigned long cookie, int src_cid, int dst_cid)
3072 {
3073 struct vcap_enabled_port *eport;
3074 struct vcap_admin *admin;
3075
3076 if (src_cid >= dst_cid)
3077 return -EFAULT;
3078
3079 admin = vcap_find_admin(vctrl, dst_cid);
3080 if (!admin)
3081 return -ENOENT;
3082
3083 eport = kzalloc(sizeof(*eport), GFP_KERNEL);
3084 if (!eport)
3085 return -ENOMEM;
3086
3087 eport->ndev = ndev;
3088 eport->cookie = cookie;
3089 eport->src_cid = src_cid;
3090 eport->dst_cid = dst_cid;
3091 mutex_lock(&admin->lock);
3092 list_add_tail(&eport->list, &admin->enabled);
3093 mutex_unlock(&admin->lock);
3094
3095 if (vcap_path_exist(vctrl, ndev, src_cid)) {
3096 /* Enable chained lookups */
3097 while (dst_cid) {
3098 admin = vcap_find_admin(vctrl, dst_cid);
3099 if (!admin)
3100 return -ENOENT;
3101
3102 vcap_enable_rules(vctrl, ndev, dst_cid);
3103 dst_cid = vcap_get_next_chain(vctrl, ndev, dst_cid);
3104 }
3105 }
3106 return 0;
3107 }
3108
3109 /* Disable this port and chain id for a VCAP instance */
vcap_disable(struct vcap_control * vctrl,struct net_device * ndev,unsigned long cookie)3110 static int vcap_disable(struct vcap_control *vctrl, struct net_device *ndev,
3111 unsigned long cookie)
3112 {
3113 struct vcap_enabled_port *elem, *eport = NULL;
3114 struct vcap_admin *found = NULL, *admin;
3115 int dst_cid;
3116
3117 list_for_each_entry(admin, &vctrl->list, list) {
3118 list_for_each_entry(elem, &admin->enabled, list) {
3119 if (elem->cookie == cookie && elem->ndev == ndev) {
3120 eport = elem;
3121 found = admin;
3122 break;
3123 }
3124 }
3125 if (eport)
3126 break;
3127 }
3128
3129 if (!eport)
3130 return -ENOENT;
3131
3132 /* Disable chained lookups */
3133 dst_cid = eport->dst_cid;
3134 while (dst_cid) {
3135 admin = vcap_find_admin(vctrl, dst_cid);
3136 if (!admin)
3137 return -ENOENT;
3138
3139 vcap_disable_rules(vctrl, ndev, dst_cid);
3140 dst_cid = vcap_get_next_chain(vctrl, ndev, dst_cid);
3141 }
3142
3143 mutex_lock(&found->lock);
3144 list_del(&eport->list);
3145 mutex_unlock(&found->lock);
3146 kfree(eport);
3147 return 0;
3148 }
3149
3150 /* Enable/Disable the VCAP instance lookups */
vcap_enable_lookups(struct vcap_control * vctrl,struct net_device * ndev,int src_cid,int dst_cid,unsigned long cookie,bool enable)3151 int vcap_enable_lookups(struct vcap_control *vctrl, struct net_device *ndev,
3152 int src_cid, int dst_cid, unsigned long cookie,
3153 bool enable)
3154 {
3155 int err;
3156
3157 err = vcap_api_check(vctrl);
3158 if (err)
3159 return err;
3160
3161 if (!ndev)
3162 return -ENODEV;
3163
3164 /* Source and destination must be the first chain in a lookup */
3165 if (src_cid % VCAP_CID_LOOKUP_SIZE)
3166 return -EFAULT;
3167 if (dst_cid % VCAP_CID_LOOKUP_SIZE)
3168 return -EFAULT;
3169
3170 if (enable) {
3171 if (vcap_is_enabled(vctrl, ndev, dst_cid))
3172 return -EADDRINUSE;
3173 if (vcap_is_chain_used(vctrl, ndev, src_cid))
3174 return -EADDRNOTAVAIL;
3175 err = vcap_enable(vctrl, ndev, cookie, src_cid, dst_cid);
3176 } else {
3177 err = vcap_disable(vctrl, ndev, cookie);
3178 }
3179
3180 return err;
3181 }
3182 EXPORT_SYMBOL_GPL(vcap_enable_lookups);
3183
3184 /* Is this chain id the last lookup of all VCAPs */
vcap_is_last_chain(struct vcap_control * vctrl,int cid,bool ingress)3185 bool vcap_is_last_chain(struct vcap_control *vctrl, int cid, bool ingress)
3186 {
3187 struct vcap_admin *admin;
3188 int lookup;
3189
3190 if (vcap_api_check(vctrl))
3191 return false;
3192
3193 admin = vcap_find_admin(vctrl, cid);
3194 if (!admin)
3195 return false;
3196
3197 if (!vcap_admin_is_last(vctrl, admin, ingress))
3198 return false;
3199
3200 /* This must be the last lookup in this VCAP type */
3201 lookup = vcap_chain_id_to_lookup(admin, cid);
3202 return lookup == admin->lookups - 1;
3203 }
3204 EXPORT_SYMBOL_GPL(vcap_is_last_chain);
3205
3206 /* Set a rule counter id (for certain vcaps only) */
vcap_rule_set_counter_id(struct vcap_rule * rule,u32 counter_id)3207 void vcap_rule_set_counter_id(struct vcap_rule *rule, u32 counter_id)
3208 {
3209 struct vcap_rule_internal *ri = to_intrule(rule);
3210
3211 ri->counter_id = counter_id;
3212 }
3213 EXPORT_SYMBOL_GPL(vcap_rule_set_counter_id);
3214
vcap_rule_set_counter(struct vcap_rule * rule,struct vcap_counter * ctr)3215 int vcap_rule_set_counter(struct vcap_rule *rule, struct vcap_counter *ctr)
3216 {
3217 struct vcap_rule_internal *ri = to_intrule(rule);
3218 int err;
3219
3220 err = vcap_api_check(ri->vctrl);
3221 if (err)
3222 return err;
3223 if (!ctr) {
3224 pr_err("%s:%d: counter is missing\n", __func__, __LINE__);
3225 return -EINVAL;
3226 }
3227
3228 mutex_lock(&ri->admin->lock);
3229 err = vcap_write_counter(ri, ctr);
3230 mutex_unlock(&ri->admin->lock);
3231
3232 return err;
3233 }
3234 EXPORT_SYMBOL_GPL(vcap_rule_set_counter);
3235
vcap_rule_get_counter(struct vcap_rule * rule,struct vcap_counter * ctr)3236 int vcap_rule_get_counter(struct vcap_rule *rule, struct vcap_counter *ctr)
3237 {
3238 struct vcap_rule_internal *ri = to_intrule(rule);
3239 int err;
3240
3241 err = vcap_api_check(ri->vctrl);
3242 if (err)
3243 return err;
3244 if (!ctr) {
3245 pr_err("%s:%d: counter is missing\n", __func__, __LINE__);
3246 return -EINVAL;
3247 }
3248
3249 mutex_lock(&ri->admin->lock);
3250 err = vcap_read_counter(ri, ctr);
3251 mutex_unlock(&ri->admin->lock);
3252
3253 return err;
3254 }
3255 EXPORT_SYMBOL_GPL(vcap_rule_get_counter);
3256
3257 /* Get a copy of a client key field */
vcap_rule_get_key(struct vcap_rule * rule,enum vcap_key_field key,struct vcap_client_keyfield * ckf)3258 static int vcap_rule_get_key(struct vcap_rule *rule,
3259 enum vcap_key_field key,
3260 struct vcap_client_keyfield *ckf)
3261 {
3262 struct vcap_client_keyfield *field;
3263
3264 field = vcap_find_keyfield(rule, key);
3265 if (!field)
3266 return -EINVAL;
3267 memcpy(ckf, field, sizeof(*ckf));
3268 INIT_LIST_HEAD(&ckf->ctrl.list);
3269 return 0;
3270 }
3271
3272 /* Find a keyset having the same size as the provided rule, where the keyset
3273 * does not have a type id.
3274 */
vcap_rule_get_untyped_keyset(struct vcap_rule_internal * ri,struct vcap_keyset_list * matches)3275 static int vcap_rule_get_untyped_keyset(struct vcap_rule_internal *ri,
3276 struct vcap_keyset_list *matches)
3277 {
3278 struct vcap_control *vctrl = ri->vctrl;
3279 enum vcap_type vt = ri->admin->vtype;
3280 const struct vcap_set *keyfield_set;
3281 int idx;
3282
3283 keyfield_set = vctrl->vcaps[vt].keyfield_set;
3284 for (idx = 0; idx < vctrl->vcaps[vt].keyfield_set_size; ++idx) {
3285 if (keyfield_set[idx].sw_per_item == ri->keyset_sw &&
3286 keyfield_set[idx].type_id == (u8)-1) {
3287 vcap_keyset_list_add(matches, idx);
3288 return 0;
3289 }
3290 }
3291 return -EINVAL;
3292 }
3293
3294 /* Get the keysets that matches the rule key type/mask */
vcap_rule_get_keysets(struct vcap_rule_internal * ri,struct vcap_keyset_list * matches)3295 int vcap_rule_get_keysets(struct vcap_rule_internal *ri,
3296 struct vcap_keyset_list *matches)
3297 {
3298 struct vcap_control *vctrl = ri->vctrl;
3299 enum vcap_type vt = ri->admin->vtype;
3300 const struct vcap_set *keyfield_set;
3301 struct vcap_client_keyfield kf = {};
3302 u32 value, mask;
3303 int err, idx;
3304
3305 err = vcap_rule_get_key(&ri->data, VCAP_KF_TYPE, &kf);
3306 if (err)
3307 return vcap_rule_get_untyped_keyset(ri, matches);
3308
3309 if (kf.ctrl.type == VCAP_FIELD_BIT) {
3310 value = kf.data.u1.value;
3311 mask = kf.data.u1.mask;
3312 } else if (kf.ctrl.type == VCAP_FIELD_U32) {
3313 value = kf.data.u32.value;
3314 mask = kf.data.u32.mask;
3315 } else {
3316 return -EINVAL;
3317 }
3318
3319 keyfield_set = vctrl->vcaps[vt].keyfield_set;
3320 for (idx = 0; idx < vctrl->vcaps[vt].keyfield_set_size; ++idx) {
3321 if (keyfield_set[idx].sw_per_item != ri->keyset_sw)
3322 continue;
3323
3324 if (keyfield_set[idx].type_id == (u8)-1) {
3325 vcap_keyset_list_add(matches, idx);
3326 continue;
3327 }
3328
3329 if ((keyfield_set[idx].type_id & mask) == value)
3330 vcap_keyset_list_add(matches, idx);
3331 }
3332 if (matches->cnt > 0)
3333 return 0;
3334
3335 return -EINVAL;
3336 }
3337
3338 /* Collect packet counts from all rules with the same cookie */
vcap_get_rule_count_by_cookie(struct vcap_control * vctrl,struct vcap_counter * ctr,u64 cookie)3339 int vcap_get_rule_count_by_cookie(struct vcap_control *vctrl,
3340 struct vcap_counter *ctr, u64 cookie)
3341 {
3342 struct vcap_rule_internal *ri;
3343 struct vcap_counter temp = {};
3344 struct vcap_admin *admin;
3345 int err;
3346
3347 err = vcap_api_check(vctrl);
3348 if (err)
3349 return err;
3350
3351 /* Iterate all rules in each VCAP instance */
3352 list_for_each_entry(admin, &vctrl->list, list) {
3353 mutex_lock(&admin->lock);
3354 list_for_each_entry(ri, &admin->rules, list) {
3355 if (ri->data.cookie != cookie)
3356 continue;
3357
3358 err = vcap_read_counter(ri, &temp);
3359 if (err)
3360 goto unlock;
3361 ctr->value += temp.value;
3362
3363 /* Reset the rule counter */
3364 temp.value = 0;
3365 temp.sticky = 0;
3366 err = vcap_write_counter(ri, &temp);
3367 if (err)
3368 goto unlock;
3369 }
3370 mutex_unlock(&admin->lock);
3371 }
3372 return err;
3373
3374 unlock:
3375 mutex_unlock(&admin->lock);
3376 return err;
3377 }
3378 EXPORT_SYMBOL_GPL(vcap_get_rule_count_by_cookie);
3379
vcap_rule_mod_key(struct vcap_rule * rule,enum vcap_key_field key,enum vcap_field_type ftype,struct vcap_client_keyfield_data * data)3380 static int vcap_rule_mod_key(struct vcap_rule *rule,
3381 enum vcap_key_field key,
3382 enum vcap_field_type ftype,
3383 struct vcap_client_keyfield_data *data)
3384 {
3385 struct vcap_client_keyfield *field;
3386
3387 field = vcap_find_keyfield(rule, key);
3388 if (!field)
3389 return vcap_rule_add_key(rule, key, ftype, data);
3390 memcpy(&field->data, data, sizeof(field->data));
3391 return 0;
3392 }
3393
3394 /* Modify a 32 bit key field with value and mask in the rule */
vcap_rule_mod_key_u32(struct vcap_rule * rule,enum vcap_key_field key,u32 value,u32 mask)3395 int vcap_rule_mod_key_u32(struct vcap_rule *rule, enum vcap_key_field key,
3396 u32 value, u32 mask)
3397 {
3398 struct vcap_client_keyfield_data data;
3399
3400 data.u32.value = value;
3401 data.u32.mask = mask;
3402 return vcap_rule_mod_key(rule, key, VCAP_FIELD_U32, &data);
3403 }
3404 EXPORT_SYMBOL_GPL(vcap_rule_mod_key_u32);
3405
vcap_rule_mod_action(struct vcap_rule * rule,enum vcap_action_field action,enum vcap_field_type ftype,struct vcap_client_actionfield_data * data)3406 static int vcap_rule_mod_action(struct vcap_rule *rule,
3407 enum vcap_action_field action,
3408 enum vcap_field_type ftype,
3409 struct vcap_client_actionfield_data *data)
3410 {
3411 struct vcap_client_actionfield *field;
3412
3413 field = vcap_find_actionfield(rule, action);
3414 if (!field)
3415 return vcap_rule_add_action(rule, action, ftype, data);
3416 memcpy(&field->data, data, sizeof(field->data));
3417 return 0;
3418 }
3419
3420 /* Modify a 32 bit action field with value in the rule */
vcap_rule_mod_action_u32(struct vcap_rule * rule,enum vcap_action_field action,u32 value)3421 int vcap_rule_mod_action_u32(struct vcap_rule *rule,
3422 enum vcap_action_field action,
3423 u32 value)
3424 {
3425 struct vcap_client_actionfield_data data;
3426
3427 data.u32.value = value;
3428 return vcap_rule_mod_action(rule, action, VCAP_FIELD_U32, &data);
3429 }
3430 EXPORT_SYMBOL_GPL(vcap_rule_mod_action_u32);
3431
3432 /* Drop keys in a keylist and any keys that are not supported by the keyset */
vcap_filter_rule_keys(struct vcap_rule * rule,enum vcap_key_field keylist[],int length,bool drop_unsupported)3433 int vcap_filter_rule_keys(struct vcap_rule *rule,
3434 enum vcap_key_field keylist[], int length,
3435 bool drop_unsupported)
3436 {
3437 struct vcap_rule_internal *ri = to_intrule(rule);
3438 struct vcap_client_keyfield *ckf, *next_ckf;
3439 const struct vcap_field *fields;
3440 enum vcap_key_field key;
3441 int err = 0;
3442 int idx;
3443
3444 if (length > 0) {
3445 err = -EEXIST;
3446 list_for_each_entry_safe(ckf, next_ckf,
3447 &ri->data.keyfields, ctrl.list) {
3448 key = ckf->ctrl.key;
3449 for (idx = 0; idx < length; ++idx)
3450 if (key == keylist[idx]) {
3451 list_del(&ckf->ctrl.list);
3452 kfree(ckf);
3453 idx++;
3454 err = 0;
3455 }
3456 }
3457 }
3458 if (drop_unsupported) {
3459 err = -EEXIST;
3460 fields = vcap_keyfields(ri->vctrl, ri->admin->vtype,
3461 rule->keyset);
3462 if (!fields)
3463 return err;
3464 list_for_each_entry_safe(ckf, next_ckf,
3465 &ri->data.keyfields, ctrl.list) {
3466 key = ckf->ctrl.key;
3467 if (fields[key].width == 0) {
3468 list_del(&ckf->ctrl.list);
3469 kfree(ckf);
3470 err = 0;
3471 }
3472 }
3473 }
3474 return err;
3475 }
3476 EXPORT_SYMBOL_GPL(vcap_filter_rule_keys);
3477
3478 /* Make a full copy of an existing rule with a new rule id */
vcap_copy_rule(struct vcap_rule * erule)3479 struct vcap_rule *vcap_copy_rule(struct vcap_rule *erule)
3480 {
3481 struct vcap_rule_internal *ri = to_intrule(erule);
3482 struct vcap_client_actionfield *caf;
3483 struct vcap_client_keyfield *ckf;
3484 struct vcap_rule *rule;
3485 int err;
3486
3487 err = vcap_api_check(ri->vctrl);
3488 if (err)
3489 return ERR_PTR(err);
3490
3491 rule = vcap_alloc_rule(ri->vctrl, ri->ndev, ri->data.vcap_chain_id,
3492 ri->data.user, ri->data.priority, 0);
3493 if (IS_ERR(rule))
3494 return rule;
3495
3496 list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {
3497 /* Add a key duplicate in the new rule */
3498 err = vcap_rule_add_key(rule,
3499 ckf->ctrl.key,
3500 ckf->ctrl.type,
3501 &ckf->data);
3502 if (err)
3503 goto err;
3504 }
3505
3506 list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {
3507 /* Add a action duplicate in the new rule */
3508 err = vcap_rule_add_action(rule,
3509 caf->ctrl.action,
3510 caf->ctrl.type,
3511 &caf->data);
3512 if (err)
3513 goto err;
3514 }
3515 return rule;
3516 err:
3517 vcap_free_rule(rule);
3518 return ERR_PTR(err);
3519 }
3520 EXPORT_SYMBOL_GPL(vcap_copy_rule);
3521
3522 #ifdef CONFIG_VCAP_KUNIT_TEST
3523 #include "vcap_api_kunit.c"
3524 #endif
3525