Commit 1a620698c29b5e18150ec04ace0609fb07d08d3e

Authored by Stephen Hemminger
Committed by David S. Miller
1 parent 9ea8cfd6aa

[BRIDGE]: flush forwarding table when device carrier off

Flush the forwarding table when carrier is lost. This helps for
availability because we don't want to forward to a downed device and
new packets may come in on other links.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 11 additions and 4 deletions Side-by-side Diff

... ... @@ -128,7 +128,10 @@
128 128 mod_timer(&br->gc_timer, jiffies + HZ/10);
129 129 }
130 130  
131   -void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
  131 +
  132 +void br_fdb_delete_by_port(struct net_bridge *br,
  133 + const struct net_bridge_port *p,
  134 + int do_all)
132 135 {
133 136 int i;
134 137  
... ... @@ -142,6 +145,8 @@
142 145 if (f->dst != p)
143 146 continue;
144 147  
  148 + if (f->is_static && !do_all)
  149 + continue;
145 150 /*
146 151 * if multiple ports all have the same device address
147 152 * then when one port is deleted, assign
... ... @@ -163,7 +163,7 @@
163 163 br_stp_disable_port(p);
164 164 spin_unlock_bh(&br->lock);
165 165  
166   - br_fdb_delete_by_port(br, p);
  166 + br_fdb_delete_by_port(br, p, 1);
167 167  
168 168 list_del_rcu(&p->list);
169 169  
... ... @@ -448,7 +448,7 @@
448 448  
449 449 return 0;
450 450 err2:
451   - br_fdb_delete_by_port(br, p);
  451 + br_fdb_delete_by_port(br, p, 1);
452 452 err1:
453 453 kobject_del(&p->kobj);
454 454 err0:
net/bridge/br_private.h
... ... @@ -143,7 +143,7 @@
143 143 const unsigned char *newaddr);
144 144 extern void br_fdb_cleanup(unsigned long arg);
145 145 extern void br_fdb_delete_by_port(struct net_bridge *br,
146   - struct net_bridge_port *p);
  146 + const struct net_bridge_port *p, int do_all);
147 147 extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
148 148 const unsigned char *addr);
149 149 extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,
net/bridge/br_stp_if.c
... ... @@ -113,6 +113,8 @@
113 113 del_timer(&p->forward_delay_timer);
114 114 del_timer(&p->hold_timer);
115 115  
  116 + br_fdb_delete_by_port(br, p, 0);
  117 +
116 118 br_configuration_update(br);
117 119  
118 120 br_port_state_selection(br);