}
 EXPORT_SYMBOL(arp_xmit);
 
-static bool arp_is_garp(struct net_device *dev, int addr_type,
-                       __be16 ar_op,
+static bool arp_is_garp(struct net *net, struct net_device *dev,
+                       int *addr_type, __be16 ar_op,
                        __be32 sip, __be32 tip,
                        unsigned char *sha, unsigned char *tha)
 {
-       bool is_garp = tip == sip && addr_type == RTN_UNICAST;
+       bool is_garp = tip == sip;
 
        /* Gratuitous ARP _replies_ also require target hwaddr to be
         * the same as source.
                        tha &&
                        !memcmp(tha, sha, dev->addr_len);
 
+       if (is_garp) {
+               *addr_type = inet_addr_type_dev_table(net, dev, sip);
+               if (*addr_type != RTN_UNICAST)
+                       is_garp = false;
+       }
        return is_garp;
 }
 
        n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
 
        if (IN_DEV_ARP_ACCEPT(in_dev)) {
-               unsigned int addr_type = inet_addr_type_dev_table(net, dev, sip);
+               addr_type = -1;
 
                /* Unsolicited ARP is not accepted by default.
                   It is possible, that this option should be enabled for some
                   devices (strip is candidate)
                 */
-               is_garp = arp_is_garp(dev, addr_type, arp->ar_op,
+               is_garp = arp_is_garp(net, dev, &addr_type, arp->ar_op,
                                      sip, tip, sha, tha);
 
                if (!n &&
-                   ((arp->ar_op == htons(ARPOP_REPLY)  &&
-                               addr_type == RTN_UNICAST) || is_garp))
+                   (is_garp ||
+                    (arp->ar_op == htons(ARPOP_REPLY) &&
+                     (addr_type == RTN_UNICAST ||
+                      (addr_type < 0 &&
+                       /* postpone calculation to as late as possible */
+                       inet_addr_type_dev_table(net, dev, sip) ==
+                               RTN_UNICAST)))))
                        n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
        }