if (ipv4_is_loopback(tip) ||
ipv4_is_multicast(tip)) return;
if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) { if (br_is_neigh_suppress_enabled(p, vid)) return; if (is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
parp->ar_op == htons(ARPOP_REQUEST)) return; if (parp->ar_op != htons(ARPOP_RREQUEST) &&
parp->ar_op != htons(ARPOP_RREPLY) &&
(ipv4_is_zeronet(sip) || sip == tip)) { /* prevent flooding to neigh suppress ports */
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1; return;
}
}
if (parp->ar_op != htons(ARPOP_REQUEST)) return;
if (vid != 0) {
vlandev = __vlan_find_dev_deep_rcu(br->dev, skb->vlan_proto,
vid); if (!vlandev) return;
}
if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
br_is_local_ip(vlandev, tip)) { /* its our local ip, so don't proxy reply * and don't forward to neigh suppress ports
*/
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1; return;
}
n = neigh_lookup(&arp_tbl, &tip, vlandev); if (n) { struct net_bridge_fdb_entry *f;
if (!(READ_ONCE(n->nud_state) & NUD_VALID)) {
neigh_release(n); return;
}
f = br_fdb_find_rcu(br, n->ha, vid); if (f) { bool replied = false;
/* If we have replied or as long as we know the * mac, indicate to arp replied
*/ if (replied ||
br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
}
if (ipv6_addr_any(saddr) || !ipv6_addr_cmp(saddr, daddr)) { /* prevent flooding to neigh suppress ports */
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1; return;
}
if (vid != 0) { /* build neigh table lookup on the vlan device */
vlandev = __vlan_find_dev_deep_rcu(br->dev, skb->vlan_proto,
vid); if (!vlandev) return;
} else {
vlandev = dev;
}
if (br_is_local_ip6(vlandev, &msg->target)) { /* its our own ip, so don't proxy reply * and don't forward to arp suppress ports
*/
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1; return;
}
n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, vlandev); if (n) { struct net_bridge_fdb_entry *f;
if (!(READ_ONCE(n->nud_state) & NUD_VALID)) {
neigh_release(n); return;
}
f = br_fdb_find_rcu(br, n->ha, vid); if (f) { bool replied = false;
if (br_is_neigh_suppress_enabled(f->dst, vid)) { if (vid != 0)
br_nd_send(br, p, skb, n,
skb->vlan_proto,
skb_vlan_tag_get(skb), msg); else
br_nd_send(br, p, skb, n, 0, 0, msg);
replied = true;
}
/* If we have replied or as long as we know the * mac, indicate to NEIGH_SUPPRESS ports that we * have replied
*/ if (replied ||
br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
}
neigh_release(n);
}
} #endif
bool br_is_neigh_suppress_enabled(conststruct net_bridge_port *p, u16 vid)
{ if (!p) returnfalse;
if (!vid) return !!(p->flags & BR_NEIGH_SUPPRESS);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.