Add the corresponding data structure and logics, to support the offload
of IPv4 item.

Signed-off-by: Chaoyong He <chaoyong...@corigine.com>
Reviewed-by: Long Wu <long...@corigine.com>
Reviewed-by: Peng Zhang <peng.zh...@corigine.com>
---
 drivers/net/nfp/nfp_net_cmsg.h | 37 ++++++++++++++++++++++
 drivers/net/nfp/nfp_net_flow.c | 58 ++++++++++++++++++++++++++++++++--
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h
index a95f4ef831..9bc064d9d7 100644
--- a/drivers/net/nfp/nfp_net_cmsg.h
+++ b/drivers/net/nfp/nfp_net_cmsg.h
@@ -21,6 +21,43 @@ struct nfp_net_cmsg_match_eth {
        uint16_t spare;
 };
 
+/**
+ * Match IPv4 data
+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word  +-----+-------------------------+---------------+---------------+
+ *    0  |     |        Position         |   L4 Proto    | L4 Proto Mask |
+ *       +-----+-------------------------+---------------+---------------+
+ *    1  |                             SIP4                              |
+ *       +---------------------------------------------------------------+
+ *    2  |                           SIP4 Mask                           |
+ *       +---------------------------------------------------------------+
+ *    3  |                             DIP4                              |
+ *       +---------------------------------------------------------------+
+ *    4  |                           DIP4 Mask                           |
+ *       +-------------------------------+-------------------------------+
+ *    5  |             SPort             |           SPort Mask          |
+ *       +-------------------------------+-------------------------------+
+ *    6  |             DPort             |           DPort Mask          |
+ *       +-----------------+-------------+-------------------------------+
+ *
+ * Position – Position index of the rule, 13bits.
+ *            As priority, smaller value indicates higher priority.
+ */
+struct nfp_net_cmsg_match_v4 {
+       uint8_t l4_protocol_mask;
+       uint8_t l4_protocol;
+       uint16_t position;
+       uint32_t src_ipv4;
+       uint32_t src_ipv4_mask;
+       uint32_t dst_ipv4;
+       uint32_t dst_ipv4_mask;
+       uint16_t src_port;
+       uint16_t src_port_mask;
+       uint16_t dst_port;
+       uint16_t dst_port_mask;
+};
+
 #define NFP_NET_CMSG_ACTION_DROP          (0x1 << 0) /* Drop action */
 #define NFP_NET_CMSG_ACTION_QUEUE         (0x1 << 1) /* Queue action */
 #define NFP_NET_CMSG_ACTION_MARK          (0x1 << 2) /* Mark action */
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index c8b6902bf1..6edb96c17a 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -188,6 +188,10 @@ nfp_net_flow_calculate_items(const struct rte_flow_item 
items[],
                        PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_ETH detected");
                        *match_len = sizeof(struct nfp_net_cmsg_match_eth);
                        return 0;
+               case RTE_FLOW_ITEM_TYPE_IPV4:
+                       PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected");
+                       *match_len = sizeof(struct nfp_net_cmsg_match_v4);
+                       return 0;
                default:
                        PMD_DRV_LOG(ERR, "Can't calculate match length");
                        *match_len = 0;
@@ -220,14 +224,58 @@ nfp_net_flow_merge_eth(__rte_unused struct rte_flow 
*nfp_flow,
        return 0;
 }
 
+static int
+nfp_net_flow_merge_ipv4(struct rte_flow *nfp_flow,
+               const struct rte_flow_item *item,
+               const struct nfp_net_flow_item_proc *proc)
+{
+       struct nfp_net_cmsg_match_v4 *ipv4;
+       const struct rte_flow_item_ipv4 *mask;
+       const struct rte_flow_item_ipv4 *spec;
+
+       spec = item->spec;
+       if (spec == NULL) {
+               PMD_DRV_LOG(DEBUG, "NFP flow merge ipv4: no item->spec!");
+               return 0;
+       }
+
+       mask = (item->mask != NULL) ? item->mask : proc->mask_default;
+
+       nfp_flow->payload.cmsg_type = NFP_NET_CFG_MBOX_CMD_FS_ADD_V4;
+       ipv4 = (struct nfp_net_cmsg_match_v4 *)nfp_flow->payload.match_data;
+
+       ipv4->l4_protocol_mask = mask->hdr.next_proto_id;
+       ipv4->src_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.src_addr);
+       ipv4->dst_ipv4_mask    = rte_be_to_cpu_32(mask->hdr.dst_addr);
+
+       ipv4->l4_protocol  = spec->hdr.next_proto_id;
+       ipv4->src_ipv4     = rte_be_to_cpu_32(spec->hdr.src_addr);
+       ipv4->dst_ipv4     = rte_be_to_cpu_32(spec->hdr.dst_addr);
+
+       return 0;
+}
+
 /* Graph of supported items and associated process function */
 static const struct nfp_net_flow_item_proc nfp_net_flow_item_proc_list[] = {
        [RTE_FLOW_ITEM_TYPE_END] = {
-               .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+               .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH,
+                               RTE_FLOW_ITEM_TYPE_IPV4),
        },
        [RTE_FLOW_ITEM_TYPE_ETH] = {
                .merge = nfp_net_flow_merge_eth,
        },
+       [RTE_FLOW_ITEM_TYPE_IPV4] = {
+               .mask_support = &(const struct rte_flow_item_ipv4){
+                       .hdr = {
+                               .next_proto_id = 0xff,
+                               .src_addr      = RTE_BE32(0xffffffff),
+                               .dst_addr      = RTE_BE32(0xffffffff),
+                       },
+               },
+               .mask_default = &rte_flow_item_ipv4_mask,
+               .mask_sz = sizeof(struct rte_flow_item_ipv4),
+               .merge = nfp_net_flow_merge_ipv4,
+       },
 };
 
 static int
@@ -367,10 +415,16 @@ nfp_net_flow_compile_actions(const struct rte_flow_action 
actions[],
 }
 
 static void
-nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,
+nfp_net_flow_process_priority(struct rte_flow *nfp_flow,
                uint32_t match_len)
 {
+       struct nfp_net_cmsg_match_v4 *ipv4;
+
        switch (match_len) {
+       case sizeof(struct nfp_net_cmsg_match_v4):
+               ipv4 = (struct nfp_net_cmsg_match_v4 
*)nfp_flow->payload.match_data;
+               ipv4->position = nfp_flow->position;
+               break;
        default:
                break;
        }
-- 
2.39.1

Reply via email to