X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=61813bb4cb41e33b84f0c704d25ed3dd0eeb5038;hb=5d0ae1387c968859b390dba9768ce44ac788405b;hp=8314c5392bd2b73c8e332bc1aab336ac551c045d;hpb=9d82ec478d52edfddd215dff1b0659ed7508b365;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 8314c539..61813bb4 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -2269,12 +2269,17 @@ update_learning_table(struct bridge *br, const flow_t *flow, int vlan, } } +/* A VM broadcasts a gratuitous ARP to indicate that it has resumed after + * migration. Older Citrix-patched Linux DomU used gratuitous ARP replies to + * indicate this; newer upstream kernels use gratuitous ARP requests. */ static bool -is_bcast_arp_reply(const flow_t *flow) +is_gratuitous_arp(const flow_t *flow) { return (flow->dl_type == htons(ETH_TYPE_ARP) - && flow->nw_proto == ARP_OP_REPLY - && eth_addr_is_broadcast(flow->dl_dst)); + && eth_addr_is_broadcast(flow->dl_dst) + && (flow->nw_proto == ARP_OP_REPLY + || (flow->nw_proto == ARP_OP_REQUEST + && flow->nw_src == flow->nw_dst))); } /* Determines whether packets in 'flow' within 'br' should be forwarded or @@ -2366,11 +2371,11 @@ is_admissible(struct bridge *br, const flow_t *flow, bool have_packet, /* Drop all packets for which we have learned a different input * port, because we probably sent the packet on one slave and got - * it back on the other. Broadcast ARP replies are an exception + * it back on the other. Gratuitous ARP packets are an exception * to this rule: the host has moved to another switch. */ src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan); if (src_idx != -1 && src_idx != in_port->port_idx && - !is_bcast_arp_reply(flow)) { + !is_gratuitous_arp(flow)) { return false; } }