aboutsummaryrefslogtreecommitdiff
path: root/lib/bond.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2011-10-22 17:22:11 -0700
committerJesse Gross <jesse@nicira.com>2011-11-02 16:36:49 -0700
commitea131871e4c8793ff90f60cfb5f45947d6a2c10b (patch)
tree67eb333e30de6f6c01004d4bb2d673ec84aff7bf /lib/bond.c
parenta7d7f493ba47b1986857b57103f75dccf65d548a (diff)
ofproto-dpif: Use send_packet() instead of netdev_send().
netdev_send() directly sends a packet using Linux mechanisms, skipping our kernel module. Several upper layer abstractions are built on top of the kernel module, so this means that we loose stats, sFlow, etc. on these packets. This changes bonding, LACP, and STP to use send_packet() as CFM does, which uses the standard kernel mechanisms and provides a single place that needs to be updated.
Diffstat (limited to 'lib/bond.c')
-rw-r--r--lib/bond.c35
1 files changed, 16 insertions, 19 deletions
diff --git a/lib/bond.c b/lib/bond.c
index 73ee814c..2b99b9ac 100644
--- a/lib/bond.c
+++ b/lib/bond.c
@@ -484,14 +484,15 @@ bond_wait(struct bond *bond)
static bool
may_send_learning_packets(const struct bond *bond)
{
- return !bond->lacp_negotiated && bond->balance != BM_AB;
+ return !bond->lacp_negotiated && bond->balance != BM_AB &&
+ bond->active_slave;
}
/* Returns true if 'bond' needs the client to send out packets to assist with
* MAC learning on 'bond'. If this function returns true, then the client
* should iterate through its MAC learning table for the bridge on which 'bond'
* is located. For each MAC that has been learned on a port other than 'bond',
- * it should call bond_send_learning_packet().
+ * it should call bond_compose_learning_packet().
*
* This function will only return true if 'bond' is in SLB mode and LACP is not
* negotiated. Otherwise sending learning packets isn't necessary.
@@ -507,37 +508,33 @@ bond_should_send_learning_packets(struct bond *bond)
/* Sends a gratuitous learning packet on 'bond' from 'eth_src' on 'vlan'.
*
- * See bond_should_send_learning_packets() for description of usage. */
-int
-bond_send_learning_packet(struct bond *bond,
- const uint8_t eth_src[ETH_ADDR_LEN],
- uint16_t vlan)
+ * See bond_should_send_learning_packets() for description of usage. The
+ * caller should send the composed packet on the port associated with
+ * port_aux and takes ownership of the returned ofpbuf. */
+struct ofpbuf *
+bond_compose_learning_packet(struct bond *bond,
+ const uint8_t eth_src[ETH_ADDR_LEN],
+ uint16_t vlan, void **port_aux)
{
struct bond_slave *slave;
- struct ofpbuf packet;
+ struct ofpbuf *packet;
struct flow flow;
- int error;
assert(may_send_learning_packets(bond));
- if (!bond->active_slave) {
- /* Nowhere to send the learning packet. */
- return 0;
- }
memset(&flow, 0, sizeof flow);
memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN);
slave = choose_output_slave(bond, &flow, vlan);
- ofpbuf_init(&packet, 0);
- compose_benign_packet(&packet, "Open vSwitch Bond Failover", 0xf177,
+ packet = ofpbuf_new(0);
+ compose_benign_packet(packet, "Open vSwitch Bond Failover", 0xf177,
eth_src);
if (vlan) {
- eth_push_vlan(&packet, htons(vlan));
+ eth_push_vlan(packet, htons(vlan));
}
- error = netdev_send(slave->netdev, &packet);
- ofpbuf_uninit(&packet);
- return error;
+ *port_aux = slave->aux;
+ return packet;
}
/* Checks whether a packet that arrived on 'slave_' within 'bond', with an