ice: fix adding different tunnels
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 creating 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. Fixes: 8b032a55c1bd5 ("ice: low level support for tunnels") Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
0e32ff0240
commit
de6acd1cdd
@ -1268,7 +1268,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)
|
||||
@ -1652,7 +1652,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");
|
||||
|
@ -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 ICE_ERR_DOES_NOT_EXIST;
|
||||
if (!ice_fdir_pkt[idx].tun_pkt)
|
||||
return ICE_ERR_PARAM;
|
||||
|
@ -1899,9 +1899,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;
|
||||
@ -1909,7 +1911,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;
|
||||
|
@ -33,7 +33,8 @@ enum ice_status
|
||||
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,
|
||||
|
@ -3796,10 +3796,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;
|
||||
@ -3860,8 +3863,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 */
|
||||
}
|
||||
}
|
||||
@ -4651,11 +4655,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)
|
||||
@ -4958,11 +4963,13 @@ ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
|
||||
|
||||
switch (tun_type) {
|
||||
case ICE_SW_TUN_VXLAN:
|
||||
case ICE_SW_TUN_GENEVE:
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port))
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
|
||||
return ICE_ERR_CFG;
|
||||
break;
|
||||
case ICE_SW_TUN_GENEVE:
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
|
||||
return ICE_ERR_CFG;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Nothing needs to be done for this tunnel type */
|
||||
return 0;
|
||||
@ -5555,7 +5562,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 ICE_ERR_PARAM;
|
||||
|
@ -795,7 +795,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user