aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_fdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_fdb.c')
-rw-r--r--net/bridge/br_fdb.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 68def3b7fb49..c8e7861b88b0 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -558,19 +558,28 @@ skip:
558 558
559/* Create new static fdb entry */ 559/* Create new static fdb entry */
560static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, 560static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
561 __u16 state) 561 __u16 state, __u16 flags)
562{ 562{
563 struct net_bridge *br = source->br; 563 struct net_bridge *br = source->br;
564 struct hlist_head *head = &br->hash[br_mac_hash(addr)]; 564 struct hlist_head *head = &br->hash[br_mac_hash(addr)];
565 struct net_bridge_fdb_entry *fdb; 565 struct net_bridge_fdb_entry *fdb;
566 566
567 fdb = fdb_find(head, addr); 567 fdb = fdb_find(head, addr);
568 if (fdb) 568 if (fdb == NULL) {
569 return -EEXIST; 569 if (!(flags & NLM_F_CREATE))
570 return -ENOENT;
570 571
571 fdb = fdb_create(head, source, addr); 572 fdb = fdb_create(head, source, addr);
572 if (!fdb) 573 if (!fdb)
573 return -ENOMEM; 574 return -ENOMEM;
575 } else {
576 if (flags & NLM_F_EXCL)
577 return -EEXIST;
578
579 if (flags & NLM_F_REPLACE)
580 fdb->updated = fdb->used = jiffies;
581 fdb->is_local = fdb->is_static = 0;
582 }
574 583
575 if (state & NUD_PERMANENT) 584 if (state & NUD_PERMANENT)
576 fdb->is_local = fdb->is_static = 1; 585 fdb->is_local = fdb->is_static = 1;
@@ -626,7 +635,7 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
626 } 635 }
627 636
628 spin_lock_bh(&p->br->hash_lock); 637 spin_lock_bh(&p->br->hash_lock);
629 err = fdb_add_entry(p, addr, ndm->ndm_state); 638 err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags);
630 spin_unlock_bh(&p->br->hash_lock); 639 spin_unlock_bh(&p->br->hash_lock);
631 640
632 return err; 641 return err;