Commit 6869c3b0 authored by Nikolay Aleksandrov's avatar Nikolay Aleksandrov Committed by David S. Miller

net: bridge: fdb: convert is_local to bitops

The patch adds a new fdb flags field in the hole between the two cache
lines and uses it to convert is_local to bitops.
Signed-off-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8466a57d
...@@ -250,7 +250,8 @@ void br_fdb_find_delete_local(struct net_bridge *br, ...@@ -250,7 +250,8 @@ void br_fdb_find_delete_local(struct net_bridge *br,
spin_lock_bh(&br->hash_lock); spin_lock_bh(&br->hash_lock);
f = br_fdb_find(br, addr, vid); f = br_fdb_find(br, addr, vid);
if (f && f->is_local && !f->added_by_user && f->dst == p) if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
!f->added_by_user && f->dst == p)
fdb_delete_local(br, p, f); fdb_delete_local(br, p, f);
spin_unlock_bh(&br->hash_lock); spin_unlock_bh(&br->hash_lock);
} }
...@@ -265,7 +266,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) ...@@ -265,7 +266,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
spin_lock_bh(&br->hash_lock); spin_lock_bh(&br->hash_lock);
vg = nbp_vlan_group(p); vg = nbp_vlan_group(p);
hlist_for_each_entry(f, &br->fdb_list, fdb_node) { hlist_for_each_entry(f, &br->fdb_list, fdb_node) {
if (f->dst == p && f->is_local && !f->added_by_user) { if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) &&
!f->added_by_user) {
/* delete old one */ /* delete old one */
fdb_delete_local(br, p, f); fdb_delete_local(br, p, f);
...@@ -306,7 +308,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) ...@@ -306,7 +308,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
/* If old entry was unassociated with any port, then delete it. */ /* If old entry was unassociated with any port, then delete it. */
f = br_fdb_find(br, br->dev->dev_addr, 0); f = br_fdb_find(br, br->dev->dev_addr, 0);
if (f && f->is_local && !f->dst && !f->added_by_user) if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
!f->dst && !f->added_by_user)
fdb_delete_local(br, NULL, f); fdb_delete_local(br, NULL, f);
fdb_insert(br, NULL, newaddr, 0); fdb_insert(br, NULL, newaddr, 0);
...@@ -321,7 +324,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) ...@@ -321,7 +324,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
if (!br_vlan_should_use(v)) if (!br_vlan_should_use(v))
continue; continue;
f = br_fdb_find(br, br->dev->dev_addr, v->vid); f = br_fdb_find(br, br->dev->dev_addr, v->vid);
if (f && f->is_local && !f->dst && !f->added_by_user) if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
!f->dst && !f->added_by_user)
fdb_delete_local(br, NULL, f); fdb_delete_local(br, NULL, f);
fdb_insert(br, NULL, newaddr, v->vid); fdb_insert(br, NULL, newaddr, v->vid);
} }
...@@ -400,7 +404,7 @@ void br_fdb_delete_by_port(struct net_bridge *br, ...@@ -400,7 +404,7 @@ void br_fdb_delete_by_port(struct net_bridge *br,
if (f->is_static || (vid && f->key.vlan_id != vid)) if (f->is_static || (vid && f->key.vlan_id != vid))
continue; continue;
if (f->is_local) if (test_bit(BR_FDB_LOCAL, &f->flags))
fdb_delete_local(br, p, f); fdb_delete_local(br, p, f);
else else
fdb_delete(br, f, true); fdb_delete(br, f, true);
...@@ -469,7 +473,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, ...@@ -469,7 +473,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
fe->port_no = f->dst->port_no; fe->port_no = f->dst->port_no;
fe->port_hi = f->dst->port_no >> 8; fe->port_hi = f->dst->port_no >> 8;
fe->is_local = f->is_local; fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags);
if (!f->is_static) if (!f->is_static)
fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated); fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
++fe; ++fe;
...@@ -494,7 +498,9 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, ...@@ -494,7 +498,9 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
memcpy(fdb->key.addr.addr, addr, ETH_ALEN); memcpy(fdb->key.addr.addr, addr, ETH_ALEN);
fdb->dst = source; fdb->dst = source;
fdb->key.vlan_id = vid; fdb->key.vlan_id = vid;
fdb->is_local = is_local; fdb->flags = 0;
if (is_local)
set_bit(BR_FDB_LOCAL, &fdb->flags);
fdb->is_static = is_static; fdb->is_static = is_static;
fdb->added_by_user = 0; fdb->added_by_user = 0;
fdb->added_by_external_learn = 0; fdb->added_by_external_learn = 0;
...@@ -526,7 +532,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, ...@@ -526,7 +532,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
/* it is okay to have multiple ports with same /* it is okay to have multiple ports with same
* address, just use the first one. * address, just use the first one.
*/ */
if (fdb->is_local) if (test_bit(BR_FDB_LOCAL, &fdb->flags))
return 0; return 0;
br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n", br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n",
source ? source->dev->name : br->dev->name, addr, vid); source ? source->dev->name : br->dev->name, addr, vid);
...@@ -572,7 +578,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, ...@@ -572,7 +578,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
if (likely(fdb)) { if (likely(fdb)) {
/* attempt to update an entry for a local interface */ /* attempt to update an entry for a local interface */
if (unlikely(fdb->is_local)) { if (unlikely(test_bit(BR_FDB_LOCAL, &fdb->flags))) {
if (net_ratelimit()) if (net_ratelimit())
br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n", br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n",
source->dev->name, addr, vid); source->dev->name, addr, vid);
...@@ -616,7 +622,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, ...@@ -616,7 +622,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
static int fdb_to_nud(const struct net_bridge *br, static int fdb_to_nud(const struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb) const struct net_bridge_fdb_entry *fdb)
{ {
if (fdb->is_local) if (test_bit(BR_FDB_LOCAL, &fdb->flags))
return NUD_PERMANENT; return NUD_PERMANENT;
else if (fdb->is_static) else if (fdb->is_static)
return NUD_NOARP; return NUD_NOARP;
...@@ -840,19 +846,19 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, ...@@ -840,19 +846,19 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
if (fdb_to_nud(br, fdb) != state) { if (fdb_to_nud(br, fdb) != state) {
if (state & NUD_PERMANENT) { if (state & NUD_PERMANENT) {
fdb->is_local = 1; set_bit(BR_FDB_LOCAL, &fdb->flags);
if (!fdb->is_static) { if (!fdb->is_static) {
fdb->is_static = 1; fdb->is_static = 1;
fdb_add_hw_addr(br, addr); fdb_add_hw_addr(br, addr);
} }
} else if (state & NUD_NOARP) { } else if (state & NUD_NOARP) {
fdb->is_local = 0; clear_bit(BR_FDB_LOCAL, &fdb->flags);
if (!fdb->is_static) { if (!fdb->is_static) {
fdb->is_static = 1; fdb->is_static = 1;
fdb_add_hw_addr(br, addr); fdb_add_hw_addr(br, addr);
} }
} else { } else {
fdb->is_local = 0; clear_bit(BR_FDB_LOCAL, &fdb->flags);
if (fdb->is_static) { if (fdb->is_static) {
fdb->is_static = 0; fdb->is_static = 0;
fdb_del_hw_addr(br, addr); fdb_del_hw_addr(br, addr);
......
...@@ -151,7 +151,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -151,7 +151,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
if (dst) { if (dst) {
unsigned long now = jiffies; unsigned long now = jiffies;
if (dst->is_local) if (test_bit(BR_FDB_LOCAL, &dst->flags))
return br_pass_frame_up(skb); return br_pass_frame_up(skb);
if (now != dst->used) if (now != dst->used)
......
...@@ -172,6 +172,11 @@ struct net_bridge_vlan_group { ...@@ -172,6 +172,11 @@ struct net_bridge_vlan_group {
u16 pvid; u16 pvid;
}; };
/* bridge fdb flags */
enum {
BR_FDB_LOCAL,
};
struct net_bridge_fdb_key { struct net_bridge_fdb_key {
mac_addr addr; mac_addr addr;
u16 vlan_id; u16 vlan_id;
...@@ -183,8 +188,8 @@ struct net_bridge_fdb_entry { ...@@ -183,8 +188,8 @@ struct net_bridge_fdb_entry {
struct net_bridge_fdb_key key; struct net_bridge_fdb_key key;
struct hlist_node fdb_node; struct hlist_node fdb_node;
unsigned char is_local:1, unsigned long flags;
is_static:1, unsigned char is_static:1,
is_sticky:1, is_sticky:1,
added_by_user:1, added_by_user:1,
added_by_external_learn:1, added_by_external_learn:1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment