浏览代码

bridge: allow updating existing fdb entries

Need to allow application to update existing fdb entries that already
exist. This makes bridge netlink neighbor API have same flags and
semantics as ip neighbor table.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
stephen hemminger 13 年之前
父节点
当前提交
64af1bac9b
共有 1 个文件被更改,包括 16 次插入7 次删除
  1. 16 7
      net/bridge/br_fdb.c

+ 16 - 7
net/bridge/br_fdb.c

@@ -558,19 +558,28 @@ skip:
 
 
 /* Create new static fdb entry */
 /* Create new static fdb entry */
 static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
 static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
-			 __u16 state)
+			 __u16 state, __u16 flags)
 {
 {
 	struct net_bridge *br = source->br;
 	struct net_bridge *br = source->br;
 	struct hlist_head *head = &br->hash[br_mac_hash(addr)];
 	struct hlist_head *head = &br->hash[br_mac_hash(addr)];
 	struct net_bridge_fdb_entry *fdb;
 	struct net_bridge_fdb_entry *fdb;
 
 
 	fdb = fdb_find(head, addr);
 	fdb = fdb_find(head, addr);
-	if (fdb)
-		return -EEXIST;
+	if (fdb == NULL) {
+		if (!(flags & NLM_F_CREATE))
+			return -ENOENT;
 
 
-	fdb = fdb_create(head, source, addr);
-	if (!fdb)
-		return -ENOMEM;
+		fdb = fdb_create(head, source, addr);
+		if (!fdb)
+			return -ENOMEM;
+	} else {
+		if (flags & NLM_F_EXCL)
+			return -EEXIST;
+
+		if (flags & NLM_F_REPLACE)
+			fdb->updated = fdb->used = jiffies;
+		fdb->is_local = fdb->is_static = 0;
+	}
 
 
 	if (state & NUD_PERMANENT)
 	if (state & NUD_PERMANENT)
 		fdb->is_local = fdb->is_static = 1;
 		fdb->is_local = fdb->is_static = 1;
@@ -626,7 +635,7 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 	}
 	}
 
 
 	spin_lock_bh(&p->br->hash_lock);
 	spin_lock_bh(&p->br->hash_lock);
-	err = fdb_add_entry(p, addr, ndm->ndm_state);
+	err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags);
 	spin_unlock_bh(&p->br->hash_lock);
 	spin_unlock_bh(&p->br->hash_lock);
 
 
 	return err;
 	return err;