Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 292d1398 authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller
Browse files

bridge: add NTF_USE support



More changes to the recent code to support control of forwarding
database via netlink.
   * Support NTF_USE like neighbour table
   * Validate state bits from application
   * Only send notifications (and change bits) if new entry is
     different.

Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 23020ab3
Loading
Loading
Loading
Loading
+27 −11
Original line number Diff line number Diff line
@@ -556,7 +556,7 @@ int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
	return skb->len;
}

/* Create new static fdb entry */
/* Update (create or replace) forwarding database entry */
static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
			 __u16 state, __u16 flags)
{
@@ -575,16 +575,21 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
	} 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 (fdb_to_nud(fdb) != state) {
		if (state & NUD_PERMANENT)
			fdb->is_local = fdb->is_static = 1;
	else if (state & NUD_NOARP)
		else if (state & NUD_NOARP) {
			fdb->is_local = 0;
			fdb->is_static = 1;
		} else
			fdb->is_local = fdb->is_static = 0;

		fdb->updated = fdb->used = jiffies;
		fdb_notify(fdb, RTM_NEWNEIGH);
	}

	return 0;
}

@@ -627,6 +632,11 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
		return -EINVAL;
	}

	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
		pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
		return -EINVAL;
	}

	p = br_port_get_rtnl(dev);
	if (p == NULL) {
		pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
@@ -634,9 +644,15 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
		return -EINVAL;
	}

	if (ndm->ndm_flags & NTF_USE) {
		rcu_read_lock();
		br_fdb_update(p->br, p, addr);
		rcu_read_unlock();
	} else {
		spin_lock_bh(&p->br->hash_lock);
		err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags);
		spin_unlock_bh(&p->br->hash_lock);
	}

	return err;
}