From mboxrd@z Thu Jan 1 00:00:00 1970 From: Beilei Xing Subject: [PATCH 12/24] net/i40e: parse macvlan filter Date: Fri, 2 Dec 2016 06:53:33 -0500 Message-ID: <1480679625-4157-13-git-send-email-beilei.xing@intel.com> References: <1480679625-4157-1-git-send-email-beilei.xing@intel.com> Cc: dev@dpdk.org, wenzhuo.lu@intel.com To: jingjing.wu@intel.com, helin.zhang@intel.com Return-path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id BB6625598 for ; Fri, 2 Dec 2016 05:13:12 +0100 (CET) In-Reply-To: <1480679625-4157-1-git-send-email-beilei.xing@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Check if the rule is a macvlan rule, and get the macvlan info BTW. Signed-off-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.c | 160 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index c1623c4..18247c0 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "i40e_logs.h" #include "base/i40e_prototype.h" @@ -491,6 +492,11 @@ static void i40e_tunnel_filter_restore(struct i40e_pf *pf); static void i40e_rss_hash_restore(struct i40e_pf *pf); static void i40e_filter_restore(struct i40e_pf *pf); +static int i40e_parse_macvlan_filter(const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action *actions, + struct rte_eth_mac_filter *filter, + struct rte_flow_error *error); static int i40e_flow_validate(__rte_unused struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, @@ -10241,6 +10247,154 @@ i40e_filter_restore(struct i40e_pf *pf) } static int +i40e_parse_attr(const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + /* Must be input direction */ + if (!attr->ingress) { + error->type = RTE_FLOW_ERROR_TYPE_ATTR_INGRESS; + return -EINVAL; + } + + /* Not supported */ + if (attr->egress) { + error->type = RTE_FLOW_ERROR_TYPE_ATTR_EGRESS; + return -EINVAL; + } + + /* Not supported */ + if (attr->priority) { + error->type = RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY; + return -EINVAL; + } + + return 0; +} + +/** + * Parse the rule to see if it is a macvlan rule. + * And get the macvlan filter info BTW. + */ +static int +i40e_parse_macvlan_filter(const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action *actions, + struct rte_eth_mac_filter *filter, + struct rte_flow_error *error) +{ + const struct rte_flow_item *item; + const struct rte_flow_action *act; + const struct rte_flow_item_eth *eth_spec, *eth_mask; + const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; + const struct rte_flow_action_vf *act_vf; + struct ether_addr macaddr_unmasked = { + .addr_bytes = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + }; + struct ether_addr macaddr_masked = { + .addr_bytes = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} + }; + uint32_t i; + + /* Parse pattern */ + i = 0; + + /* the first item not void item should be ETH */ + PATTERN_SKIP_VOID(filter, struct rte_eth_mac_filter, + RTE_FLOW_ERROR_TYPE_ITEM_NUM); + if (item->type != RTE_FLOW_ITEM_TYPE_ETH) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + eth_spec = (const struct rte_flow_item_eth *)item->spec; + eth_mask = (const struct rte_flow_item_eth *)item->mask; + if (!eth_spec || !eth_mask) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + /** + * SRC MAC address should be masked. + * DST MAC address shouldn't be masked. + */ + if (!is_same_ether_addr(ð_mask->src, &macaddr_masked) || + !is_same_ether_addr(ð_mask->dst, &macaddr_unmasked)) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + /* Ethertype should be masked. */ + if (eth_mask->type) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + rte_memcpy(&filter->mac_addr, ð_spec->dst, ETHER_ADDR_LEN); + filter->filter_type = RTE_MAC_PERFECT_MATCH; + + i++; + PATTERN_SKIP_VOID(filter, struct rte_eth_mac_filter, + RTE_FLOW_ERROR_TYPE_ITEM_NUM); + + if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { + vlan_spec = (const struct rte_flow_item_vlan *)item->spec; + vlan_mask = (const struct rte_flow_item_vlan *)item->mask; + + if (!(vlan_spec && vlan_mask)) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + /* PRI and CFI should be masked. */ + if (vlan_mask->tci == rte_cpu_to_be_16(0x0FFF)) + filter->filter_type = RTE_MACVLAN_PERFECT_MATCH; + else if (vlan_mask->tci == 0x0) + filter->filter_type = RTE_MAC_PERFECT_MATCH; + else { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + i++; + PATTERN_SKIP_VOID(filter, struct rte_eth_mac_filter, + RTE_FLOW_ERROR_TYPE_ITEM_NUM); + } + + /* Check if the next not void item is END. */ + if (item->type != RTE_FLOW_ITEM_TYPE_END) { + error->type = RTE_FLOW_ERROR_TYPE_ITEM; + return -EINVAL; + } + + /* Parse action */ + i = 0; + + /* Check if the next not void item is VF. */ + ACTION_SKIP_VOID(filter, struct rte_eth_mac_filter, + RTE_FLOW_ERROR_TYPE_ACTION_NUM); + if (act->type != RTE_FLOW_ACTION_TYPE_VF) { + error->type = RTE_FLOW_ERROR_TYPE_ACTION; + return -EINVAL; + } + + filter->is_vf = 1; + + act_vf = (const struct rte_flow_action_vf *)act->conf; + filter->dst_id = act_vf->id; + + /* Check if the next not void item is END. */ + i++; + ACTION_SKIP_VOID(filter, struct rte_eth_mac_filter, + RTE_FLOW_ERROR_TYPE_ACTION_NUM); + if (act->type != RTE_FLOW_ACTION_TYPE_END) { + error->type = RTE_FLOW_ERROR_TYPE_ACTION; + return -EINVAL; + } + + return i40e_parse_attr(attr, error); +} + +static int i40e_flow_validate(__rte_unused struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, @@ -10248,6 +10402,7 @@ i40e_flow_validate(__rte_unused struct rte_eth_dev *dev, struct rte_flow_error *error) { struct rte_eth_ethertype_filter ethertype_filter; + struct rte_eth_mac_filter macvlan_filter; int ret; ret = cons_parse_ethertype_filter(attr, pattern, actions, @@ -10255,5 +10410,10 @@ i40e_flow_validate(__rte_unused struct rte_eth_dev *dev, if (!ret) return 0; + ret = i40e_parse_macvlan_filter(attr, pattern, actions, + &macvlan_filter, error); + if (!ret) + return 0; + return ret; } -- 2.5.5