mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
aoe: pull in the headers each received packet type reads
aoenet_rcv() only pulls the AoE and ATA headers into the skb head when
the packet is long enough to hold both. A shorter packet goes through
unpulled, and aoenet_rcv() reads the AoE header from it anyway. CFG
responses go on to aoecmd_cfg_rsp(), which reads the config header
after it, and ATA responses get queued for ktiocomplete(), which
skb_pull()s both headers. Ethernet pads frames to 60 bytes, so this
mostly takes a virtual link, but nothing stops a short frame from
getting here.
Pull the AoE header up front and drop the packet if it isn't there,
then pull the ATA or config header in the switch arm that hands the
packet on, so each path gets the headers it reads. This also replaces
the open-coded __pskb_pull_tail() with pskb_may_pull().
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261007-b4-aoe-short-packets-v1-1-db5155f7bb9c@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
b766aba70e
commit
e1274a6bc4
|
|
@ -131,9 +131,7 @@ static int
|
|||
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
|
||||
{
|
||||
struct aoe_hdr *h;
|
||||
struct aoe_atahdr *ah;
|
||||
u32 n;
|
||||
int sn;
|
||||
|
||||
if (dev_net(ifp) != &init_net)
|
||||
goto exit;
|
||||
|
|
@ -144,12 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
|
|||
if (!is_aoe_netif(ifp))
|
||||
goto exit;
|
||||
skb_push(skb, ETH_HLEN); /* (1) */
|
||||
sn = sizeof(*h) + sizeof(*ah);
|
||||
if (skb->len >= sn) {
|
||||
sn -= skb_headlen(skb);
|
||||
if (sn > 0 && !__pskb_pull_tail(skb, sn))
|
||||
goto exit;
|
||||
}
|
||||
if (!pskb_may_pull(skb, sizeof(*h)))
|
||||
goto exit;
|
||||
h = (struct aoe_hdr *) skb->data;
|
||||
n = get_unaligned_be32(&h->tag);
|
||||
if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
|
||||
|
|
@ -171,10 +165,14 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
|
|||
|
||||
switch (h->cmd) {
|
||||
case AOECMD_ATA:
|
||||
if (!pskb_may_pull(skb, sizeof(*h) + sizeof(struct aoe_atahdr)))
|
||||
goto exit;
|
||||
/* ata_rsp may keep skb for later processing or give it back */
|
||||
skb = aoecmd_ata_rsp(skb);
|
||||
break;
|
||||
case AOECMD_CFG:
|
||||
if (!pskb_may_pull(skb, sizeof(*h) + sizeof(struct aoe_cfghdr)))
|
||||
goto exit;
|
||||
aoecmd_cfg_rsp(skb);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user