Skip to content

Commit 45a6878

Browse files
Nikolay Aleksandrovkuba-moo
authored andcommitted
net: bridge: fix flags interpretation for extern learn fdb entries
Ignore fdb flags when adding port extern learn entries and always set BR_FDB_LOCAL flag when adding bridge extern learn entries. This is closest to the behaviour we had before and avoids breaking any use cases which were allowed. This patch fixes iproute2 calls which assume NUD_PERMANENT and were allowed before, example: $ bridge fdb add 00:11:22:33:44:55 dev swp1 extern_learn Extern learn entries are allowed to roam, but do not expire, so static or dynamic flags make no sense for them. Also add a comment for future reference. Fixes: eb100e0 ("net: bridge: allow to add externally learned entries from user-space") Fixes: 0541a62 ("net: bridge: validate the NUD_PERMANENT bit when adding an extern_learn FDB entry") Reviewed-by: Ido Schimmel <[email protected]> Tested-by: Ido Schimmel <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Reviewed-by: Vladimir Oltean <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 2e273b0 commit 45a6878

File tree

4 files changed

+11
-12
lines changed

4 files changed

+11
-12
lines changed

include/uapi/linux/neighbour.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ enum {
6666
#define NUD_NONE 0x00
6767

6868
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change
69-
and make no address resolution or NUD.
70-
NUD_PERMANENT also cannot be deleted by garbage collectors.
69+
* and make no address resolution or NUD.
70+
* NUD_PERMANENT also cannot be deleted by garbage collectors.
71+
* When NTF_EXT_LEARNED is set for a bridge fdb entry the different cache entry
72+
* states don't make sense and thus are ignored. Such entries don't age and
73+
* can roam.
7174
*/
7275

7376
struct nda_cacheinfo {

net/bridge/br.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ static int br_switchdev_event(struct notifier_block *unused,
166166
case SWITCHDEV_FDB_ADD_TO_BRIDGE:
167167
fdb_info = ptr;
168168
err = br_fdb_external_learn_add(br, p, fdb_info->addr,
169-
fdb_info->vid,
170-
fdb_info->is_local, false);
169+
fdb_info->vid, false);
171170
if (err) {
172171
err = notifier_from_errno(err);
173172
break;

net/bridge/br_fdb.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,10 +1044,7 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
10441044
"FDB entry towards bridge must be permanent");
10451045
return -EINVAL;
10461046
}
1047-
1048-
err = br_fdb_external_learn_add(br, p, addr, vid,
1049-
ndm->ndm_state & NUD_PERMANENT,
1050-
true);
1047+
err = br_fdb_external_learn_add(br, p, addr, vid, true);
10511048
} else {
10521049
spin_lock_bh(&br->hash_lock);
10531050
err = fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb);
@@ -1275,7 +1272,7 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
12751272
}
12761273

12771274
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
1278-
const unsigned char *addr, u16 vid, bool is_local,
1275+
const unsigned char *addr, u16 vid,
12791276
bool swdev_notify)
12801277
{
12811278
struct net_bridge_fdb_entry *fdb;
@@ -1293,7 +1290,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
12931290
if (swdev_notify)
12941291
flags |= BIT(BR_FDB_ADDED_BY_USER);
12951292

1296-
if (is_local)
1293+
if (!p)
12971294
flags |= BIT(BR_FDB_LOCAL);
12981295

12991296
fdb = fdb_create(br, p, addr, vid, flags);
@@ -1322,7 +1319,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
13221319
if (swdev_notify)
13231320
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
13241321

1325-
if (is_local)
1322+
if (!p)
13261323
set_bit(BR_FDB_LOCAL, &fdb->flags);
13271324

13281325
if (modified)

net/bridge/br_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev,
711711
int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
712712
void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
713713
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
714-
const unsigned char *addr, u16 vid, bool is_local,
714+
const unsigned char *addr, u16 vid,
715715
bool swdev_notify);
716716
int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
717717
const unsigned char *addr, u16 vid,

0 commit comments

Comments
 (0)