sfc: check ef100 RX packets are from the wire
authorEdward Cree <ecree.xilinx@gmail.com>
Thu, 28 Jul 2022 18:57:47 +0000 (19:57 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 30 Jul 2022 04:22:06 +0000 (21:22 -0700)
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: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/sfc/ef100_rx.c
drivers/net/ethernet/sfc/ethtool_common.c
drivers/net/ethernet/sfc/net_driver.h

index 85207ac..b8da9e3 100644 (file)
@@ -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;
 }
index 58ad9d6..bc840ed 100644 (file)
@@ -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),
index 4cde54c..6b64ba3 100644 (file)
@@ -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;