Commit 08d0b16e authored by Edward Cree's avatar Edward Cree Committed by Jakub Kicinski
Browse files

sfc: check ef100 RX packets are from the wire



If not, for now drop them and warn.  A subsequent patch will look up
 the source m-port to try and find a representor to deliver them to.

Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 6f6838aa
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -55,10 +55,14 @@ static bool ef100_has_fcs_error(struct efx_channel *channel, u32 *prefix)

void __ef100_rx_packet(struct efx_channel *channel)
{
	struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue, channel->rx_pkt_index);
	struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
	struct efx_rx_buffer *rx_buf = efx_rx_buffer(rx_queue,
						     channel->rx_pkt_index);
	struct efx_nic *efx = channel->efx;
	struct ef100_nic_data *nic_data;
	u8 *eh = efx_rx_buf_va(rx_buf);
	__wsum csum = 0;
	u16 ing_port;
	u32 *prefix;

	prefix = (u32 *)(eh - ESE_GZ_RX_PKT_PREFIX_LEN);
@@ -76,6 +80,19 @@ void __ef100_rx_packet(struct efx_channel *channel)
		goto out;
	}

	ing_port = le16_to_cpu((__force __le16) PREFIX_FIELD(prefix, INGRESS_MPORT));

	nic_data = efx->nic_data;

	if (nic_data->have_mport && ing_port != nic_data->base_mport) {
		if (net_ratelimit())
			netif_warn(efx, drv, efx->net_dev,
				   "Unrecognised ing_port %04x (base %04x), dropping\n",
				   ing_port, nic_data->base_mport);
		channel->n_rx_mport_bad++;
		goto free_rx_buffer;
	}

	if (likely(efx->net_dev->features & NETIF_F_RXCSUM)) {
		if (PREFIX_FIELD(prefix, NT_OR_INNER_L3_CLASS) == 1) {
			++channel->n_rx_ip_hdr_chksum_err;
@@ -87,17 +104,16 @@ void __ef100_rx_packet(struct efx_channel *channel)
	}

	if (channel->type->receive_skb) {
		struct efx_rx_queue *rx_queue =
			efx_channel_get_rx_queue(channel);

		/* no support for special channels yet, so just discard */
		WARN_ON_ONCE(1);
		efx_free_rx_buffers(rx_queue, rx_buf, 1);
		goto out;
		goto free_rx_buffer;
	}

	efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh, csum);
	goto out;

free_rx_buffer:
	efx_free_rx_buffers(rx_queue, rx_buf, 1);
out:
	channel->rx_pkt_n_frags = 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = {
	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_bad_drops),
	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_tx),
	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_redirect),
	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mport_bad),
#ifdef CONFIG_RFS_ACCEL
	EFX_ETHTOOL_UINT_CHANNEL_STAT_NO_N(rfs_filter_count),
	EFX_ETHTOOL_UINT_CHANNEL_STAT(rfs_succeeded),
+3 −0
Original line number Diff line number Diff line
@@ -478,6 +478,8 @@ enum efx_sync_events_state {
 * @n_rx_xdp_bad_drops: Count of RX packets dropped due to XDP errors
 * @n_rx_xdp_tx: Count of RX packets retransmitted due to XDP
 * @n_rx_xdp_redirect: Count of RX packets redirected to a different NIC by XDP
 * @n_rx_mport_bad: Count of RX packets dropped because their ingress mport was
 *	not recognised
 * @rx_pkt_n_frags: Number of fragments in next packet to be delivered by
 *	__efx_rx_packet(), or zero if there is none
 * @rx_pkt_index: Ring index of first buffer for next packet to be delivered
@@ -540,6 +542,7 @@ struct efx_channel {
	unsigned int n_rx_xdp_bad_drops;
	unsigned int n_rx_xdp_tx;
	unsigned int n_rx_xdp_redirect;
	unsigned int n_rx_mport_bad;

	unsigned int rx_pkt_n_frags;
	unsigned int rx_pkt_index;