aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorAmerigo Wang <amwang@redhat.com>2012-12-14 17:09:51 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-15 20:14:39 -0500
commitccb1c31a7a8744cd153a7d92b726a56b56ad61d3 (patch)
tree1c62ac2565c657155474b3e8335a13ebcc35560e /net/bridge
parent9dd9ff99532d7a7f8222fd1f0d410d91c0f15ac5 (diff)
bridge: add flags to distinguish permanent mdb entires
This patch adds a flag to each mdb entry, so that we can distinguish permanent entries with temporary entries. Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Stephen Hemminger <shemminger@vyatta.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_mdb.c9
-rw-r--r--net/bridge/br_multicast.c8
-rw-r--r--net/bridge/br_private.h4
3 files changed, 14 insertions, 7 deletions
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 6f0a2eebcb27..9cf5d2b28c76 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -83,6 +83,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
83 if (port) { 83 if (port) {
84 struct br_mdb_entry e; 84 struct br_mdb_entry e;
85 e.ifindex = port->dev->ifindex; 85 e.ifindex = port->dev->ifindex;
86 e.state = p->state;
86 e.addr.u.ip4 = p->addr.u.ip4; 87 e.addr.u.ip4 = p->addr.u.ip4;
87#if IS_ENABLED(CONFIG_IPV6) 88#if IS_ENABLED(CONFIG_IPV6)
88 e.addr.u.ip6 = p->addr.u.ip6; 89 e.addr.u.ip6 = p->addr.u.ip6;
@@ -253,6 +254,8 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
253#endif 254#endif
254 } else 255 } else
255 return false; 256 return false;
257 if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY)
258 return false;
256 259
257 return true; 260 return true;
258} 261}
@@ -310,7 +313,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
310} 313}
311 314
312static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, 315static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
313 struct br_ip *group) 316 struct br_ip *group, unsigned char state)
314{ 317{
315 struct net_bridge_mdb_entry *mp; 318 struct net_bridge_mdb_entry *mp;
316 struct net_bridge_port_group *p; 319 struct net_bridge_port_group *p;
@@ -336,7 +339,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
336 break; 339 break;
337 } 340 }
338 341
339 p = br_multicast_new_port_group(port, group, *pp); 342 p = br_multicast_new_port_group(port, group, *pp, state);
340 if (unlikely(!p)) 343 if (unlikely(!p))
341 return -ENOMEM; 344 return -ENOMEM;
342 rcu_assign_pointer(*pp, p); 345 rcu_assign_pointer(*pp, p);
@@ -373,7 +376,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
373#endif 376#endif
374 377
375 spin_lock_bh(&br->multicast_lock); 378 spin_lock_bh(&br->multicast_lock);
376 ret = br_mdb_add_group(br, p, &ip); 379 ret = br_mdb_add_group(br, p, &ip, entry->state);
377 spin_unlock_bh(&br->multicast_lock); 380 spin_unlock_bh(&br->multicast_lock);
378 return ret; 381 return ret;
379} 382}
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2561af9d18a2..dce9defae3c6 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -279,7 +279,7 @@ static void br_multicast_port_group_expired(unsigned long data)
279 279
280 spin_lock(&br->multicast_lock); 280 spin_lock(&br->multicast_lock);
281 if (!netif_running(br->dev) || timer_pending(&pg->timer) || 281 if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
282 hlist_unhashed(&pg->mglist)) 282 hlist_unhashed(&pg->mglist) || pg->state & MDB_PERMANENT)
283 goto out; 283 goto out;
284 284
285 br_multicast_del_pg(br, pg); 285 br_multicast_del_pg(br, pg);
@@ -622,7 +622,8 @@ out:
622struct net_bridge_port_group *br_multicast_new_port_group( 622struct net_bridge_port_group *br_multicast_new_port_group(
623 struct net_bridge_port *port, 623 struct net_bridge_port *port,
624 struct br_ip *group, 624 struct br_ip *group,
625 struct net_bridge_port_group __rcu *next) 625 struct net_bridge_port_group __rcu *next,
626 unsigned char state)
626{ 627{
627 struct net_bridge_port_group *p; 628 struct net_bridge_port_group *p;
628 629
@@ -632,6 +633,7 @@ struct net_bridge_port_group *br_multicast_new_port_group(
632 633
633 p->addr = *group; 634 p->addr = *group;
634 p->port = port; 635 p->port = port;
636 p->state = state;
635 rcu_assign_pointer(p->next, next); 637 rcu_assign_pointer(p->next, next);
636 hlist_add_head(&p->mglist, &port->mglist); 638 hlist_add_head(&p->mglist, &port->mglist);
637 setup_timer(&p->timer, br_multicast_port_group_expired, 639 setup_timer(&p->timer, br_multicast_port_group_expired,
@@ -674,7 +676,7 @@ static int br_multicast_add_group(struct net_bridge *br,
674 break; 676 break;
675 } 677 }
676 678
677 p = br_multicast_new_port_group(port, group, *pp); 679 p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY);
678 if (unlikely(!p)) 680 if (unlikely(!p))
679 goto err; 681 goto err;
680 rcu_assign_pointer(*pp, p); 682 rcu_assign_pointer(*pp, p);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index f21a739a6186..49b85af44016 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -83,6 +83,7 @@ struct net_bridge_port_group {
83 struct rcu_head rcu; 83 struct rcu_head rcu;
84 struct timer_list timer; 84 struct timer_list timer;
85 struct br_ip addr; 85 struct br_ip addr;
86 unsigned char state;
86}; 87};
87 88
88struct net_bridge_mdb_entry 89struct net_bridge_mdb_entry
@@ -443,7 +444,8 @@ extern void br_multicast_free_pg(struct rcu_head *head);
443extern struct net_bridge_port_group *br_multicast_new_port_group( 444extern struct net_bridge_port_group *br_multicast_new_port_group(
444 struct net_bridge_port *port, 445 struct net_bridge_port *port,
445 struct br_ip *group, 446 struct br_ip *group,
446 struct net_bridge_port_group *next); 447 struct net_bridge_port_group *next,
448 unsigned char state);
447extern void br_mdb_init(void); 449extern void br_mdb_init(void);
448extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, 450extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
449 struct br_ip *group, int type); 451 struct br_ip *group, int type);