X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=61813bb4cb41e33b84f0c704d25ed3dd0eeb5038;hb=5d0ae1387c968859b390dba9768ce44ac788405b;hp=354d4d89452a46adef4771dbbf478cb6a23d35de;hpb=2457b24fc5c935ec8c2930f9df923fc37b8bb38e;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 354d4d89..61813bb4 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1986,11 +1987,11 @@ bond_wait(struct bridge *br) for (j = 0; j < port->n_ifaces; j++) { struct iface *iface = port->ifaces[j]; if (iface->delay_expires != LLONG_MAX) { - poll_timer_wait(iface->delay_expires - time_msec()); + poll_timer_wait_until(iface->delay_expires); } } if (port->bond_fake_iface) { - poll_timer_wait(port->bond_next_fake_iface_update - time_msec()); + poll_timer_wait_until(port->bond_next_fake_iface_update); } } } @@ -2268,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 @@ -2365,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; } }