|
8 | 8 |
|
9 | 9 | #include "vcap_api_private.h" |
10 | 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 | + |
11 | 33 | /* Moving a rule in the VCAP address space */ |
12 | 34 | struct vcap_rule_move { |
13 | 35 | int addr; /* address to move */ |
@@ -1312,12 +1334,67 @@ const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule, |
1312 | 1334 | } |
1313 | 1335 | EXPORT_SYMBOL_GPL(vcap_lookup_keyfield); |
1314 | 1336 |
|
| 1337 | +/* Copy data from src to dst but reverse the data in chunks of 32bits. |
| 1338 | + * For example if src is 00:11:22:33:44:55 where 55 is LSB the dst will |
| 1339 | + * have the value 22:33:44:55:00:11. |
| 1340 | + */ |
| 1341 | +static void vcap_copy_to_w32be(u8 *dst, u8 *src, int size) |
| 1342 | +{ |
| 1343 | + for (int idx = 0; idx < size; ++idx) { |
| 1344 | + int first_byte_index = 0; |
| 1345 | + int nidx; |
| 1346 | + |
| 1347 | + first_byte_index = size - (((idx >> 2) + 1) << 2); |
| 1348 | + if (first_byte_index < 0) |
| 1349 | + first_byte_index = 0; |
| 1350 | + nidx = idx + first_byte_index - (idx & ~0x3); |
| 1351 | + dst[nidx] = src[idx]; |
| 1352 | + } |
| 1353 | +} |
| 1354 | + |
1315 | 1355 | static void vcap_copy_from_client_keyfield(struct vcap_rule *rule, |
1316 | 1356 | struct vcap_client_keyfield *field, |
1317 | 1357 | struct vcap_client_keyfield_data *data) |
1318 | 1358 | { |
1319 | | - /* This will be expanded later to handle different vcap memory layouts */ |
1320 | | - memcpy(&field->data, data, sizeof(field->data)); |
| 1359 | + struct vcap_rule_internal *ri = to_intrule(rule); |
| 1360 | + int size; |
| 1361 | + |
| 1362 | + if (!ri->admin->w32be) { |
| 1363 | + memcpy(&field->data, data, sizeof(field->data)); |
| 1364 | + return; |
| 1365 | + } |
| 1366 | + |
| 1367 | + size = keyfield_size_table[field->ctrl.type] / 2; |
| 1368 | + switch (field->ctrl.type) { |
| 1369 | + case VCAP_FIELD_BIT: |
| 1370 | + case VCAP_FIELD_U32: |
| 1371 | + memcpy(&field->data, data, sizeof(field->data)); |
| 1372 | + break; |
| 1373 | + case VCAP_FIELD_U48: |
| 1374 | + vcap_copy_to_w32be(field->data.u48.value, data->u48.value, size); |
| 1375 | + vcap_copy_to_w32be(field->data.u48.mask, data->u48.mask, size); |
| 1376 | + break; |
| 1377 | + case VCAP_FIELD_U56: |
| 1378 | + vcap_copy_to_w32be(field->data.u56.value, data->u56.value, size); |
| 1379 | + vcap_copy_to_w32be(field->data.u56.mask, data->u56.mask, size); |
| 1380 | + break; |
| 1381 | + case VCAP_FIELD_U64: |
| 1382 | + vcap_copy_to_w32be(field->data.u64.value, data->u64.value, size); |
| 1383 | + vcap_copy_to_w32be(field->data.u64.mask, data->u64.mask, size); |
| 1384 | + break; |
| 1385 | + case VCAP_FIELD_U72: |
| 1386 | + vcap_copy_to_w32be(field->data.u72.value, data->u72.value, size); |
| 1387 | + vcap_copy_to_w32be(field->data.u72.mask, data->u72.mask, size); |
| 1388 | + break; |
| 1389 | + case VCAP_FIELD_U112: |
| 1390 | + vcap_copy_to_w32be(field->data.u112.value, data->u112.value, size); |
| 1391 | + vcap_copy_to_w32be(field->data.u112.mask, data->u112.mask, size); |
| 1392 | + break; |
| 1393 | + case VCAP_FIELD_U128: |
| 1394 | + vcap_copy_to_w32be(field->data.u128.value, data->u128.value, size); |
| 1395 | + vcap_copy_to_w32be(field->data.u128.mask, data->u128.mask, size); |
| 1396 | + break; |
| 1397 | + }; |
1321 | 1398 | } |
1322 | 1399 |
|
1323 | 1400 | /* Check if the keyfield is already in the rule */ |
@@ -1475,8 +1552,39 @@ static void vcap_copy_from_client_actionfield(struct vcap_rule *rule, |
1475 | 1552 | struct vcap_client_actionfield *field, |
1476 | 1553 | struct vcap_client_actionfield_data *data) |
1477 | 1554 | { |
1478 | | - /* This will be expanded later to handle different vcap memory layouts */ |
1479 | | - memcpy(&field->data, data, sizeof(field->data)); |
| 1555 | + struct vcap_rule_internal *ri = to_intrule(rule); |
| 1556 | + int size; |
| 1557 | + |
| 1558 | + if (!ri->admin->w32be) { |
| 1559 | + memcpy(&field->data, data, sizeof(field->data)); |
| 1560 | + return; |
| 1561 | + } |
| 1562 | + |
| 1563 | + size = actionfield_size_table[field->ctrl.type]; |
| 1564 | + switch (field->ctrl.type) { |
| 1565 | + case VCAP_FIELD_BIT: |
| 1566 | + case VCAP_FIELD_U32: |
| 1567 | + memcpy(&field->data, data, sizeof(field->data)); |
| 1568 | + break; |
| 1569 | + case VCAP_FIELD_U48: |
| 1570 | + vcap_copy_to_w32be(field->data.u48.value, data->u48.value, size); |
| 1571 | + break; |
| 1572 | + case VCAP_FIELD_U56: |
| 1573 | + vcap_copy_to_w32be(field->data.u56.value, data->u56.value, size); |
| 1574 | + break; |
| 1575 | + case VCAP_FIELD_U64: |
| 1576 | + vcap_copy_to_w32be(field->data.u64.value, data->u64.value, size); |
| 1577 | + break; |
| 1578 | + case VCAP_FIELD_U72: |
| 1579 | + vcap_copy_to_w32be(field->data.u72.value, data->u72.value, size); |
| 1580 | + break; |
| 1581 | + case VCAP_FIELD_U112: |
| 1582 | + vcap_copy_to_w32be(field->data.u112.value, data->u112.value, size); |
| 1583 | + break; |
| 1584 | + case VCAP_FIELD_U128: |
| 1585 | + vcap_copy_to_w32be(field->data.u128.value, data->u128.value, size); |
| 1586 | + break; |
| 1587 | + }; |
1480 | 1588 | } |
1481 | 1589 |
|
1482 | 1590 | /* Check if the actionfield is already in the rule */ |
|
0 commit comments