diff options
author | Amerigo Wang <amwang@redhat.com> | 2012-12-14 17:09:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-15 20:14:39 -0500 |
commit | ccb1c31a7a8744cd153a7d92b726a56b56ad61d3 (patch) | |
tree | 1c62ac2565c657155474b3e8335a13ebcc35560e /net/bridge | |
parent | 9dd9ff99532d7a7f8222fd1f0d410d91c0f15ac5 (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.c | 9 | ||||
-rw-r--r-- | net/bridge/br_multicast.c | 8 | ||||
-rw-r--r-- | net/bridge/br_private.h | 4 |
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 | ||
312 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | 315 | static 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: | |||
622 | struct net_bridge_port_group *br_multicast_new_port_group( | 622 | struct 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 | ||
88 | struct net_bridge_mdb_entry | 89 | struct net_bridge_mdb_entry |
@@ -443,7 +444,8 @@ extern void br_multicast_free_pg(struct rcu_head *head); | |||
443 | extern struct net_bridge_port_group *br_multicast_new_port_group( | 444 | extern 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); | ||
447 | extern void br_mdb_init(void); | 449 | extern void br_mdb_init(void); |
448 | extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, | 450 | extern 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); |