X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ofproto%2Fbond.c;h=c2749e52db94f777fa7f14d6d3e2dc5e8d16171f;hb=6422372c103d280450eb400ed7fe955b74deeb2a;hp=2e3ad2957f615fe6b850358206005fd0794e0abf;hpb=daaeeec0bd4348b1f6ac5ca5a302e57bd11cca01;p=cascardo%2Fovs.git diff --git a/ofproto/bond.c b/ofproto/bond.c index 2e3ad2957..c2749e52d 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,7 +84,7 @@ struct bond_slave { void *aux; /* Client-provided handle for this slave. */ struct netdev *netdev; /* Network device, owned by the client. */ - unsigned int change_seq; /* Tracks changes in 'netdev'. */ + uint64_t change_seq; /* Tracks changes in 'netdev'. */ ofp_port_t ofp_port; /* OpenFlow port number. */ char *name; /* Name (a copy of netdev_get_name(netdev)). */ @@ -140,7 +140,7 @@ struct bond { /* Interface name may not be persistent across an OS reboot, use * MAC address for identifing the active slave */ - uint8_t active_slave_mac[ETH_ADDR_LEN]; + struct eth_addr active_slave_mac; /* The MAC address of the active interface. */ /* Legacy compatibility. */ bool lacp_fallback_ab; /* Fallback to active-backup on LACP failure. */ @@ -172,7 +172,7 @@ static void bond_link_status_update(struct bond_slave *) OVS_REQ_WRLOCK(rwlock); static void bond_choose_active_slave(struct bond *) OVS_REQ_WRLOCK(rwlock); -static unsigned int bond_hash_src(const uint8_t mac[ETH_ADDR_LEN], +static unsigned int bond_hash_src(const struct eth_addr mac, uint16_t vlan, uint32_t basis); static unsigned int bond_hash_tcp(const struct flow *, uint16_t vlan, uint32_t basis); @@ -458,9 +458,7 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s) bond_entry_reset(bond); } - memcpy(bond->active_slave_mac, s->active_slave_mac, - sizeof s->active_slave_mac); - + bond->active_slave_mac = s->active_slave_mac; bond->active_slave_changed = false; ovs_rwlock_unlock(&rwlock); @@ -468,19 +466,19 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s) } static struct bond_slave * -bond_find_slave_by_mac(const struct bond *bond, const uint8_t mac[ETH_ADDR_LEN]) +bond_find_slave_by_mac(const struct bond *bond, const struct eth_addr mac) { struct bond_slave *slave; /* Find the last active slave */ HMAP_FOR_EACH(slave, hmap_node, &bond->slaves) { - uint8_t slave_mac[ETH_ADDR_LEN]; + struct eth_addr slave_mac; - if (netdev_get_etheraddr(slave->netdev, slave_mac)) { + if (netdev_get_etheraddr(slave->netdev, &slave_mac)) { continue; } - if (!memcmp(slave_mac, mac, sizeof(slave_mac))) { + if (eth_addr_equals(slave_mac, mac)) { return slave; } } @@ -491,10 +489,10 @@ bond_find_slave_by_mac(const struct bond *bond, const uint8_t mac[ETH_ADDR_LEN]) static void bond_active_slave_changed(struct bond *bond) { - uint8_t mac[ETH_ADDR_LEN]; + struct eth_addr mac; - netdev_get_etheraddr(bond->active_slave->netdev, mac); - memcpy(bond->active_slave_mac, mac, sizeof bond->active_slave_mac); + netdev_get_etheraddr(bond->active_slave->netdev, &mac); + bond->active_slave_mac = mac; bond->active_slave_changed = true; seq_change(connectivity_seq_get()); } @@ -721,8 +719,7 @@ bond_should_send_learning_packets(struct bond *bond) * caller should send the composed packet on the port associated with * port_aux and takes ownership of the returned ofpbuf. */ struct dp_packet * -bond_compose_learning_packet(struct bond *bond, - const uint8_t eth_src[ETH_ADDR_LEN], +bond_compose_learning_packet(struct bond *bond, const struct eth_addr eth_src, uint16_t vlan, void **port_aux) { struct bond_slave *slave; @@ -732,7 +729,7 @@ bond_compose_learning_packet(struct bond *bond, ovs_rwlock_rdlock(&rwlock); ovs_assert(may_send_learning_packets(bond)); memset(&flow, 0, sizeof flow); - memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN); + flow.dl_src = eth_src; slave = choose_output_slave(bond, &flow, NULL, vlan); packet = dp_packet_new(0); @@ -763,7 +760,7 @@ bond_compose_learning_packet(struct bond *bond, */ enum bond_verdict bond_check_admissibility(struct bond *bond, const void *slave_, - const uint8_t eth_dst[ETH_ADDR_LEN]) + const struct eth_addr eth_dst) { enum bond_verdict verdict = BV_DROP; struct bond_slave *slave; @@ -1068,23 +1065,24 @@ choose_entry_to_migrate(const struct bond_slave *from, uint64_t to_tx_bytes) } LIST_FOR_EACH (e, list_node, &from->entries) { - double old_ratio, new_ratio; - uint64_t delta; - - if (to_tx_bytes == 0) { - /* Nothing on the new slave, move it. */ - return e; - } - - delta = e->tx_bytes; - old_ratio = (double)from->tx_bytes / to_tx_bytes; - new_ratio = (double)(from->tx_bytes - delta) / (to_tx_bytes + delta); - if (old_ratio - new_ratio > 0.1 - && fabs(new_ratio - 1.0) < fabs(old_ratio - 1.0)) { - /* We're aiming for an ideal ratio of 1, meaning both the 'from' - and 'to' slave have the same load. Therefore, we only move an - entry if it decreases the load on 'from', and brings us closer - to equal traffic load. */ + uint64_t delta = e->tx_bytes; /* The amount to rebalance. */ + uint64_t ideal_tx_bytes = (from->tx_bytes + to_tx_bytes)/2; + /* Note, the ideal traffic is the mid point + * between 'from' and 'to'. This value does + * not change by rebalancing. */ + uint64_t new_low; /* The lower bandwidth between 'to' and 'from' + after rebalancing. */ + + new_low = MIN(from->tx_bytes - delta, to_tx_bytes + delta); + + if ((new_low > to_tx_bytes) && + (new_low - to_tx_bytes >= (ideal_tx_bytes - to_tx_bytes) / 10)) { + /* Only rebalance if the new 'low' is closer to to the mid point, + * and the improvement exceeds 10% of current traffic + * deviation from the ideal split. + * + * The improvement on the 'high' side is always the same as the + * 'low' side. Thus consider 'low' side is sufficient. */ return e; } } @@ -1137,7 +1135,7 @@ bond_rebalance(struct bond *bond) } bond->next_rebalance = time_msec() + bond->rebalance_interval; - use_recirc = ofproto_dpif_get_enable_recirc(bond->ofproto) && + use_recirc = ofproto_dpif_get_support(bond->ofproto)->odp.recirc && bond_may_recirc(bond, NULL, NULL); if (use_recirc) { @@ -1562,7 +1560,7 @@ bond_unixctl_hash(struct unixctl_conn *conn, int argc, const char *argv[], const char *mac_s = argv[1]; const char *vlan_s = argc > 2 ? argv[2] : NULL; const char *basis_s = argc > 3 ? argv[3] : NULL; - uint8_t mac[ETH_ADDR_LEN]; + struct eth_addr mac; uint8_t hash; char *hash_cstr; unsigned int vlan; @@ -1705,7 +1703,7 @@ bond_link_status_update(struct bond_slave *slave) } static unsigned int -bond_hash_src(const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan, uint32_t basis) +bond_hash_src(const struct eth_addr mac, uint16_t vlan, uint32_t basis) { return hash_mac(mac, vlan, basis); } @@ -1871,7 +1869,8 @@ bond_choose_active_slave(struct bond *bond) * If return true, 'mac' will store the bond's current active slave's * MAC address. */ bool -bond_get_changed_active_slave(const char *name, uint8_t* mac, bool force) +bond_get_changed_active_slave(const char *name, struct eth_addr *mac, + bool force) { struct bond *bond; @@ -1879,7 +1878,7 @@ bond_get_changed_active_slave(const char *name, uint8_t* mac, bool force) bond = bond_find(name); if (bond) { if (bond->active_slave_changed || force) { - memcpy(mac, bond->active_slave_mac, ETH_ADDR_LEN); + *mac = bond->active_slave_mac; bond->active_slave_changed = false; ovs_rwlock_unlock(&rwlock); return true;