diff options
-rw-r--r-- | net/ipv4/arp.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index ca6e1e6c1496..c22103cec823 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -641,12 +641,12 @@ void arp_xmit(struct sk_buff *skb) | |||
641 | } | 641 | } |
642 | EXPORT_SYMBOL(arp_xmit); | 642 | EXPORT_SYMBOL(arp_xmit); |
643 | 643 | ||
644 | static bool arp_is_garp(struct net_device *dev, int addr_type, | 644 | static bool arp_is_garp(struct net *net, struct net_device *dev, |
645 | __be16 ar_op, | 645 | int *addr_type, __be16 ar_op, |
646 | __be32 sip, __be32 tip, | 646 | __be32 sip, __be32 tip, |
647 | unsigned char *sha, unsigned char *tha) | 647 | unsigned char *sha, unsigned char *tha) |
648 | { | 648 | { |
649 | bool is_garp = tip == sip && addr_type == RTN_UNICAST; | 649 | bool is_garp = tip == sip; |
650 | 650 | ||
651 | /* Gratuitous ARP _replies_ also require target hwaddr to be | 651 | /* Gratuitous ARP _replies_ also require target hwaddr to be |
652 | * the same as source. | 652 | * the same as source. |
@@ -659,6 +659,11 @@ static bool arp_is_garp(struct net_device *dev, int addr_type, | |||
659 | tha && | 659 | tha && |
660 | !memcmp(tha, sha, dev->addr_len); | 660 | !memcmp(tha, sha, dev->addr_len); |
661 | 661 | ||
662 | if (is_garp) { | ||
663 | *addr_type = inet_addr_type_dev_table(net, dev, sip); | ||
664 | if (*addr_type != RTN_UNICAST) | ||
665 | is_garp = false; | ||
666 | } | ||
662 | return is_garp; | 667 | return is_garp; |
663 | } | 668 | } |
664 | 669 | ||
@@ -859,18 +864,23 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
859 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); | 864 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); |
860 | 865 | ||
861 | if (IN_DEV_ARP_ACCEPT(in_dev)) { | 866 | if (IN_DEV_ARP_ACCEPT(in_dev)) { |
862 | unsigned int addr_type = inet_addr_type_dev_table(net, dev, sip); | 867 | addr_type = -1; |
863 | 868 | ||
864 | /* Unsolicited ARP is not accepted by default. | 869 | /* Unsolicited ARP is not accepted by default. |
865 | It is possible, that this option should be enabled for some | 870 | It is possible, that this option should be enabled for some |
866 | devices (strip is candidate) | 871 | devices (strip is candidate) |
867 | */ | 872 | */ |
868 | is_garp = arp_is_garp(dev, addr_type, arp->ar_op, | 873 | is_garp = arp_is_garp(net, dev, &addr_type, arp->ar_op, |
869 | sip, tip, sha, tha); | 874 | sip, tip, sha, tha); |
870 | 875 | ||
871 | if (!n && | 876 | if (!n && |
872 | ((arp->ar_op == htons(ARPOP_REPLY) && | 877 | (is_garp || |
873 | addr_type == RTN_UNICAST) || is_garp)) | 878 | (arp->ar_op == htons(ARPOP_REPLY) && |
879 | (addr_type == RTN_UNICAST || | ||
880 | (addr_type < 0 && | ||
881 | /* postpone calculation to as late as possible */ | ||
882 | inet_addr_type_dev_table(net, dev, sip) == | ||
883 | RTN_UNICAST))))) | ||
874 | n = __neigh_lookup(&arp_tbl, &sip, dev, 1); | 884 | n = __neigh_lookup(&arp_tbl, &sip, dev, 1); |
875 | } | 885 | } |
876 | 886 | ||