Patch "s390/qeth: no ETH header for outbound AF_IUCV" has been added to the 4.4-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
s390/qeth: no ETH header for outbound AF_IUCV
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
s390-qeth-no-eth-header-for-outbound-af_iucv.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Dec 21 10:35:49 CET 2017
From: Julian Wiedmann <[email protected]>
Date: Thu, 23 Mar 2017 14:55:09 +0100
Subject: s390/qeth: no ETH header for outbound AF_IUCV
From: Julian Wiedmann <[email protected]>
[ Upstream commit acd9776b5c45ef02d1a210969a6fcc058afb76e3 ]
With AF_IUCV traffic, the skb passed to hard_start_xmit() has a 14 byte slot at skb->data, intended for an ETH header. qeth_l3_fill_af_iucv_hdr() fills this ETH header... and then immediately moves it to the skb's headroom, where it disappears and is never seen again.
But it's still possible for us to return NETDEV_TX_BUSY after the skb has been modified. Since we didn't get a private copy of the skb, the next time the skb is delivered to hard_start_xmit() it no longer has the expected layout (we moved the ETH header to the headroom, so skb->data now starts at the IUCV_TRANS header). So when qeth_l3_fill_af_iucv_hdr() does another round of rebuilding, the resulting qeth header ends up all wrong. On transmission, the buffer is then rejected by the HiperSockets device with SBALF15 = x'04'.
When this error is passed back to af_iucv as TX_NOTIFY_UNREACHABLE, it tears down the offending socket.
As the ETH header for AF_IUCV serves no purpose, just align the code to what we do for IP traffic on L3 HiperSockets: keep the ETH header at skb->data, and pass down data_offset = ETH_HLEN to qeth_fill_buffer(). When mapping the payload into the SBAL elements, the ETH header is then stripped off. This avoids the skb manipulations in qeth_l3_fill_af_iucv_hdr(), and any buffer re-entering hard_start_xmit() after NETDEV_TX_BUSY is now processed properly.
--- drivers/s390/net/qeth_l3_main.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
drivers/s390/net/qeth_l3_main.c +4 -11
@@ -2680,17 +2680,13 @@ static void qeth_l3_fill_af_iucv_hdr(strchar daddr[16 ];struct af_iucv_trans_hdr *iucv_hdr; -skb_pull (skb,14 ); - card->dev->header_ops->create (skb, card->dev,0 , - card->dev->dev_addr, card->dev->dev_addr, - card->dev->addr_len); -skb_pull (skb,14 ); - iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;memset (hdr,0 ,sizeof (struct qeth_hdr )); hdr->hdr.l3.id =QETH_HEADER_TYPE_LAYER3 ; hdr->hdr.l3.ext_flags =0 ; - hdr->hdr.l3.length = skb->len; + hdr->hdr.l3.length = skb->len -ETH_HLEN ; hdr->hdr.l3.flags =QETH_HDR_IPV6 |QETH_CAST_UNICAST ; + + iucv_hdr = (struct af_iucv_trans_hdr *) (skb->data +ETH_HLEN );memset (daddr,0 ,sizeof (daddr)); daddr[0 ] =0xfe ; daddr[1 ] =0x80 ;
@@ -2873,10 +2869,7 @@ static int qeth_l3_hard_start_xmit(strucif ((card->info.type ==QETH_CARD_TYPE_IQD ) && (!large_send) && (skb_shinfo (skb)->nr_frags ==0 )) { new_skb = skb; -if (new_skb->protocol ==ETH_P_AF_IUCV ) - data_offset =0 ; -else - data_offset =ETH_HLEN ; + data_offset =ETH_HLEN ; hdr =kmem_cache_alloc (qeth_core_header_cache,GFP_ATOMIC );if (!hdr) goto tx_drop;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/s390-qeth-no-eth-header-for-outbound-af_iucv.patch