return;
if (parp->ar_op != htons(ARPOP_RREQUEST) &&
parp->ar_op != htons(ARPOP_RREPLY) &&
- (ipv4_is_zeronet(sip) || sip == tip)) {
+ sip == tip) {
/* prevent flooding to neigh suppress ports */
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
return;
int ns_olen;
int i, len;
u8 *daddr;
+ bool dad;
u16 pvid;
if (!dev || skb_linearize(request))
}
}
+ dad = ipv6_addr_any(&ipv6_hdr(request)->saddr);
+
/* Ethernet header */
- ether_addr_copy(eth_hdr(reply)->h_dest, daddr);
+ if (dad)
+ ipv6_eth_mc_map(&in6addr_linklocal_allnodes, eth_hdr(reply)->h_dest);
+ else
+ ether_addr_copy(eth_hdr(reply)->h_dest, daddr);
ether_addr_copy(eth_hdr(reply)->h_source, n->ha);
eth_hdr(reply)->h_proto = htons(ETH_P_IPV6);
reply->protocol = htons(ETH_P_IPV6);
pip6->priority = ipv6_hdr(request)->priority;
pip6->nexthdr = IPPROTO_ICMPV6;
pip6->hop_limit = 255;
- pip6->daddr = ipv6_hdr(request)->saddr;
+ pip6->daddr = dad ? in6addr_linklocal_allnodes : ipv6_hdr(request)->saddr;
pip6->saddr = *(struct in6_addr *)n->primary_key;
skb_pull(reply, sizeof(struct ipv6hdr));
na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
na->icmph.icmp6_router = (n->flags & NTF_ROUTER) ? 1 : 0;
na->icmph.icmp6_override = 1;
- na->icmph.icmp6_solicited = 1;
+ na->icmph.icmp6_solicited = dad ? 0 : 1;
na->target = ns->target;
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
saddr = &iphdr->saddr;
daddr = &iphdr->daddr;
- if (ipv6_addr_any(saddr) || !ipv6_addr_cmp(saddr, daddr)) {
+ if (!ipv6_addr_cmp(saddr, daddr)) {
/* prevent flooding to neigh suppress ports */
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
return;