[ovs-dev] [bridge 10/15] mac-learning: Refactor to increase generality.
Ben Pfaff
blp at nicira.com
Tue Mar 22 16:55:22 UTC 2011
On Mon, Mar 21, 2011 at 03:42:15PM -0700, Ethan Jackson wrote:
> Thanks for writing this up. Looks like it will be nifty in the future.
>
> > + * If the returned MAC entry is new (as may be determined by calling
> > + * mac_entry_is_new()), then the caller must pass the new entry to
> > + * mac_learning_touch() and mac_learning_change(), in that order. ?The caller
> > + * must also initialize the new entry's 'port' member. ?Otherwise calling those
> > + * functions is at the caller's discretion. */
> > +struct mac_entry *
> > +mac_learning_insert(struct mac_learning *ml,
> > + ? ? ? ? ? ? ? ? ? ?const uint8_t src_mac[ETH_ADDR_LEN], uint16_t vlan)
> > ?{
>
> It may make sense to automatically call mac_learning_touch and
> mac_learning_change for the caller if the returned mac_entry is new.
> This may reduce the risk of errors. I think there is a slight risk of
> either of these functions being called twice on new mac entries, but
> that doesn't seem like a huge problem to me.
I agree that that would be a better interface.
Looking more carefully, I don't see a problem with always
unconditionally doing mac_learning_touch(). Before, I was concerned
about behaving exactly the same way as the previous version, which did
not do the mac_learning_touch() equivalent for locked ARP entries, but
I can't see how it would make a real different in practice. So, I've
integrated that into mac_learning_insert().
That's the one that's really important. If mac_learning_change()
doesn't get called, it's really not a big deal for the mac_learning
module itself.
> If we can't do this, it may make sense alternatively to have
> mac_learning_lookup assert each returned mac_entries tag and expires
> members to ensure that they were properly initialized.
It's a good idea anyway, so I added that too.
> > +mac_learning_change(struct mac_learning *ml, struct mac_entry *e)
> > +{
> > + ? ?tag_type old_tag = e->tag;
> > +
> > + ? ?COVERAGE_INC(mac_learning_learned);
>
> It may make sense to rename this mac_learning_changed.
I was on the fence about that already, so I made the change.
>
> > + ? ?mac = mac_learning_insert(br->ml, flow->dl_src, vlan);
> > + ? ?if (is_gratuitous_arp(flow)) {
> > + ? ? ? ?/* We don't want to learn from gratuitous ARP packets that are
> > + ? ? ? ? * reflected back over bond slaves so we lock the learning table. */
> > + ? ? ? ?if (in_port->n_ifaces == 1) {
> > + ? ? ? ? ? ?mac_entry_set_grat_arp_lock(mac);
> > + ? ? ? ?} else if (mac_entry_is_grat_arp_locked(mac)) {
> > + ? ? ? ? ? ?return;
>
> If mac is new here it will never be touched or changed. I'm not sure
> if that's a problem as it may get touched next time
> update_learning_table is called, but it seems like we may end up with
> entries with bogus lru status.
A new MAC won't be locked so the return here will never be reached.
More information about the dev
mailing list