diff options
author | Ethan Jackson <ethan@nicira.com> | 2013-08-01 18:04:07 -0700 |
---|---|---|
committer | Ethan Jackson <ethan@nicira.com> | 2013-08-02 14:41:23 -0700 |
commit | 30618594b6c68497b56443de81a7f19e57e3e898 (patch) | |
tree | c1eea28dad5a81c4c123b872689d739054cf9863 /lib | |
parent | 15aee11695811c70efd8b7d3dab11625b4dd59f2 (diff) | |
download | openvswitch-30618594b6c68497b56443de81a7f19e57e3e898.tar.gz |
mac-learning: Stop using tags.
This patch transitions mac learning away from using tags as required
by future patches.
Signed-off-by: Ethan Jackson <ethan@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/learning-switch.c | 9 | ||||
-rw-r--r-- | lib/mac-learning.c | 60 | ||||
-rw-r--r-- | lib/mac-learning.h | 22 |
3 files changed, 28 insertions, 63 deletions
diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 6c8156ace..9c1aff7a4 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -252,7 +252,7 @@ lswitch_run(struct lswitch *sw) if (sw->ml) { ovs_rwlock_wrlock(&sw->ml->rwlock); - mac_learning_run(sw->ml, NULL); + mac_learning_run(sw->ml); ovs_rwlock_unlock(&sw->ml->rwlock); } @@ -479,14 +479,13 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) ovs_rwlock_wrlock(&sw->ml->rwlock); if (mac_learning_may_learn(sw->ml, flow->dl_src, 0)) { struct mac_entry *mac = mac_learning_insert(sw->ml, flow->dl_src, 0); - if (mac_entry_is_new(mac) - || mac->port.ofp_port != flow->in_port.ofp_port) { + if (mac->port.ofp_port != flow->in_port.ofp_port) { VLOG_DBG_RL(&rl, "%016llx: learned that "ETH_ADDR_FMT" is on " "port %"PRIu16, sw->datapath_id, ETH_ADDR_ARGS(flow->dl_src), flow->in_port.ofp_port); mac->port.ofp_port = flow->in_port.ofp_port; - mac_learning_changed(sw->ml, mac); + mac_learning_changed(sw->ml); } } ovs_rwlock_unlock(&sw->ml->rwlock); @@ -501,7 +500,7 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) struct mac_entry *mac; ovs_rwlock_rdlock(&sw->ml->rwlock); - mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0, NULL); + mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0); if (mac) { out_port = mac->port.ofp_port; if (out_port == flow->in_port.ofp_port) { diff --git a/lib/mac-learning.c b/lib/mac-learning.c index 06e61d1d3..80dac6982 100644 --- a/lib/mac-learning.c +++ b/lib/mac-learning.c @@ -25,7 +25,6 @@ #include "hash.h" #include "list.h" #include "poll-loop.h" -#include "tag.h" #include "timeval.h" #include "unaligned.h" #include "util.h" @@ -60,16 +59,6 @@ mac_entry_from_lru_node(struct list *list) return CONTAINER_OF(list, struct mac_entry, lru_node); } -/* Returns a tag that represents that 'mac' is on an unknown port in 'vlan'. - * (When we learn where 'mac' is in 'vlan', this allows flows that were - * flooded to be revalidated.) */ -static tag_type -make_unknown_mac_tag(const struct mac_learning *ml, - const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan) -{ - return tag_create_deterministic(mac_table_hash(ml, mac, vlan)); -} - static struct mac_entry * mac_entry_lookup(const struct mac_learning *ml, const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan) @@ -124,7 +113,7 @@ mac_learning_create(unsigned int idle_time) ml->flood_vlans = NULL; ml->idle_time = normalize_idle_time(idle_time); ml->max_entries = MAC_DEFAULT_MAX; - tag_set_init(&ml->tags); + ml->need_revalidate = false; atomic_init(&ml->ref_cnt, 1); ovs_rwlock_init(&ml->rwlock); return ml; @@ -257,8 +246,8 @@ mac_learning_insert(struct mac_learning *ml, hmap_insert(&ml->table, &e->hmap_node, hash); memcpy(e->mac, src_mac, ETH_ADDR_LEN); e->vlan = vlan; - e->tag = 0; e->grat_arp_lock = TIME_MIN; + e->port.p = NULL; } else { list_remove(&e->lru_node); } @@ -279,14 +268,10 @@ mac_learning_insert(struct mac_learning *ml, * from mac_learning_insert(), if the entry is either new or if its learned * port has changed. */ void -mac_learning_changed(struct mac_learning *ml, struct mac_entry *e) +mac_learning_changed(struct mac_learning *ml) { - tag_type tag = e->tag ? e->tag : make_unknown_mac_tag(ml, e->mac, e->vlan); - COVERAGE_INC(mac_learning_learned); - - e->tag = tag_create_random(); - tag_set_add(&ml->tags, tag); + ml->need_revalidate = true; } /* Looks up MAC 'dst' for VLAN 'vlan' in 'ml' and returns the associated MAC @@ -295,8 +280,7 @@ mac_learning_changed(struct mac_learning *ml, struct mac_entry *e) * '*tag'. */ struct mac_entry * mac_learning_lookup(const struct mac_learning *ml, - const uint8_t dst[ETH_ADDR_LEN], uint16_t vlan, - tag_type *tag) + const uint8_t dst[ETH_ADDR_LEN], uint16_t vlan) { if (eth_addr_is_multicast(dst)) { /* No tag because the treatment of multicast destinations never @@ -309,11 +293,7 @@ mac_learning_lookup(const struct mac_learning *ml, } else { struct mac_entry *e = mac_entry_lookup(ml, dst, vlan); - ovs_assert(e == NULL || e->tag != 0); - if (tag) { - /* Tag either the learned port or the lack thereof. */ - *tag |= e ? e->tag : make_unknown_mac_tag(ml, dst, vlan); - } + ovs_assert(e == NULL || e->port.p != NULL) return e; } } @@ -332,44 +312,42 @@ mac_learning_expire(struct mac_learning *ml, struct mac_entry *e) * is responsible for revalidating any flows that depend on 'ml', if * necessary. */ void -mac_learning_flush(struct mac_learning *ml, struct tag_set *tags) +mac_learning_flush(struct mac_learning *ml) { struct mac_entry *e; while (get_lru(ml, &e)){ - if (tags) { - tag_set_add(tags, e->tag); - } + ml->need_revalidate = true; mac_learning_expire(ml, e); } hmap_shrink(&ml->table); } -void -mac_learning_run(struct mac_learning *ml, struct tag_set *set) +/* Does periodic work required by 'ml'. Returns true if something changed that + * may require flow revalidation. */ +bool +mac_learning_run(struct mac_learning *ml) { + bool need_revalidate; struct mac_entry *e; - if (set) { - tag_set_union(set, &ml->tags); - } - tag_set_init(&ml->tags); - while (get_lru(ml, &e) && (hmap_count(&ml->table) > ml->max_entries || time_now() >= e->expires)) { COVERAGE_INC(mac_learning_expired); - if (set) { - tag_set_add(set, e->tag); - } + ml->need_revalidate = true; mac_learning_expire(ml, e); } + + need_revalidate = ml->need_revalidate; + ml->need_revalidate = false; + return need_revalidate; } void mac_learning_wait(struct mac_learning *ml) { if (hmap_count(&ml->table) > ml->max_entries - || !tag_set_is_empty(&ml->tags)) { + || ml->need_revalidate) { poll_immediate_wake(); } else if (!list_is_empty(&ml->lrus)) { struct mac_entry *e = mac_entry_from_lru_node(ml->lrus.next); diff --git a/lib/mac-learning.h b/lib/mac-learning.h index ea5ea8a58..ba7f73421 100644 --- a/lib/mac-learning.h +++ b/lib/mac-learning.h @@ -23,7 +23,6 @@ #include "ovs-atomic.h" #include "ovs-thread.h" #include "packets.h" -#include "tag.h" #include "timeval.h" struct mac_learning; @@ -46,7 +45,6 @@ struct mac_entry { time_t grat_arp_lock; /* Gratuitous ARP lock expiration time. */ uint8_t mac[ETH_ADDR_LEN]; /* Known MAC address. */ uint16_t vlan; /* VLAN tag. */ - tag_type tag; /* Tag for this learning entry. */ /* The following are marked guarded to prevent users from iterating over or * accessing a mac_entry without hodling the parent mac_learning rwlock. */ @@ -59,13 +57,6 @@ struct mac_entry { } port OVS_GUARDED; }; -/* Returns true if mac_learning_insert() just created 'mac' and the caller has - * not yet properly initialized it. */ -static inline bool mac_entry_is_new(const struct mac_entry *mac) -{ - return !mac->tag; -} - /* Sets a gratuitous ARP lock on 'mac' that will expire in * MAC_GRAT_ARP_LOCK_TIME seconds. */ static inline void mac_entry_set_grat_arp_lock(struct mac_entry *mac) @@ -89,9 +80,9 @@ struct mac_learning { unsigned long *flood_vlans; /* Bitmap of learning disabled VLANs. */ unsigned int idle_time; /* Max age before deleting an entry. */ size_t max_entries; /* Max number of learned MACs. */ - struct tag_set tags; /* Tags which have changed. */ atomic_int ref_cnt; struct ovs_rwlock rwlock; + bool need_revalidate; }; int mac_entry_age(const struct mac_learning *ml, const struct mac_entry *e) @@ -102,8 +93,7 @@ struct mac_learning *mac_learning_create(unsigned int idle_time); struct mac_learning *mac_learning_ref(const struct mac_learning *); void mac_learning_unref(struct mac_learning *); -void mac_learning_run(struct mac_learning *ml, struct tag_set *) - OVS_REQ_WRLOCK(ml->rwlock); +bool mac_learning_run(struct mac_learning *ml) OVS_REQ_WRLOCK(ml->rwlock); void mac_learning_wait(struct mac_learning *ml) OVS_REQ_RDLOCK(ml->rwlock); @@ -126,19 +116,17 @@ struct mac_entry *mac_learning_insert(struct mac_learning *ml, const uint8_t src[ETH_ADDR_LEN], uint16_t vlan) OVS_REQ_WRLOCK(ml->rwlock); -void mac_learning_changed(struct mac_learning *ml, struct mac_entry *e) - OVS_REQ_WRLOCK(ml->rwlock); +void mac_learning_changed(struct mac_learning *ml) OVS_REQ_WRLOCK(ml->rwlock); /* Lookup. */ struct mac_entry *mac_learning_lookup(const struct mac_learning *ml, const uint8_t dst[ETH_ADDR_LEN], - uint16_t vlan, tag_type *) + uint16_t vlan) OVS_REQ_RDLOCK(ml->rwlock); /* Flushing. */ void mac_learning_expire(struct mac_learning *ml, struct mac_entry *e) OVS_REQ_WRLOCK(ml->rwlock); -void mac_learning_flush(struct mac_learning *ml, struct tag_set *) - OVS_REQ_WRLOCK(ml->rwlock); +void mac_learning_flush(struct mac_learning *ml) OVS_REQ_WRLOCK(ml->rwlock); #endif /* mac-learning.h */ |