Commit 22963454 authored by Mateusz Pacuszka's avatar Mateusz Pacuszka Committed by Tony Nguyen
Browse files

ice: receive LLDP on trusted VFs



When a trusted VF tries to configure an LLDP multicast address, configure a
rule that would mirror the traffic to this VF, untrusted VFs are not
allowed to receive LLDP at all, so the request to add LLDP MAC address will
always fail for them.

Add a forwarding LLDP filter to a trusted VF when it tries to add an LLDP
multicast MAC address. The MAC address has to be added after enabling
trust (through restarting the LLDP service).

Signed-off-by: default avatarMateusz Pacuszka <mateuszx.pacuszka@intel.com>
Co-developed-by: default avatarLarysa Zaremba <larysa.zaremba@intel.com>
Signed-off-by: default avatarLarysa Zaremba <larysa.zaremba@intel.com>
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 4d5a1c4e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -846,7 +846,7 @@ int ice_init_pf_dcb(struct ice_pf *pf, bool locked)
			goto dcb_init_err;
		}

		ice_cfg_sw_lldp(pf_vsi, false, true);
		ice_cfg_sw_rx_lldp(pf, true);

		pf->dcbx_cap = ice_dcb_get_mode(port_info, true);
		return 0;
+1 −1
Original line number Diff line number Diff line
@@ -1818,7 +1818,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
			/* Remove rule to direct LLDP packets to default VSI.
			 * The FW LLDP engine will now be consuming them.
			 */
			ice_cfg_sw_lldp(vsi, false, false);
			ice_cfg_sw_rx_lldp(vsi->back, false);

			/* AQ command to start FW LLDP agent will return an
			 * error if the agent is already started
+42 −6
Original line number Diff line number Diff line
@@ -2065,12 +2065,15 @@ static void ice_vsi_set_tc_cfg(struct ice_vsi *vsi)
}

/**
 * ice_cfg_sw_lldp - Config switch rules for LLDP packet handling
 * ice_vsi_cfg_sw_lldp - Config switch rules for LLDP packet handling
 * @vsi: the VSI being configured
 * @tx: bool to determine Tx or Rx rule
 * @create: bool to determine create or remove Rule
 *
 * Adding an ethtype Tx rule to the uplink VSI results in it being applied
 * to the whole port, so LLDP transmission for VFs will be blocked too.
 */
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create)
void ice_vsi_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create)
{
	int (*eth_fltr)(struct ice_vsi *v, u16 type, u16 flag,
			enum ice_sw_fwd_act_type act);
@@ -2109,6 +2112,37 @@ void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create)
			 vsi->vsi_num, status);
}

/**
 * ice_cfg_sw_rx_lldp - Enable/disable software handling of LLDP
 * @pf: the PF being configured
 * @enable: enable or disable
 *
 * Configure switch rules to enable/disable LLDP handling by software
 * across PF.
 */
void ice_cfg_sw_rx_lldp(struct ice_pf *pf, bool enable)
{
	struct ice_vsi *vsi;
	struct ice_vf *vf;
	unsigned int bkt;

	vsi = ice_get_main_vsi(pf);
	ice_vsi_cfg_sw_lldp(vsi, false, enable);

	if (!test_bit(ICE_FLAG_SRIOV_ENA, pf->flags))
		return;

	ice_for_each_vf(pf, bkt, vf) {
		vsi = ice_get_vf_vsi(vf);

		if (WARN_ON(!vsi))
			continue;

		if (ice_vf_is_lldp_ena(vf))
			ice_vsi_cfg_sw_lldp(vsi, false, enable);
	}
}

/**
 * ice_set_agg_vsi - sets up scheduler aggregator node and move VSI into it
 * @vsi: pointer to the VSI
@@ -2537,7 +2571,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_vsi_cfg_params *params)
	if (!ice_is_safe_mode(pf) && vsi->type == ICE_VSI_PF) {
		ice_fltr_add_eth(vsi, ETH_P_PAUSE, ICE_FLTR_TX,
				 ICE_DROP_PACKET);
		ice_cfg_sw_lldp(vsi, true, true);
		ice_vsi_cfg_sw_lldp(vsi, true, true);
	}

	if (!vsi->agg_node)
@@ -2834,9 +2868,11 @@ int ice_vsi_release(struct ice_vsi *vsi)
	/* The Rx rule will only exist to remove if the LLDP FW
	 * engine is currently stopped
	 */
	if (!ice_is_safe_mode(pf) && vsi->type == ICE_VSI_PF &&
	    !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
		ice_cfg_sw_lldp(vsi, false, false);
	if (!ice_is_safe_mode(pf) &&
	    !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags) &&
	    (vsi->type == ICE_VSI_PF || (vsi->type == ICE_VSI_VF &&
	     ice_vf_is_lldp_ena(vsi->vf))))
		ice_vsi_cfg_sw_lldp(vsi, false, false);

	ice_vsi_decfg(vsi);

+2 −1
Original line number Diff line number Diff line
@@ -29,7 +29,8 @@ ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,

int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);

void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
void ice_vsi_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
void ice_cfg_sw_rx_lldp(struct ice_pf *pf, bool enable);

int ice_set_link(struct ice_vsi *vsi, bool ena);

+4 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ static void ice_free_vf_res(struct ice_vf *vf)
	if (vf->lan_vsi_idx != ICE_NO_VSI) {
		ice_vf_vsi_release(vf);
		vf->num_mac = 0;
		vf->num_mac_lldp = 0;
	}

	last_vector_idx = vf->first_vector_idx + vf->num_msix - 1;
@@ -1402,6 +1403,9 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)

	mutex_lock(&vf->cfg_lock);

	while (!trusted && vf->num_mac_lldp)
		ice_vf_update_mac_lldp_num(vf, ice_get_vf_vsi(vf), false);

	vf->trusted = trusted;
	ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
	dev_info(ice_pf_to_dev(pf), "VF %u is now %strusted\n",
Loading