lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.4 043/167] arp: honour gratuitous ARP _replies_
    Date
    From: Ihar Hrachyshka <ihrachys@redhat.com>

    [ Upstream commit 23d268eb240954e6e78f7cfab04f2b1e79f84489 ]

    When arp_accept is 1, gratuitous ARPs are supposed to override matching
    entries irrespective of whether they arrive during locktime. This was
    implemented in commit 56022a8fdd87 ("ipv4: arp: update neighbour address
    when a gratuitous arp is received and arp_accept is set")

    There is a glitch in the patch though. RFC 2002, section 4.6, "ARP,
    Proxy ARP, and Gratuitous ARP", defines gratuitous ARPs so that they can
    be either of Request or Reply type. Those Reply gratuitous ARPs can be
    triggered with standard tooling, for example, arping -A option does just
    that.

    This patch fixes the glitch, making both Request and Reply flavours of
    gratuitous ARPs to behave identically.

    As per RFC, if gratuitous ARPs are of Reply type, their Target Hardware
    Address field should also be set to the link-layer address to which this
    cache entry should be updated. The field is present in ARP over Ethernet
    but not in IEEE 1394. In this patch, I don't consider any broadcasted
    ARP replies as gratuitous if the field is not present, to conform the
    standard. It's not clear whether there is such a thing for IEEE 1394 as
    a gratuitous ARP reply; until it's cleared up, we will ignore such
    broadcasts. Note that they will still update existing ARP cache entries,
    assuming they arrive out of locktime time interval.

    Signed-off-by: Ihar Hrachyshka <ihrachys@redhat.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    net/ipv4/arp.c | 16 ++++++++++++++--
    1 file changed, 14 insertions(+), 2 deletions(-)

    diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
    index cb5eb649ad5f..6bc16a01f1ee 100644
    --- a/net/ipv4/arp.c
    +++ b/net/ipv4/arp.c
    @@ -658,6 +658,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
    unsigned char *arp_ptr;
    struct rtable *rt;
    unsigned char *sha;
    + unsigned char *tha = NULL;
    __be32 sip, tip;
    u16 dev_type = dev->type;
    int addr_type;
    @@ -729,6 +730,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
    break;
    #endif
    default:
    + tha = arp_ptr;
    arp_ptr += dev->addr_len;
    }
    memcpy(&tip, arp_ptr, 4);
    @@ -839,8 +841,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
    It is possible, that this option should be enabled for some
    devices (strip is candidate)
    */
    - is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
    - addr_type == RTN_UNICAST;
    + is_garp = tip == sip && addr_type == RTN_UNICAST;
    +
    + /* Unsolicited ARP _replies_ also require target hwaddr to be
    + * the same as source.
    + */
    + if (is_garp && arp->ar_op == htons(ARPOP_REPLY))
    + is_garp =
    + /* IPv4 over IEEE 1394 doesn't provide target
    + * hardware address field in its ARP payload.
    + */
    + tha &&
    + !memcmp(tha, sha, dev->addr_len);

    if (!n &&
    ((arp->ar_op == htons(ARPOP_REPLY) &&
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-19 18:26    [W:4.138 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site