From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [next-queue PATCH v2 8/8] igb: Add support for adding offloaded clsflower filters
Date: Tue, 06 Mar 2018 11:08:26 -0800 [thread overview]
Message-ID: <87muzl10ph.fsf@intel.com> (raw)
In-Reply-To: <20180305131350.326a886d@cakuba.netronome.com>
Hi,
Jakub Kicinski <kubakici@wp.pl> writes:
> On Fri, 2 Mar 2018 10:43:44 -0800, Vinicius Costa Gomes wrote:
>> This allows filters added by tc-flower and specifying MAC addresses,
>> Ethernet types, and the VLAN priority field, to be offloaded to the
>> controller.
>>
>> This reuses most of the infrastructure used by ethtool, ethtool can be
>> used to read these filters, but modification and deletion can only be
>> done via tc-flower.
>>
>> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
>> ---
>> drivers/net/ethernet/intel/igb/igb.h | 2 +
>> drivers/net/ethernet/intel/igb/igb_main.c | 176 +++++++++++++++++++++++++++++-
>> 2 files changed, 176 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
>> index 43ce6d64f693..0edd3a74d043 100644
>> --- a/drivers/net/ethernet/intel/igb/igb.h
>> +++ b/drivers/net/ethernet/intel/igb/igb.h
>> @@ -463,6 +463,7 @@ struct igb_nfc_input {
>> struct igb_nfc_filter {
>> struct hlist_node nfc_node;
>> struct igb_nfc_input filter;
>> + unsigned long cookie;
>> u16 etype_reg_index;
>> u16 sw_idx;
>> u16 action;
>> @@ -601,6 +602,7 @@ struct igb_adapter {
>>
>> /* RX network flow classification support */
>> struct hlist_head nfc_filter_list;
>> + struct hlist_head cls_flower_list;
>> unsigned int nfc_filter_count;
>> /* lock for RX network flow classification filter */
>> spinlock_t nfc_lock;
>> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
>> index b5a6bd37bb16..cbd2048b9110 100644
>> --- a/drivers/net/ethernet/intel/igb/igb_main.c
>> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
>> @@ -2397,6 +2397,12 @@ static int igb_set_features(struct net_device *netdev,
>> hlist_del(&rule->nfc_node);
>> kfree(rule);
>> }
>> + hlist_for_each_entry_safe(rule, node2,
>> + &adapter->cls_flower_list, nfc_node) {
>> + igb_erase_filter(adapter, rule);
>> + hlist_del(&rule->nfc_node);
>> + kfree(rule);
>> + }
>
> Hm. I don't think you should flush cls filters when someone disables
> NTUPLE. (a) ntuple is independent, (b) the in_hw flag will no longer
> reflect the actual state of the system.
Makes total sense. Will fix.
>
>> spin_unlock(&adapter->nfc_lock);
>> adapter->nfc_filter_count = 0;
>> }
>> @@ -2497,16 +2503,179 @@ static int igb_offload_cbs(struct igb_adapter *adapter,
>> return 0;
>> }
>>
>> +#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
>> +
>> +static int igb_parse_cls_flower(struct igb_adapter *adapter,
>> + struct tc_cls_flower_offload *f,
>> + int traffic_class,
>> + struct igb_nfc_filter *input)
>> +{
>> + if (f->dissector->used_keys &
>> + ~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
>> + BIT(FLOW_DISSECTOR_KEY_CONTROL) |
>> + BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
>> + BIT(FLOW_DISSECTOR_KEY_VLAN))) {
>> + dev_err(&adapter->pdev->dev, "Unsupported key used: 0x%x\n",
>> + f->dissector->used_keys);
>
> This will probably trigger for opportunistic offload (non-skip_sw) and
> confuse users.
>
I see your point. I will change to 'dev_warn()', it should not surprise
users too much, right?
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
>> + struct flow_dissector_key_eth_addrs *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_ETH_ADDRS,
>> + f->key);
>> +
>> + struct flow_dissector_key_eth_addrs *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_ETH_ADDRS,
>> + f->mask);
>
> You can do the assignment on separate lines to avoid strange variable
> declaration.
>
Fair enough. Will fix.
>> + if (is_broadcast_ether_addr(mask->dst)) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_DST_MAC_ADDR;
>> + ether_addr_copy(input->filter.dst_addr, key->dst);
>> + }
>> +
>> + if (is_broadcast_ether_addr(mask->src)) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_SRC_MAC_ADDR;
>> + ether_addr_copy(input->filter.src_addr, key->src);
>> + }
>
> If the mask is not full you need to reject the filter, I don't think
> you can just ignore the MAC if it's masked..
>
> Same two comments for conditions below.
Yeah, being silent in these cases can cause some confusion. Will
fix them.
>
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
>> + struct flow_dissector_key_basic *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_BASIC,
>> + f->key);
>> +
>> + struct flow_dissector_key_basic *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_BASIC,
>> + f->mask);
>> +
>> + if (mask->n_proto == ETHER_TYPE_FULL_MASK) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_ETHER_TYPE;
>> + input->filter.etype = key->n_proto;
>> + }
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
>> + struct flow_dissector_key_vlan *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_VLAN,
>> + f->key);
>> + struct flow_dissector_key_vlan *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_VLAN,
>> + f->mask);
>> +
>> + if (mask->vlan_priority) {
>> + input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI;
>> + input->filter.vlan_tci = key->vlan_priority;
>> + }
>> + }
>> +
>> + input->action = traffic_class;
>> + input->cookie = f->cookie;
>> +
>> + return 0;
>> +}
>> +
>> static int igb_configure_clsflower(struct igb_adapter *adapter,
>> struct tc_cls_flower_offload *cls_flower)
>> {
>> - return -EOPNOTSUPP;
>> + struct igb_nfc_filter *filter, *f;
>> + int err, tc;
>> +
>> + if (!(adapter->netdev->hw_features & NETIF_F_NTUPLE))
>> + return -EOPNOTSUPP;
>
> I'd rather there wasn't dependency on NTUPLEs for cls offloads.
>
Cool. Will remove this check.
>> + tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
>> + if (tc < 0) {
>> + dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
>> + return -EINVAL;
>> + }
>> +
>> + filter = kzalloc(sizeof(*filter), GFP_KERNEL);
>> + if (!filter)
>> + return -ENOMEM;
>> +
>> + err = igb_parse_cls_flower(adapter, cls_flower, tc, filter);
>> + if (err < 0) {
>> + dev_err(&adapter->pdev->dev, "Invalid cls_flower filter\n");
>> + goto err_parse;
>> + }
>> +
>> + spin_lock(&adapter->nfc_lock);
>> +
>> + hlist_for_each_entry(f, &adapter->nfc_filter_list, nfc_node) {
>> + if (!memcmp(&f->filter, &filter->filter, sizeof(f->filter))) {
>> + err = -EEXIST;
>> + dev_err(&adapter->pdev->dev,
>> + "This filter is already set in ethtool\n");
>
> Consider using extack too, maybe?
Yeah, will do.
>
>> + goto err_locked;
>> + }
>> + }
>> +
>> + hlist_for_each_entry(f, &adapter->cls_flower_list, nfc_node) {
>> + if (!memcmp(&f->filter, &filter->filter, sizeof(f->filter))) {
>> + err = -EEXIST;
>> + dev_err(&adapter->pdev->dev,
>> + "This filter is already set in cls_flower\n");
>> + goto err_locked;
>> + }
>> + }
>> +
>> + err = igb_add_filter(adapter, filter);
>> + if (err < 0)
>> + goto err_locked;
>> +
>> + hlist_add_head(&filter->nfc_node, &adapter->cls_flower_list);
>> +
>> + spin_unlock(&adapter->nfc_lock);
>> +
>> + return 0;
>> +
>> +err_locked:
>> + spin_unlock(&adapter->nfc_lock);
>> +
>> +err_parse:
>> + kfree(filter);
>> +
>> + return err;
>> }
Cheers,
--
Vinicius
WARNING: multiple messages have this Message-ID (diff)
From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
To: Jakub Kicinski <kubakici@wp.pl>
Cc: intel-wired-lan@lists.osuosl.org, jeffrey.t.kirsher@intel.com,
netdev@vger.kernel.org, jesus.sanchez-palencia@intel.com
Subject: Re: [next-queue PATCH v2 8/8] igb: Add support for adding offloaded clsflower filters
Date: Tue, 06 Mar 2018 11:08:26 -0800 [thread overview]
Message-ID: <87muzl10ph.fsf@intel.com> (raw)
In-Reply-To: <20180305131350.326a886d@cakuba.netronome.com>
Hi,
Jakub Kicinski <kubakici@wp.pl> writes:
> On Fri, 2 Mar 2018 10:43:44 -0800, Vinicius Costa Gomes wrote:
>> This allows filters added by tc-flower and specifying MAC addresses,
>> Ethernet types, and the VLAN priority field, to be offloaded to the
>> controller.
>>
>> This reuses most of the infrastructure used by ethtool, ethtool can be
>> used to read these filters, but modification and deletion can only be
>> done via tc-flower.
>>
>> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
>> ---
>> drivers/net/ethernet/intel/igb/igb.h | 2 +
>> drivers/net/ethernet/intel/igb/igb_main.c | 176 +++++++++++++++++++++++++++++-
>> 2 files changed, 176 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
>> index 43ce6d64f693..0edd3a74d043 100644
>> --- a/drivers/net/ethernet/intel/igb/igb.h
>> +++ b/drivers/net/ethernet/intel/igb/igb.h
>> @@ -463,6 +463,7 @@ struct igb_nfc_input {
>> struct igb_nfc_filter {
>> struct hlist_node nfc_node;
>> struct igb_nfc_input filter;
>> + unsigned long cookie;
>> u16 etype_reg_index;
>> u16 sw_idx;
>> u16 action;
>> @@ -601,6 +602,7 @@ struct igb_adapter {
>>
>> /* RX network flow classification support */
>> struct hlist_head nfc_filter_list;
>> + struct hlist_head cls_flower_list;
>> unsigned int nfc_filter_count;
>> /* lock for RX network flow classification filter */
>> spinlock_t nfc_lock;
>> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
>> index b5a6bd37bb16..cbd2048b9110 100644
>> --- a/drivers/net/ethernet/intel/igb/igb_main.c
>> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
>> @@ -2397,6 +2397,12 @@ static int igb_set_features(struct net_device *netdev,
>> hlist_del(&rule->nfc_node);
>> kfree(rule);
>> }
>> + hlist_for_each_entry_safe(rule, node2,
>> + &adapter->cls_flower_list, nfc_node) {
>> + igb_erase_filter(adapter, rule);
>> + hlist_del(&rule->nfc_node);
>> + kfree(rule);
>> + }
>
> Hm. I don't think you should flush cls filters when someone disables
> NTUPLE. (a) ntuple is independent, (b) the in_hw flag will no longer
> reflect the actual state of the system.
Makes total sense. Will fix.
>
>> spin_unlock(&adapter->nfc_lock);
>> adapter->nfc_filter_count = 0;
>> }
>> @@ -2497,16 +2503,179 @@ static int igb_offload_cbs(struct igb_adapter *adapter,
>> return 0;
>> }
>>
>> +#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
>> +
>> +static int igb_parse_cls_flower(struct igb_adapter *adapter,
>> + struct tc_cls_flower_offload *f,
>> + int traffic_class,
>> + struct igb_nfc_filter *input)
>> +{
>> + if (f->dissector->used_keys &
>> + ~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
>> + BIT(FLOW_DISSECTOR_KEY_CONTROL) |
>> + BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
>> + BIT(FLOW_DISSECTOR_KEY_VLAN))) {
>> + dev_err(&adapter->pdev->dev, "Unsupported key used: 0x%x\n",
>> + f->dissector->used_keys);
>
> This will probably trigger for opportunistic offload (non-skip_sw) and
> confuse users.
>
I see your point. I will change to 'dev_warn()', it should not surprise
users too much, right?
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
>> + struct flow_dissector_key_eth_addrs *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_ETH_ADDRS,
>> + f->key);
>> +
>> + struct flow_dissector_key_eth_addrs *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_ETH_ADDRS,
>> + f->mask);
>
> You can do the assignment on separate lines to avoid strange variable
> declaration.
>
Fair enough. Will fix.
>> + if (is_broadcast_ether_addr(mask->dst)) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_DST_MAC_ADDR;
>> + ether_addr_copy(input->filter.dst_addr, key->dst);
>> + }
>> +
>> + if (is_broadcast_ether_addr(mask->src)) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_SRC_MAC_ADDR;
>> + ether_addr_copy(input->filter.src_addr, key->src);
>> + }
>
> If the mask is not full you need to reject the filter, I don't think
> you can just ignore the MAC if it's masked..
>
> Same two comments for conditions below.
Yeah, being silent in these cases can cause some confusion. Will
fix them.
>
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
>> + struct flow_dissector_key_basic *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_BASIC,
>> + f->key);
>> +
>> + struct flow_dissector_key_basic *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_BASIC,
>> + f->mask);
>> +
>> + if (mask->n_proto == ETHER_TYPE_FULL_MASK) {
>> + input->filter.match_flags |=
>> + IGB_FILTER_FLAG_ETHER_TYPE;
>> + input->filter.etype = key->n_proto;
>> + }
>> + }
>> +
>> + if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
>> + struct flow_dissector_key_vlan *key =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_VLAN,
>> + f->key);
>> + struct flow_dissector_key_vlan *mask =
>> + skb_flow_dissector_target(f->dissector,
>> + FLOW_DISSECTOR_KEY_VLAN,
>> + f->mask);
>> +
>> + if (mask->vlan_priority) {
>> + input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI;
>> + input->filter.vlan_tci = key->vlan_priority;
>> + }
>> + }
>> +
>> + input->action = traffic_class;
>> + input->cookie = f->cookie;
>> +
>> + return 0;
>> +}
>> +
>> static int igb_configure_clsflower(struct igb_adapter *adapter,
>> struct tc_cls_flower_offload *cls_flower)
>> {
>> - return -EOPNOTSUPP;
>> + struct igb_nfc_filter *filter, *f;
>> + int err, tc;
>> +
>> + if (!(adapter->netdev->hw_features & NETIF_F_NTUPLE))
>> + return -EOPNOTSUPP;
>
> I'd rather there wasn't dependency on NTUPLEs for cls offloads.
>
Cool. Will remove this check.
>> + tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
>> + if (tc < 0) {
>> + dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
>> + return -EINVAL;
>> + }
>> +
>> + filter = kzalloc(sizeof(*filter), GFP_KERNEL);
>> + if (!filter)
>> + return -ENOMEM;
>> +
>> + err = igb_parse_cls_flower(adapter, cls_flower, tc, filter);
>> + if (err < 0) {
>> + dev_err(&adapter->pdev->dev, "Invalid cls_flower filter\n");
>> + goto err_parse;
>> + }
>> +
>> + spin_lock(&adapter->nfc_lock);
>> +
>> + hlist_for_each_entry(f, &adapter->nfc_filter_list, nfc_node) {
>> + if (!memcmp(&f->filter, &filter->filter, sizeof(f->filter))) {
>> + err = -EEXIST;
>> + dev_err(&adapter->pdev->dev,
>> + "This filter is already set in ethtool\n");
>
> Consider using extack too, maybe?
Yeah, will do.
>
>> + goto err_locked;
>> + }
>> + }
>> +
>> + hlist_for_each_entry(f, &adapter->cls_flower_list, nfc_node) {
>> + if (!memcmp(&f->filter, &filter->filter, sizeof(f->filter))) {
>> + err = -EEXIST;
>> + dev_err(&adapter->pdev->dev,
>> + "This filter is already set in cls_flower\n");
>> + goto err_locked;
>> + }
>> + }
>> +
>> + err = igb_add_filter(adapter, filter);
>> + if (err < 0)
>> + goto err_locked;
>> +
>> + hlist_add_head(&filter->nfc_node, &adapter->cls_flower_list);
>> +
>> + spin_unlock(&adapter->nfc_lock);
>> +
>> + return 0;
>> +
>> +err_locked:
>> + spin_unlock(&adapter->nfc_lock);
>> +
>> +err_parse:
>> + kfree(filter);
>> +
>> + return err;
>> }
Cheers,
--
Vinicius
next prev parent reply other threads:[~2018-03-06 19:08 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-02 18:43 [Intel-wired-lan] [next-queue PATCH v2 0/8] igb: offloading of receive filters Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 1/8] igb: Fix not adding filter elements to the list Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 2/8] igb: Fix queue selection on MAC filters on i210 and i211 Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 3/8] igb: Enable the hardware traffic class feature bit for igb models Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 4/8] igb: Add support for MAC address filters specifying source addresses Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 5/8] igb: Enable nfc filters to specify MAC addresses Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 6/8] igb: Add MAC address support for ethtool nftuple filters Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 7/8] igb: Add the skeletons for tc-flower offloading Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-02 18:43 ` [Intel-wired-lan] [next-queue PATCH v2 8/8] igb: Add support for adding offloaded clsflower filters Vinicius Costa Gomes
2018-03-02 18:43 ` Vinicius Costa Gomes
2018-03-05 21:13 ` [Intel-wired-lan] " Jakub Kicinski
2018-03-05 21:13 ` Jakub Kicinski
2018-03-06 19:08 ` Vinicius Costa Gomes [this message]
2018-03-06 19:08 ` Vinicius Costa Gomes
2018-03-06 19:28 ` [Intel-wired-lan] " Jakub Kicinski
2018-03-06 19:28 ` Jakub Kicinski
2018-03-06 21:26 ` [Intel-wired-lan] " Vinicius Costa Gomes
2018-03-06 21:26 ` Vinicius Costa Gomes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87muzl10ph.fsf@intel.com \
--to=vinicius.gomes@intel.com \
--cc=intel-wired-lan@osuosl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.