• Julian Wiedmann's avatar
    s390/qeth: no ETH header for outbound AF_IUCV · acd9776b
    Julian Wiedmann authored
    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.
    Signed-off-by: default avatarJulian Wiedmann <jwi@linux.vnet.ibm.com>
    Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    acd9776b
qeth_l3_main.c 89.8 KB