• Daniel Borkmann's avatar
    packet: infer protocol from ethernet header if unset · c72219b7
    Daniel Borkmann authored
    In case no struct sockaddr_ll has been passed to packet
    socket's sendmsg() when doing a TX_RING flush run, then
    skb->protocol is set to po->num instead, which is the protocol
    passed via socket(2)/bind(2).
    
    Applications only xmitting can go the path of allocating the
    socket as socket(PF_PACKET, <mode>, 0) and do a bind(2) on the
    TX_RING with sll_protocol of 0. That way, register_prot_hook()
    is neither called on creation nor on bind time, which saves
    cycles when there's no interest in capturing anyway.
    
    That leaves us however with po->num 0 instead and therefore
    the TX_RING flush run sets skb->protocol to 0 as well. Eric
    reported that this leads to problems when using tools like
    trafgen over bonding device. I.e. the bonding's hash function
    could invoke the kernel's flow dissector, which depends on
    skb->protocol being properly set. In the current situation, all
    the traffic is then directed to a single slave.
    
    Fix it up by inferring skb->protocol from the Ethernet header
    when not set and we have ARPHRD_ETHER device type. This is only
    done in case of SOCK_RAW and where we have a dev->hard_header_len
    length. In case of ARPHRD_ETHER devices, this is guaranteed to
    cover ETH_HLEN, and therefore being accessed on the skb after
    the skb_store_bits().
    Reported-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarWillem de Bruijn <willemb@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    c72219b7
af_packet.c 104 KB