NICS-11.
Signed-off-by: Ben Pfaff <blp@nicira.com>
/*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
sw->max_idle = cfg->max_idle;
sw->datapath_id = 0;
sw->last_features_request = time_now() - 1;
- sw->ml = cfg->mode == LSW_LEARN ? mac_learning_create() : NULL;
+ sw->ml = (cfg->mode == LSW_LEARN
+ ? mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME)
+ : NULL);
sw->action_normal = cfg->mode == LSW_NORMAL;
flow_wildcards_init_exact(&sw->wc);
/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
COVERAGE_DEFINE(mac_learning_learned);
COVERAGE_DEFINE(mac_learning_expired);
-/* Returns the number of seconds since 'e' was last learned. */
+/* Returns the number of seconds since 'e' (within 'ml') was last learned. */
int
-mac_entry_age(const struct mac_entry *e)
+mac_entry_age(const struct mac_learning *ml, const struct mac_entry *e)
{
time_t remaining = e->expires - time_now();
- return MAC_ENTRY_IDLE_TIME - remaining;
+ return ml->idle_time - remaining;
}
static uint32_t
list_push_front(&ml->free, &e->lru_node);
}
-/* Creates and returns a new MAC learning table. */
+static unsigned int
+normalize_idle_time(unsigned int idle_time)
+{
+ return (idle_time < 15 ? 15
+ : idle_time > 3600 ? 3600
+ : idle_time);
+}
+
+/* Creates and returns a new MAC learning table with an initial MAC aging
+ * timeout of 'idle_time' seconds. */
struct mac_learning *
-mac_learning_create(void)
+mac_learning_create(unsigned int idle_time)
{
struct mac_learning *ml;
int i;
}
ml->secret = random_uint32();
ml->flood_vlans = NULL;
+ ml->idle_time = normalize_idle_time(idle_time);
return ml;
}
return ret;
}
+/* Changes the MAC aging timeout of 'ml' to 'idle_time' seconds. */
+void
+mac_learning_set_idle_time(struct mac_learning *ml, unsigned int idle_time)
+{
+ idle_time = normalize_idle_time(idle_time);
+ if (idle_time != ml->idle_time) {
+ struct mac_entry *e;
+ int delta;
+
+ delta = (int) idle_time - (int) ml->idle_time;
+ LIST_FOR_EACH (e, lru_node, &ml->lrus) {
+ e->expires += delta;
+ }
+ ml->idle_time = idle_time;
+ }
+}
+
static bool
is_learning_vlan(const struct mac_learning *ml, uint16_t vlan)
{
/* Make the entry most-recently-used. */
list_remove(&e->lru_node);
list_push_back(&ml->lrus, &e->lru_node);
- e->expires = time_now() + MAC_ENTRY_IDLE_TIME;
+ e->expires = time_now() + ml->idle_time;
if (lock_type == GRAT_ARP_LOCK_SET) {
e->grat_arp_lock = time_now() + MAC_GRAT_ARP_LOCK_TIME;
}
#include "packets.h"
#include "tag.h"
+struct mac_learning;
+
#define MAC_HASH_BITS 10
#define MAC_HASH_MASK (MAC_HASH_SIZE - 1)
#define MAC_HASH_SIZE (1u << MAC_HASH_BITS)
#define MAC_MAX 2048
/* Time, in seconds, before expiring a mac_entry due to inactivity. */
-#define MAC_ENTRY_IDLE_TIME 300
+#define MAC_ENTRY_DEFAULT_IDLE_TIME 300
/* Time, in seconds, to lock an entry updated by a gratuitous ARP to avoid
* relearning based on a reflection from a bond slave. */
tag_type tag; /* Tag for this learning entry. */
};
-int mac_entry_age(const struct mac_entry *);
+int mac_entry_age(const struct mac_learning *, const struct mac_entry *);
/* MAC learning table. */
struct mac_learning {
struct mac_entry entries[MAC_MAX]; /* All entries. */
uint32_t secret; /* Secret for randomizing hash table. */
unsigned long *flood_vlans; /* Bitmap of learning disabled VLANs. */
+ unsigned int idle_time; /* Max age before deleting an entry. */
};
-struct mac_learning *mac_learning_create(void);
+struct mac_learning *mac_learning_create(unsigned int idle_time);
void mac_learning_destroy(struct mac_learning *);
bool mac_learning_set_flood_vlans(struct mac_learning *,
unsigned long *bitmap);
+void mac_learning_set_idle_time(struct mac_learning *, unsigned int idle_time);
tag_type mac_learning_learn(struct mac_learning *,
const uint8_t src[ETH_ADDR_LEN], uint16_t vlan,
uint16_t src_port, enum grat_arp_lock_type
/*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
* Copyright (c) 2010 Jean Tourrilhes - HP-Labs.
*
* Licensed under the Apache License, Version 2.0 (the "License");
} else {
p->ofhooks = &default_ofhooks;
p->aux = p;
- p->ml = mac_learning_create();
+ p->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
}
/* Pick final datapath ID. */
}
ds_put_format(&ds, "%5d %4d "ETH_ADDR_FMT" %3d\n",
br->ports[e->port]->ifaces[0]->dp_ifidx,
- e->vlan, ETH_ADDR_ARGS(e->mac), mac_entry_age(e));
+ e->vlan, ETH_ADDR_ARGS(e->mac),
+ mac_entry_age(br->ml, e));
}
unixctl_command_reply(conn, 200, ds_cstr(&ds));
ds_destroy(&ds);
br->name = xstrdup(br_cfg->name);
br->cfg = br_cfg;
- br->ml = mac_learning_create();
+ br->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
eth_addr_nicira_random(br->default_ea);
hmap_init(&br->ifaces);
struct svec snoops, old_snoops;
struct shash_node *node;
enum ofproto_fail_mode fail_mode;
+ const char *idle_time_str;
+ int idle_time;
size_t i;
/* Collect old ports. */
}
ofproto_set_fail_mode(br->ofproto, fail_mode);
+ /* Set the MAC learning aging timeout. */
+ idle_time_str = bridge_get_other_config(br->cfg, "mac-aging-time");
+ idle_time = (idle_time_str && atoi(idle_time_str)
+ ? atoi(idle_time_str)
+ : MAC_ENTRY_DEFAULT_IDLE_TIME);
+ mac_learning_set_idle_time(br->ml, idle_time);
+
/* Delete all flows if we're switching from connected to standalone or vice
* versa. (XXX Should we delete all flows if we are switching from one
* controller to another?) */
does not have QoS configured, or if the port does not have a queue
with the specified ID, the default queue is used instead.
</dd>
+ <dt><code>mac-aging-time</code></dt>
+ <dd>
+ A positive integer specifying the maximum number of seconds to
+ retain a MAC learning entry for which no packets have been seen.
+ The default is currently 300 seconds (5 minutes).
+ </dd>
</dl>
</column>
</group>