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); |
