diff options
author | roopa <roopa@cumulusnetworks.com> | 2013-04-22 08:56:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-29 11:40:26 -0400 |
commit | b0a397fb352e65e3b6501dca9662617a18862ef1 (patch) | |
tree | 951ed994f24b426160e548d86c869becbda37f51 | |
parent | c39904a0ac22cf05f5f44226457f6da0fe65457e (diff) |
bridge: Add fdb dst check during fdb update
Current bridge fdb update code does not seem to update the port
during fdb update. This patch adds a check for fdb dst (port)
change during fdb update. Also rearranges the call to
fdb_notify to send only one notification for create and update.
Changelog:
v2 - Change notify flag to bool
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/bridge/br_fdb.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index c581f1200ef7..ebfa4443c69b 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -615,6 +615,7 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | |||
615 | struct net_bridge *br = source->br; | 615 | struct net_bridge *br = source->br; |
616 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; | 616 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; |
617 | struct net_bridge_fdb_entry *fdb; | 617 | struct net_bridge_fdb_entry *fdb; |
618 | bool modified = false; | ||
618 | 619 | ||
619 | fdb = fdb_find(head, addr, vid); | 620 | fdb = fdb_find(head, addr, vid); |
620 | if (fdb == NULL) { | 621 | if (fdb == NULL) { |
@@ -624,10 +625,16 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | |||
624 | fdb = fdb_create(head, source, addr, vid); | 625 | fdb = fdb_create(head, source, addr, vid); |
625 | if (!fdb) | 626 | if (!fdb) |
626 | return -ENOMEM; | 627 | return -ENOMEM; |
627 | fdb_notify(br, fdb, RTM_NEWNEIGH); | 628 | |
629 | modified = true; | ||
628 | } else { | 630 | } else { |
629 | if (flags & NLM_F_EXCL) | 631 | if (flags & NLM_F_EXCL) |
630 | return -EEXIST; | 632 | return -EEXIST; |
633 | |||
634 | if (fdb->dst != source) { | ||
635 | fdb->dst = source; | ||
636 | modified = true; | ||
637 | } | ||
631 | } | 638 | } |
632 | 639 | ||
633 | if (fdb_to_nud(fdb) != state) { | 640 | if (fdb_to_nud(fdb) != state) { |
@@ -639,7 +646,12 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | |||
639 | } else | 646 | } else |
640 | fdb->is_local = fdb->is_static = 0; | 647 | fdb->is_local = fdb->is_static = 0; |
641 | 648 | ||
642 | fdb->updated = fdb->used = jiffies; | 649 | modified = true; |
650 | } | ||
651 | |||
652 | fdb->used = jiffies; | ||
653 | if (modified) { | ||
654 | fdb->updated = jiffies; | ||
643 | fdb_notify(br, fdb, RTM_NEWNEIGH); | 655 | fdb_notify(br, fdb, RTM_NEWNEIGH); |
644 | } | 656 | } |
645 | 657 | ||