Add new adminq commands for the driver to configure flow rules that are stored in the device. For configuring flow rules, 3 sub commands are supported. - create: creates a new flow rule with a specific rule_id. - destroy: deletes an existing flow rule with the specified rule_id. - flush: clears and deletes all currently active flow rules.
Co-developed-by: Vee Agarwal <[email protected]> Signed-off-by: Vee Agarwal <[email protected]> Signed-off-by: Jasper Tran O'Leary <[email protected]> --- drivers/net/gve/base/gve_adminq.c | 52 +++++++++++++++++++++++++++ drivers/net/gve/base/gve_adminq.h | 30 ++++++++++++++++ drivers/net/gve/gve_ethdev.h | 1 + drivers/net/gve/gve_flow_rule.h | 59 +++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 dpdk/drivers/net/gve/gve_flow_rule.h diff --git a/drivers/net/gve/base/gve_adminq.c b/drivers/net/gve/base/gve_adminq.c index 0cc6d44..9a94591 100644 --- a/drivers/net/gve/base/gve_adminq.c +++ b/drivers/net/gve/base/gve_adminq.c @@ -239,6 +239,7 @@ int gve_adminq_alloc(struct gve_priv *priv) priv->adminq_report_stats_cnt = 0; priv->adminq_report_link_speed_cnt = 0; priv->adminq_get_ptype_map_cnt = 0; + priv->adminq_cfg_flow_rule_cnt = 0; /* Setup Admin queue with the device */ rte_pci_read_config(priv->pci_dev, &pci_rev_id, sizeof(pci_rev_id), @@ -487,6 +488,9 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv, case GVE_ADMINQ_VERIFY_DRIVER_COMPATIBILITY: priv->adminq_verify_driver_compatibility_cnt++; break; + case GVE_ADMINQ_CONFIGURE_FLOW_RULE: + priv->adminq_cfg_flow_rule_cnt++; + break; default: PMD_DRV_LOG(ERR, "unknown AQ command opcode %d", opcode); } @@ -546,6 +550,54 @@ static int gve_adminq_execute_extended_cmd(struct gve_priv *priv, u32 opcode, return err; } +static int +gve_adminq_configure_flow_rule(struct gve_priv *priv, + struct gve_adminq_configure_flow_rule *flow_rule_cmd) +{ + int err = gve_adminq_execute_extended_cmd(priv, + GVE_ADMINQ_CONFIGURE_FLOW_RULE, + sizeof(struct gve_adminq_configure_flow_rule), + flow_rule_cmd); + + return err; +} + +int gve_adminq_add_flow_rule(struct gve_priv *priv, + struct gve_flow_rule_params *rule, u32 loc) +{ + struct gve_adminq_configure_flow_rule flow_rule_cmd = { + .opcode = cpu_to_be16(GVE_FLOW_RULE_CFG_ADD), + .location = cpu_to_be32(loc), + .rule = { + .flow_type = cpu_to_be16(rule->flow_type), + .action = cpu_to_be16(rule->action), + .key = rule->key, + .mask = rule->mask, + }, + }; + + return gve_adminq_configure_flow_rule(priv, &flow_rule_cmd); +} + +int gve_adminq_del_flow_rule(struct gve_priv *priv, u32 loc) +{ + struct gve_adminq_configure_flow_rule flow_rule_cmd = { + .opcode = cpu_to_be16(GVE_FLOW_RULE_CFG_DEL), + .location = cpu_to_be32(loc), + }; + + return gve_adminq_configure_flow_rule(priv, &flow_rule_cmd); +} + +int gve_adminq_reset_flow_rules(struct gve_priv *priv) +{ + struct gve_adminq_configure_flow_rule flow_rule_cmd = { + .opcode = cpu_to_be16(GVE_FLOW_RULE_CFG_RESET), + }; + + return gve_adminq_configure_flow_rule(priv, &flow_rule_cmd); +} + /* The device specifies that the management vector can either be the first irq * or the last irq. ntfy_blk_msix_base_idx indicates the first irq assigned to * the ntfy blks. It if is 0 then the management vector is last, if it is 1 then diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h index f52658e..d8e5e6a 100644 --- a/drivers/net/gve/base/gve_adminq.h +++ b/drivers/net/gve/base/gve_adminq.h @@ -7,6 +7,7 @@ #define _GVE_ADMINQ_H #include "gve_osdep.h" +#include "../gve_flow_rule.h" /* Admin queue opcodes */ enum gve_adminq_opcodes { @@ -34,6 +35,10 @@ enum gve_adminq_opcodes { * inner opcode of gve_adminq_extended_cmd_opcodes specified. The inner command * is written in the dma memory allocated by GVE_ADMINQ_EXTENDED_COMMAND. */ +enum gve_adminq_extended_cmd_opcodes { + GVE_ADMINQ_CONFIGURE_FLOW_RULE = 0x101, +}; + /* Admin queue status codes */ enum gve_adminq_statuses { GVE_ADMINQ_COMMAND_UNSET = 0x0, @@ -434,6 +439,26 @@ struct gve_adminq_configure_rss { __be64 indir_addr; }; +/* Flow rule definition for the admin queue using network byte order (big + * endian). This struct represents the hardware wire format and should not be + * used outside of admin queue contexts. + */ +struct gve_adminq_flow_rule { + __be16 flow_type; + __be16 action; /* RX queue id */ + struct gve_flow_spec key; + struct gve_flow_spec mask; +}; + +struct gve_adminq_configure_flow_rule { + __be16 opcode; + u8 padding[2]; + struct gve_adminq_flow_rule rule; + __be32 location; +}; + +GVE_CHECK_STRUCT_LEN(92, gve_adminq_configure_flow_rule); + union gve_adminq_command { struct { __be32 opcode; @@ -499,4 +524,9 @@ int gve_adminq_verify_driver_compatibility(struct gve_priv *priv, int gve_adminq_configure_rss(struct gve_priv *priv, struct gve_rss_config *rss_config); +int gve_adminq_add_flow_rule(struct gve_priv *priv, + struct gve_flow_rule_params *rule, u32 loc); +int gve_adminq_del_flow_rule(struct gve_priv *priv, u32 loc); +int gve_adminq_reset_flow_rules(struct gve_priv *priv); + #endif /* _GVE_ADMINQ_H */ diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h index 3a810b6..4e07ca8 100644 --- a/drivers/net/gve/gve_ethdev.h +++ b/drivers/net/gve/gve_ethdev.h @@ -314,6 +314,7 @@ struct gve_priv { uint32_t adminq_report_link_speed_cnt; uint32_t adminq_get_ptype_map_cnt; uint32_t adminq_verify_driver_compatibility_cnt; + uint32_t adminq_cfg_flow_rule_cnt; volatile uint32_t state_flags; /* Gvnic device link speed from hypervisor. */ diff --git a/drivers/net/gve/gve_flow_rule.h b/drivers/net/gve/gve_flow_rule.h new file mode 100644 index 0000000..d1a2622 --- /dev/null +++ b/drivers/net/gve/gve_flow_rule.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2022 Intel Corporation + */ + +#ifndef _GVE_FLOW_RULE_H_ +#define _GVE_FLOW_RULE_H_ + +#include "base/gve_osdep.h" + +enum gve_adminq_flow_rule_cfg_opcode { + GVE_FLOW_RULE_CFG_ADD = 0, + GVE_FLOW_RULE_CFG_DEL = 1, + GVE_FLOW_RULE_CFG_RESET = 2, +}; + +enum gve_adminq_flow_type { + GVE_FLOW_TYPE_TCPV4, + GVE_FLOW_TYPE_UDPV4, + GVE_FLOW_TYPE_SCTPV4, + GVE_FLOW_TYPE_AHV4, + GVE_FLOW_TYPE_ESPV4, + GVE_FLOW_TYPE_TCPV6, + GVE_FLOW_TYPE_UDPV6, + GVE_FLOW_TYPE_SCTPV6, + GVE_FLOW_TYPE_AHV6, + GVE_FLOW_TYPE_ESPV6, +}; + +struct gve_flow_spec { + __be32 src_ip[4]; + __be32 dst_ip[4]; + union { + struct { + __be16 src_port; + __be16 dst_port; + }; + __be32 spi; + }; + union { + u8 tos; + u8 tclass; + }; +}; + +/* Flow rule parameters using mixed endianness. + * - flow_type and action are guest endian. + * - key and mask are in network byte order (big endian), matching rte_flow. + * This struct is used by the driver when validating and creating flow rules; + * guest endian fields are only converted to network byte order within admin + * queue functions. + */ +struct gve_flow_rule_params { + u16 flow_type; + u16 action; /* RX queue id */ + struct gve_flow_spec key; + struct gve_flow_spec mask; +}; + +#endif /* _GVE_FLOW_RULE_H_ */ -- 2.53.0.473.g4a7958ca14-goog

