Skip to content

Commit 435f2e7

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
net: bridge: add support for sticky fdb entries
Add support for entries which are "sticky", i.e. will not change their port if they show up from a different one. A new ndm flag is introduced for that purpose - NTF_STICKY. We allow to set it only to non-local entries. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1566534 commit 435f2e7

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

include/uapi/linux/neighbour.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {
4343
#define NTF_PROXY 0x08 /* == ATF_PUBL */
4444
#define NTF_EXT_LEARNED 0x10
4545
#define NTF_OFFLOADED 0x20
46+
#define NTF_STICKY 0x40
4647
#define NTF_ROUTER 0x80
4748

4849
/*

net/bridge/br_fdb.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
584584
unsigned long now = jiffies;
585585

586586
/* fastpath: update of existing entry */
587-
if (unlikely(source != fdb->dst)) {
587+
if (unlikely(source != fdb->dst && !fdb->is_sticky)) {
588588
fdb->dst = source;
589589
fdb_modified = true;
590590
/* Take over HW learned entry */
@@ -656,6 +656,8 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
656656
ndm->ndm_flags |= NTF_OFFLOADED;
657657
if (fdb->added_by_external_learn)
658658
ndm->ndm_flags |= NTF_EXT_LEARNED;
659+
if (fdb->is_sticky)
660+
ndm->ndm_flags |= NTF_STICKY;
659661

660662
if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.addr))
661663
goto nla_put_failure;
@@ -772,8 +774,10 @@ int br_fdb_dump(struct sk_buff *skb,
772774

773775
/* Update (create or replace) forwarding database entry */
774776
static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
775-
const __u8 *addr, __u16 state, __u16 flags, __u16 vid)
777+
const u8 *addr, u16 state, u16 flags, u16 vid,
778+
u8 ndm_flags)
776779
{
780+
u8 is_sticky = !!(ndm_flags & NTF_STICKY);
777781
struct net_bridge_fdb_entry *fdb;
778782
bool modified = false;
779783

@@ -789,6 +793,9 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
789793
return -EINVAL;
790794
}
791795

796+
if (is_sticky && (state & NUD_PERMANENT))
797+
return -EINVAL;
798+
792799
fdb = br_fdb_find(br, addr, vid);
793800
if (fdb == NULL) {
794801
if (!(flags & NLM_F_CREATE))
@@ -832,6 +839,12 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
832839

833840
modified = true;
834841
}
842+
843+
if (is_sticky != fdb->is_sticky) {
844+
fdb->is_sticky = is_sticky;
845+
modified = true;
846+
}
847+
835848
fdb->added_by_user = 1;
836849

837850
fdb->used = jiffies;
@@ -865,7 +878,7 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
865878
} else {
866879
spin_lock_bh(&br->hash_lock);
867880
err = fdb_add_entry(br, p, addr, ndm->ndm_state,
868-
nlh_flags, vid);
881+
nlh_flags, vid, ndm->ndm_flags);
869882
spin_unlock_bh(&br->hash_lock);
870883
}
871884

net/bridge/br_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ struct net_bridge_fdb_entry {
181181
struct hlist_node fdb_node;
182182
unsigned char is_local:1,
183183
is_static:1,
184+
is_sticky:1,
184185
added_by_user:1,
185186
added_by_external_learn:1,
186187
offloaded:1;

0 commit comments

Comments
 (0)