From: Jesse Gross Date: Fri, 14 Aug 2009 21:23:44 +0000 (-0700) Subject: bridge: Allow flows based on ARP opcode to be installed. X-Git-Tag: v0.90.7~33 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=69d60f9f4e8d8f1930cea759e67037f47b1bdddb;p=sliver-openvswitch.git bridge: Allow flows based on ARP opcode to be installed. Since we can now distinguish between flows with different ARP opcodes in the kernel, allow these flows to be installed. --- diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 05003e1c1..157dc6866 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1791,13 +1791,11 @@ compose_actions(struct bridge *br, const flow_t *flow, uint16_t vlan, } static bool -is_bcast_arp_reply(const flow_t *flow, const struct ofpbuf *packet) +is_bcast_arp_reply(const flow_t *flow) { - struct arp_eth_header *arp = (struct arp_eth_header *) packet->data; return (flow->dl_type == htons(ETH_TYPE_ARP) - && eth_addr_is_broadcast(flow->dl_dst) - && packet->size >= sizeof(struct arp_eth_header) - && arp->ar_op == ARP_OP_REQUEST); + && flow->nw_proto == ARP_OP_REPLY + && eth_addr_is_broadcast(flow->dl_dst)); } /* If the composed actions may be applied to any packet in the given 'flow', @@ -1915,7 +1913,7 @@ process_flow(struct bridge *br, const flow_t *flow, * 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 && - (!packet || !is_bcast_arp_reply(flow, packet))) { + !is_bcast_arp_reply(flow)) { goto done; } } @@ -1964,15 +1962,7 @@ process_flow(struct bridge *br, const flow_t *flow, done: compose_actions(br, flow, vlan, in_port, out_port, tags, actions); - /* - * We send out only a single packet, instead of setting up a flow, if the - * packet is an ARP directed to broadcast that arrived on a bonded - * interface. In such a situation ARP requests and replies must be handled - * differently, but OpenFlow unfortunately can't distinguish them. - */ - return (in_port->n_ifaces < 2 - || flow->dl_type != htons(ETH_TYPE_ARP) - || !eth_addr_is_broadcast(flow->dl_dst)); + return true; } /* Careful: 'opp' is in host byte order and opp->port_no is an OFP port