[Intel-wired-lan] [PATCH net v2] ice: fix adding different tunnels
Penigalapati, Sandeep
sandeep.penigalapati at intel.com
Tue Dec 7 09:48:47 UTC 2021
>-----Original Message-----
>From: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>
>Sent: Tuesday, December 7, 2021 12:16 PM
>To: intel-wired-lan at osuosl.org
>Cc: Penigalapati, Sandeep <sandeep.penigalapati at intel.com>
>Subject: Re: [Intel-wired-lan] [PATCH net v2] ice: fix adding different tunnels
>
>On Mon, Nov 22, 2021 at 04:39:25PM +0100, Michal Swiatkowski wrote:
>> Adding filters with the same values inside for VXLAN and geneve causes
>> hw error, because it looks exactly the same. To choose between
>> different type of tunnels new recipe is needed. Add storing tunnel
>> types in creatig recipes function and start checking it in finding function.
>>
>> Change getting open tunnels function to return port on correct tunnel
>> type. This is needed to copy correct port to dummy packet.
>>
>> Block user from adding enc_dst_port via tc flower, because VXLAN and
>> geneve filters can be created only with destination port which was
>> previously opened.
>>
>> v1 --> v2:
>> * fixed functions description (Tony)
>>
>> Fixes: 8b032a55c1bd5 ("ice: low level support for tunnels")
>> Signed-off-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>
>> ---
>> .../net/ethernet/intel/ice/ice_ethtool_fdir.c | 4 ++--
>> drivers/net/ethernet/intel/ice/ice_fdir.c | 2 +-
>> drivers/net/ethernet/intel/ice/ice_flex_pipe.c | 7 +++++--
>> drivers/net/ethernet/intel/ice/ice_flex_pipe.h | 3 ++-
>> drivers/net/ethernet/intel/ice/ice_switch.c | 18 +++++++++++++-----
>> drivers/net/ethernet/intel/ice/ice_tc_lib.c | 3 ++-
>> 6 files changed, 25 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
>> b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
>> index 68ac0be68107..bbc64d6ce4cd 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
>> @@ -1258,7 +1258,7 @@ ice_fdir_write_all_fltr(struct ice_pf *pf, struct
>ice_fdir_fltr *input,
>> bool is_tun = tun == ICE_FD_HW_SEG_TUN;
>> int err;
>>
>> - if (is_tun && !ice_get_open_tunnel_port(&pf->hw,
>&port_num))
>> + if (is_tun && !ice_get_open_tunnel_port(&pf->hw,
>&port_num,
>> +TNL_ALL))
>> continue;
>> err = ice_fdir_write_fltr(pf, input, add, is_tun);
>> if (err)
>> @@ -1642,7 +1642,7 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct
>ethtool_rxnfc *cmd)
>> }
>>
>> /* return error if not an update and no available filters */
>> - fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port) ? 2 : 1;
>> + fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port, TNL_ALL)
>?
>> +2 : 1;
>> if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) &&
>> ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) {
>> dev_err(dev, "Failed to add filter. The maximum number of
>flow
>> director filters has been reached.\n"); diff --git
>> a/drivers/net/ethernet/intel/ice/ice_fdir.c
>> b/drivers/net/ethernet/intel/ice/ice_fdir.c
>> index 9970ac3884f6..bbef6f4366de 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_fdir.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_fdir.c
>> @@ -924,7 +924,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw,
>struct ice_fdir_fltr *input,
>> memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
>> loc = pkt;
>> } else {
>> - if (!ice_get_open_tunnel_port(hw, &tnl_port))
>> + if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL))
>> return -ENOENT;
>> if (!ice_fdir_pkt[idx].tun_pkt)
>> return -EINVAL;
>> diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
>> b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
>> index b12da3cda78b..b197d3a72014 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
>> @@ -2040,9 +2040,11 @@ static struct ice_buf *ice_pkg_buf(struct
>ice_buf_build *bld)
>> * ice_get_open_tunnel_port - retrieve an open tunnel port
>> * @hw: pointer to the HW structure
>> * @port: returns open port
>> + * @type: type of tunnel, can be TNL_LAST if it doesn't matter
>> */
>> bool
>> -ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port)
>> +ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port,
>> + enum ice_tunnel_type type)
>> {
>> bool res = false;
>> u16 i;
>> @@ -2050,7 +2052,8 @@ ice_get_open_tunnel_port(struct ice_hw *hw, u16
>*port)
>> mutex_lock(&hw->tnl_lock);
>>
>> for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++)
>> - if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port) {
>> + if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port &&
>> + (type == TNL_LAST || type == hw->tnl.tbl[i].type)) {
>> *port = hw->tnl.tbl[i].port;
>> res = true;
>> break;
>> diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
>> b/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
>> index 1c2be376a537..dd602285c78e 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
>> +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
>> @@ -90,7 +90,8 @@ int
>> ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
>> unsigned long *bm, struct list_head *fv_list); bool
>> -ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port);
>> +ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port,
>> + enum ice_tunnel_type type);
>> int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
>> unsigned int idx, struct udp_tunnel_info *ti); int
>> ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int
>> table, diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c
>> b/drivers/net/ethernet/intel/ice/ice_switch.c
>> index c1dbac5f8d6b..7f7bf9815700 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_switch.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_switch.c
>> @@ -3792,10 +3792,13 @@ static struct ice_protocol_entry
>ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
>> * ice_find_recp - find a recipe
>> * @hw: pointer to the hardware structure
>> * @lkup_exts: extension sequence to match
>> + * @tun_type: type of recipe tunnel
>> *
>> * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not
>found.
>> */
>> -static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext
>> *lkup_exts)
>> +static u16
>> +ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
>> + enum ice_sw_tunnel_type tun_type)
>> {
>> bool refresh_required = true;
>> struct ice_sw_recipe *recp;
>> @@ -3856,8 +3859,9 @@ static u16 ice_find_recp(struct ice_hw *hw, struct
>ice_prot_lkup_ext *lkup_exts)
>> }
>> /* If for "i"th recipe the found was never set to false
>> * then it means we found our match
>> + * Also tun type of recipe needs to be checked
>> */
>> - if (found)
>> + if (found && recp[i].tun_type == tun_type)
>> return i; /* Return the recipe ID */
>> }
>> }
>> @@ -4647,11 +4651,12 @@ ice_add_adv_recipe(struct ice_hw *hw, struct
>ice_adv_lkup_elem *lkups,
>> }
>>
>> /* Look for a recipe which matches our requested fv / mask list */
>> - *rid = ice_find_recp(hw, lkup_exts);
>> + *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type);
>> if (*rid < ICE_MAX_NUM_RECIPES)
>> /* Success if found a recipe that match the existing criteria */
>> goto err_unroll;
>>
>> + rm->tun_type = rinfo->tun_type;
>> /* Recipe we need does not exist, add a recipe */
>> status = ice_add_sw_recipe(hw, rm, profiles);
>> if (status)
>> @@ -4954,8 +4959,11 @@ ice_fill_adv_packet_tun(struct ice_hw *hw,
>enum
>> ice_sw_tunnel_type tun_type,
>>
>> switch (tun_type) {
>> case ICE_SW_TUN_VXLAN:
>> + if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
>> + return -EIO;
>> + break;
>> case ICE_SW_TUN_GENEVE:
>> - if (!ice_get_open_tunnel_port(hw, &open_port))
>> + if (!ice_get_open_tunnel_port(hw, &open_port,
>TNL_GENEVE))
>> return -EIO;
>> break;
>>
>> @@ -5551,7 +5559,7 @@ ice_rem_adv_rule(struct ice_hw *hw, struct
>ice_adv_lkup_elem *lkups,
>> if (status)
>> return status;
>>
>> - rid = ice_find_recp(hw, &lkup_exts);
>> + rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type);
>> /* If did not find a recipe that match the existing criteria */
>> if (rid == ICE_MAX_NUM_RECIPES)
>> return -EINVAL;
>> diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
>> b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
>> index f243dacda8a0..e8feb41e6dbe 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
>> @@ -800,7 +800,8 @@ ice_parse_tunnel_attr(struct net_device *dev, struct
>flow_rule *rule,
>> headers->l3_mask.ttl = match.mask->ttl;
>> }
>>
>> - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
>> + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS)
>&&
>> + fltr->tunnel_type != TNL_VXLAN && fltr->tunnel_type !=
>> +TNL_GENEVE) {
>> struct flow_match_ports match;
>>
>> flow_rule_match_enc_ports(rule, &match);
>> --
>> 2.31.1
>Please add tested-by tag, after succesfull testing :)
>
Tested-by: Sandeep Penigalapati <sandeep.penigalapati at intel.com>
More information about the Intel-wired-lan
mailing list