+/* MAC learning table
+ * ==================
+ *
+ * A MAC learning table is a dictionary data structure that is specialized to
+ * map from an (Ethernet address, VLAN ID) pair to a user-provided pointer. In
+ * an Ethernet switch implementation, it used to keep track of the port on
+ * which a packet from a given Ethernet address was last seen. This knowledge
+ * is useful when the switch receives a packet to such an Ethernet address, so
+ * that the switch can send the packet directly to the correct port instead of
+ * having to flood it to every port.
+ *
+ * A few complications make the implementation into more than a simple wrapper
+ * around a hash table. First, and most simply, MAC learning can be disabled
+ * on a per-VLAN basis. (This is most useful for RSPAN; see
+ * ovs-vswitchd.conf.db(5) documentation of the "output_vlan" column in the
+ * Mirror table for more information.). The data structure maintains a bitmap
+ * to track such VLANs.
+ *
+ * Second, the implementation has the ability to "lock" a MAC table entry
+ * updated by a gratuitous ARP. This is a simple feature but the rationale for
+ * it is complicated. Please refer to the description of SLB bonding in
+ * vswitchd/INTERNALS for an explanation.
+ *
+ * Third, the implementation expires entries that are idle for longer than a
+ * configurable amount of time. This is implemented by keeping all of the
+ * current table entries on a list ordered from least recently used (LRU) to
+ * most recently used (MRU). Each time a MAC entry is used, it is moved to the
+ * MRU end of the list. Periodically mac_learning_run() sweeps through the
+ * list starting from the LRU end, deleting each entry that has been idle too
+ * long.
+ *
+ * Finally, the number of MAC learning table entries has a configurable maximum
+ * size to prevent memory exhaustion. When a new entry must be inserted but
+ * the table is already full, the implementation uses an eviction strategy
+ * based on fairness: it chooses the port that currently has greatest number of
+ * learned MACs (choosing arbitrarily in case of a tie), and among that port's
+ * entries it evicts the least recently used. (This is a security feature
+ * because it prevents an attacker from forcing other ports' MACs out of the
+ * MAC learning table with a "MAC flooding attack" that causes the other ports'
+ * traffic to be flooded so that the attacker can easily sniff it.) The
+ * implementation of this feature is like a specialized form of the
+ * general-purpose "eviction groups" that OVS implements in OpenFlow (see the
+ * documentation of the "groups" column in the Flow_Table table in
+ * ovs-vswitchd.conf.db(5) for details).
+ *
+ *
+ * Thread-safety
+ * =============
+ *
+ * Many operations require the caller to take the MAC learning table's rwlock
+ * for writing (please refer to the Clang thread safety annotations). The
+ * important exception to this is mac_learning_lookup(), which only needs a
+ * read lock. This is useful for the common case where a MAC learning entry
+ * being looked up already exists and does not need an update. However,
+ * there's no deadlock-free way to upgrade a read lock to a write lock, so in
+ * the case where the lookup result means that an update is required, the
+ * caller must drop the read lock, take the write lock, and then repeat the
+ * lookup (in case some other thread has already made a change).
+ */
+
+struct mac_learning;
+
+/* Default maximum size of a MAC learning table, in entries. */
+#define MAC_DEFAULT_MAX 2048