From 4a74dc65e3ad825a66dfbcb256f98c550f96445b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Mar 2013 20:13:54 +0000 Subject: [PATCH] sfc: Allow efx_channel_type::receive_skb() to reject a packet Instead of having efx_ptp_rx() call netif_receive_skb() for an invalid PTP packet, make it return false for rejected packets and have efx_rx_deliver() pass them up. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 2 +- drivers/net/ethernet/sfc/ptp.c | 16 +++++++--------- drivers/net/ethernet/sfc/rx.c | 10 ++++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 0a90abd2421b..cdcf510311c3 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -410,7 +410,7 @@ struct efx_channel_type { void (*post_remove)(struct efx_channel *); void (*get_name)(struct efx_channel *, char *buf, size_t len); struct efx_channel *(*copy)(const struct efx_channel *); - void (*receive_skb)(struct efx_channel *, struct sk_buff *); + bool (*receive_skb)(struct efx_channel *, struct sk_buff *); bool keep_eventq; }; diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 3f93624fc273..faf4baf36861 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1006,7 +1006,7 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) * the receive timestamp from the MC - this will probably occur after the * packet arrival because of the processing in the MC. */ -static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) +static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) { struct efx_nic *efx = channel->efx; struct efx_ptp_data *ptp = efx->ptp_data; @@ -1019,18 +1019,15 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) /* Correct version? */ if (ptp->mode == MC_CMD_PTP_MODE_V1) { if (skb->len < PTP_V1_MIN_LENGTH) { - netif_receive_skb(skb); - return; + return false; } version = ntohs(*(__be16 *)&skb->data[PTP_V1_VERSION_OFFSET]); if (version != PTP_VERSION_V1) { - netif_receive_skb(skb); - return; + return false; } } else { if (skb->len < PTP_V2_MIN_LENGTH) { - netif_receive_skb(skb); - return; + return false; } version = skb->data[PTP_V2_VERSION_OFFSET]; @@ -1041,8 +1038,7 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH); if ((version & PTP_VERSION_V2_MASK) != PTP_VERSION_V2) { - netif_receive_skb(skb); - return; + return false; } } @@ -1073,6 +1069,8 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) skb_queue_tail(&ptp->rxq, skb); queue_work(ptp->workwq, &ptp->work); + + return true; } /* Transmit a PTP packet. This has to be transmitted by the MC diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index bb579a6128c8..f31c23ea2a07 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -575,12 +575,14 @@ static void efx_rx_deliver(struct efx_channel *channel, /* Record the rx_queue */ skb_record_rx_queue(skb, channel->rx_queue.core_index); - /* Pass the packet up */ if (channel->type->receive_skb) - channel->type->receive_skb(channel, skb); - else - netif_receive_skb(skb); + if (channel->type->receive_skb(channel, skb)) + goto handled; + /* Pass the packet up */ + netif_receive_skb(skb); + +handled: /* Update allocation strategy method */ channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; }