|
9 | 9 | #include <rte_hash.h> |
10 | 10 | #include <rte_jhash.h> |
11 | 11 |
|
12 | | -#include "../nfp_flow.h" |
13 | 12 | #include "../nfp_logs.h" |
| 13 | +#include "nfp_flower_cmsg.h" |
14 | 14 | #include "nfp_flower_representor.h" |
15 | 15 |
|
16 | 16 | struct ct_data { |
@@ -59,6 +59,7 @@ struct nfp_ct_merge_entry { |
59 | 59 | LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list; |
60 | 60 | LIST_ENTRY(nfp_ct_merge_entry) post_ct_list; |
61 | 61 | struct nfp_initial_flow rule; |
| 62 | + struct rte_flow *compiled_rule; |
62 | 63 | struct nfp_ct_zone_entry *ze; |
63 | 64 | struct nfp_ct_flow_entry *pre_ct_parent; |
64 | 65 | struct nfp_ct_flow_entry *post_ct_parent; |
@@ -975,6 +976,102 @@ nfp_ct_zone_entry_free(struct nfp_ct_zone_entry *ze, |
975 | 976 | } |
976 | 977 | } |
977 | 978 |
|
| 979 | +static int |
| 980 | +nfp_ct_offload_add(struct nfp_flower_representor *repr, |
| 981 | + struct nfp_ct_merge_entry *merge_entry) |
| 982 | +{ |
| 983 | + int ret; |
| 984 | + uint64_t cookie; |
| 985 | + struct rte_flow *nfp_flow; |
| 986 | + struct nfp_flow_priv *priv; |
| 987 | + const struct rte_flow_item *items; |
| 988 | + const struct rte_flow_action *actions; |
| 989 | + |
| 990 | + cookie = rte_rand(); |
| 991 | + items = merge_entry->rule.items; |
| 992 | + actions = merge_entry->rule.actions; |
| 993 | + nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true); |
| 994 | + if (nfp_flow == NULL) { |
| 995 | + PMD_DRV_LOG(ERR, "Process the merged flow rule failed."); |
| 996 | + return -EINVAL; |
| 997 | + } |
| 998 | + |
| 999 | + /* Add the flow to hardware */ |
| 1000 | + priv = repr->app_fw_flower->flow_priv; |
| 1001 | + ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow); |
| 1002 | + if (ret != 0) { |
| 1003 | + PMD_DRV_LOG(ERR, "Add the merged flow to firmware failed."); |
| 1004 | + goto flow_teardown; |
| 1005 | + } |
| 1006 | + |
| 1007 | + /* Add the flow to flow hash table */ |
| 1008 | + ret = nfp_flow_table_add(priv, nfp_flow); |
| 1009 | + if (ret != 0) { |
| 1010 | + PMD_DRV_LOG(ERR, "Add the merged flow to flow table failed."); |
| 1011 | + goto flow_teardown; |
| 1012 | + } |
| 1013 | + |
| 1014 | + merge_entry->compiled_rule = nfp_flow; |
| 1015 | + |
| 1016 | + return 0; |
| 1017 | + |
| 1018 | +flow_teardown: |
| 1019 | + nfp_flow_teardown(priv, nfp_flow, false); |
| 1020 | + nfp_flow_free(nfp_flow); |
| 1021 | + |
| 1022 | + return ret; |
| 1023 | +} |
| 1024 | + |
| 1025 | +int |
| 1026 | +nfp_ct_offload_del(struct rte_eth_dev *dev, |
| 1027 | + struct nfp_ct_map_entry *me, |
| 1028 | + struct rte_flow_error *error) |
| 1029 | +{ |
| 1030 | + int ret; |
| 1031 | + struct nfp_ct_flow_entry *fe; |
| 1032 | + struct nfp_ct_merge_entry *m_ent; |
| 1033 | + |
| 1034 | + fe = me->fe; |
| 1035 | + |
| 1036 | + if (fe->type == CT_TYPE_PRE_CT) { |
| 1037 | + LIST_FOREACH(m_ent, &fe->children, pre_ct_list) { |
| 1038 | + if (m_ent->compiled_rule != NULL) { |
| 1039 | + ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error); |
| 1040 | + if (ret != 0) { |
| 1041 | + PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item"); |
| 1042 | + return -EINVAL; |
| 1043 | + } |
| 1044 | + m_ent->compiled_rule = NULL; |
| 1045 | + } |
| 1046 | + |
| 1047 | + m_ent->pre_ct_parent = NULL; |
| 1048 | + LIST_REMOVE(m_ent, pre_ct_list); |
| 1049 | + if (m_ent->post_ct_parent == NULL) |
| 1050 | + nfp_ct_merge_entry_destroy(m_ent); |
| 1051 | + } |
| 1052 | + } else { |
| 1053 | + LIST_FOREACH(m_ent, &fe->children, post_ct_list) { |
| 1054 | + if (m_ent->compiled_rule != NULL) { |
| 1055 | + ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error); |
| 1056 | + if (ret != 0) { |
| 1057 | + PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item"); |
| 1058 | + return -EINVAL; |
| 1059 | + } |
| 1060 | + m_ent->compiled_rule = NULL; |
| 1061 | + } |
| 1062 | + |
| 1063 | + m_ent->post_ct_parent = NULL; |
| 1064 | + LIST_REMOVE(m_ent, post_ct_list); |
| 1065 | + if (m_ent->pre_ct_parent == NULL) |
| 1066 | + nfp_ct_merge_entry_destroy(m_ent); |
| 1067 | + } |
| 1068 | + } |
| 1069 | + |
| 1070 | + nfp_ct_flow_entry_destroy_partly(fe); |
| 1071 | + |
| 1072 | + return 0; |
| 1073 | +} |
| 1074 | + |
978 | 1075 | static inline bool |
979 | 1076 | is_item_check_pass(const struct rte_flow_item *item1, |
980 | 1077 | const struct rte_flow_item *item2, |
@@ -1402,8 +1499,17 @@ nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze, |
1402 | 1499 | goto free_actions; |
1403 | 1500 | } |
1404 | 1501 |
|
| 1502 | + /* Send to firmware */ |
| 1503 | + ret = nfp_ct_offload_add(pre_ct_entry->repr, merge_entry); |
| 1504 | + if (ret != 0) { |
| 1505 | + PMD_DRV_LOG(ERR, "Send the merged flow to firmware failed"); |
| 1506 | + goto merge_table_del; |
| 1507 | + } |
| 1508 | + |
1405 | 1509 | return true; |
1406 | 1510 |
|
| 1511 | +merge_table_del: |
| 1512 | + nfp_ct_merge_table_delete(ze, merge_entry); |
1407 | 1513 | free_actions: |
1408 | 1514 | rte_free(merge_entry->rule.actions); |
1409 | 1515 | free_items: |
@@ -1490,7 +1596,7 @@ nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item, |
1490 | 1596 | } |
1491 | 1597 | } |
1492 | 1598 |
|
1493 | | - /* The real offload logic comes in next commit, so here just return false for now */ |
| 1599 | + return true; |
1494 | 1600 |
|
1495 | 1601 | ct_flow_entry_free: |
1496 | 1602 | nfp_ct_flow_entry_destroy(fe); |
@@ -1559,7 +1665,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item, |
1559 | 1665 | if (!ret) |
1560 | 1666 | goto ct_flow_entry_free; |
1561 | 1667 |
|
1562 | | - /* The real offload logic comes in next commit, so here just return false for now */ |
| 1668 | + return true; |
1563 | 1669 |
|
1564 | 1670 | ct_flow_entry_free: |
1565 | 1671 | nfp_ct_flow_entry_destroy(fe); |
|
0 commit comments