Skip to content

Commit

Permalink
bridge: add sysfs hook to flush forwarding table
Browse files Browse the repository at this point in the history
The RSTP daemon needs to be able to flush all dynamic forwarding
entries in the case of topology change.

This is a temporary interface. It will change to a netlink interface
before RSTP daemon is officially released.

Signed-off-by: Stephen Hemminger <[email protected]>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Apr 26, 2007
1 parent 3f89092 commit 9cf6374
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
19 changes: 19 additions & 0 deletions net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,26 @@ void br_fdb_cleanup(unsigned long _data)
mod_timer(&br->gc_timer, jiffies + HZ/10);
}

/* Completely flush all dynamic entries in forwarding database.*/
void br_fdb_flush(struct net_bridge *br)
{
int i;

spin_lock_bh(&br->hash_lock);
for (i = 0; i < BR_HASH_SIZE; i++) {
struct net_bridge_fdb_entry *f;
struct hlist_node *h, *n;
hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
if (!f->is_static)
fdb_delete(f);
}
}
spin_unlock_bh(&br->hash_lock);
}

/* Flush all entries refering to a specific port.
* if do_all is set also flush static entries
*/
void br_fdb_delete_by_port(struct net_bridge *br,
const struct net_bridge_port *p,
int do_all)
Expand Down
1 change: 1 addition & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
/* br_fdb.c */
extern void br_fdb_init(void);
extern void br_fdb_fini(void);
extern void br_fdb_flush(struct net_bridge *br);
extern void br_fdb_changeaddr(struct net_bridge_port *p,
const unsigned char *newaddr);
extern void br_fdb_cleanup(unsigned long arg);
Expand Down
14 changes: 14 additions & 0 deletions net/bridge/br_sysfs_br.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,19 @@ static ssize_t store_group_addr(struct device *d,
static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
show_group_addr, store_group_addr);

static ssize_t store_flush(struct device *d,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct net_bridge *br = to_bridge(d);

if (!capable(CAP_NET_ADMIN))
return -EPERM;

br_fdb_flush(br);
return len;
}
static DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush);

static struct attribute *bridge_attrs[] = {
&dev_attr_forward_delay.attr,
Expand All @@ -328,6 +341,7 @@ static struct attribute *bridge_attrs[] = {
&dev_attr_topology_change_timer.attr,
&dev_attr_gc_timer.attr,
&dev_attr_group_addr.attr,
&dev_attr_flush.attr,
NULL
};

Expand Down
8 changes: 8 additions & 0 deletions net/bridge/br_sysfs_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ static ssize_t show_hold_timer(struct net_bridge_port *p,
}
static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);

static ssize_t store_flush(struct net_bridge_port *p, unsigned long v)
{
br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry
return 0;
}
static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush);

static struct brport_attribute *brport_attrs[] = {
&brport_attr_path_cost,
&brport_attr_priority,
Expand All @@ -152,6 +159,7 @@ static struct brport_attribute *brport_attrs[] = {
&brport_attr_message_age_timer,
&brport_attr_forward_delay_timer,
&brport_attr_hold_timer,
&brport_attr_flush,
NULL
};

Expand Down

0 comments on commit 9cf6374

Please sign in to comment.