Skip to content

Commit 9cf6374

Browse files
Stephen HemmingerDavid S. Miller
authored andcommitted
bridge: add sysfs hook to flush forwarding table
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]>
1 parent 3f89092 commit 9cf6374

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

net/bridge/br_fdb.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,26 @@ void br_fdb_cleanup(unsigned long _data)
135135
mod_timer(&br->gc_timer, jiffies + HZ/10);
136136
}
137137

138+
/* Completely flush all dynamic entries in forwarding database.*/
139+
void br_fdb_flush(struct net_bridge *br)
140+
{
141+
int i;
138142

143+
spin_lock_bh(&br->hash_lock);
144+
for (i = 0; i < BR_HASH_SIZE; i++) {
145+
struct net_bridge_fdb_entry *f;
146+
struct hlist_node *h, *n;
147+
hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
148+
if (!f->is_static)
149+
fdb_delete(f);
150+
}
151+
}
152+
spin_unlock_bh(&br->hash_lock);
153+
}
154+
155+
/* Flush all entries refering to a specific port.
156+
* if do_all is set also flush static entries
157+
*/
139158
void br_fdb_delete_by_port(struct net_bridge *br,
140159
const struct net_bridge_port *p,
141160
int do_all)

net/bridge/br_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
135135
/* br_fdb.c */
136136
extern void br_fdb_init(void);
137137
extern void br_fdb_fini(void);
138+
extern void br_fdb_flush(struct net_bridge *br);
138139
extern void br_fdb_changeaddr(struct net_bridge_port *p,
139140
const unsigned char *newaddr);
140141
extern void br_fdb_cleanup(unsigned long arg);

net/bridge/br_sysfs_br.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,19 @@ static ssize_t store_group_addr(struct device *d,
309309
static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
310310
show_group_addr, store_group_addr);
311311

312+
static ssize_t store_flush(struct device *d,
313+
struct device_attribute *attr,
314+
const char *buf, size_t len)
315+
{
316+
struct net_bridge *br = to_bridge(d);
317+
318+
if (!capable(CAP_NET_ADMIN))
319+
return -EPERM;
320+
321+
br_fdb_flush(br);
322+
return len;
323+
}
324+
static DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush);
312325

313326
static struct attribute *bridge_attrs[] = {
314327
&dev_attr_forward_delay.attr,
@@ -328,6 +341,7 @@ static struct attribute *bridge_attrs[] = {
328341
&dev_attr_topology_change_timer.attr,
329342
&dev_attr_gc_timer.attr,
330343
&dev_attr_group_addr.attr,
344+
&dev_attr_flush.attr,
331345
NULL
332346
};
333347

net/bridge/br_sysfs_if.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ static ssize_t show_hold_timer(struct net_bridge_port *p,
137137
}
138138
static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
139139

140+
static ssize_t store_flush(struct net_bridge_port *p, unsigned long v)
141+
{
142+
br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry
143+
return 0;
144+
}
145+
static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush);
146+
140147
static struct brport_attribute *brport_attrs[] = {
141148
&brport_attr_path_cost,
142149
&brport_attr_priority,
@@ -152,6 +159,7 @@ static struct brport_attribute *brport_attrs[] = {
152159
&brport_attr_message_age_timer,
153160
&brport_attr_forward_delay_timer,
154161
&brport_attr_hold_timer,
162+
&brport_attr_flush,
155163
NULL
156164
};
157165

0 commit comments

Comments
 (0)