--- zzzz-none-000/linux-5.15.111/net/bridge/br_fdb.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-arm-6670-761/linux-5.15.111/net/bridge/br_fdb.c 2024-02-07 09:28:09.000000000 +0000 @@ -1,10 +1,27 @@ -// SPDX-License-Identifier: GPL-2.0-or-later /* - * Forwarding database - * Linux ethernet bridge + * Copyright (C) 2020-2022 MaxLinear, Inc. + * Copyright (C) 2011-2020 Intel Corporation * - * Authors: - * Lennert Buytenhek + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see http://www.gnu.org/licenses/. + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/* + * Includes Maxlinear's changes dated: 2022. + * Changed portions - Copyright 2020-2022 MaxLinear, Inc. + * Includes Intel Corporation's changes/modifications dated: [11/07/2011]. + * Changed/modified portions - Copyright © [2011], Intel Corporation. */ #include @@ -14,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +42,7 @@ #include #include "br_private.h" + static const struct rhashtable_params br_fdb_rht_params = { .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), .key_offset = offsetof(struct net_bridge_fdb_entry, key), @@ -31,6 +50,10 @@ .automatic_shrinking = true, }; +#ifdef CONFIG_INTEL_MAX_BRIDGE_MACS_LIMIT +static int fdb_insert_cnt = 0; +#endif + static struct kmem_cache *br_fdb_cache __read_mostly; static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr, u16 vid); @@ -206,6 +229,12 @@ br_fdb_rht_params); fdb_notify(br, f, RTM_DELNEIGH, swdev_notify); call_rcu(&f->rcu, fdb_rcu_free); + +#ifdef CONFIG_INTEL_MAX_BRIDGE_MACS_LIMIT + if (fdb_insert_cnt >= 1) { + fdb_insert_cnt--; + } +#endif } /* Delete a local entry if no other port had the same address. */ @@ -369,7 +398,26 @@ } else { spin_lock_bh(&br->hash_lock); if (!hlist_unhashed(&f->fdb_node)) +#ifdef CONFIG_TI_PACKET_PROCESSOR + { + /* Generate a HIL Packet Processor event indicating that the FDB entry + * is being deleted. Notifications are sent only for non-local FDB + * entries as local traffic is not accelerated through PP. */ + if(!test_bit(BR_FDB_LOCAL, &f->flags)) + ti_hil_pp_event(TI_BRIDGE_FDB_TIMEOUT, (void*)f); + + + /* Check if the PP has a session alive for this FDB entry + * ACTIVE - Reset ageing timer + * NOT ACTIVE - Delete the FDB entry. */ + if (!(f->ti_pp_fdb_status & TI_PP_FDB_ACTIVE)) + fdb_delete(br, f, true); + } + else + f->updated = jiffies; +#else fdb_delete(br, f, true); +#endif spin_unlock_bh(&br->hash_lock); } } @@ -511,6 +559,13 @@ { struct net_bridge_fdb_entry *fdb; +#ifdef CONFIG_INTEL_MAX_BRIDGE_MACS_LIMIT + if (fdb_insert_cnt >= CONFIG_INTEL_MAX_BRIDGE_MACS) { + printk(KERN_WARNING "\n fdb_create reached max bridge macs limit \n"); + return 0; + } +#endif + fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); if (fdb) { memcpy(fdb->key.addr.addr, addr, ETH_ALEN); @@ -524,7 +579,26 @@ kmem_cache_free(br_fdb_cache, fdb); fdb = NULL; } else { +#ifdef CONFIG_TI_PACKET_PROCESSOR + /* Initialize the Status flag to INACTIVE by default. If + * the event TI_BRIDGE_FDB_CREATED is indeed handled, then + * this flag must be set to TI_PP_FDB_ACTIVE so that it + * can be synced up with PP when FDB entry expires in the + * bridge. If the status flag is not set active, it is assumed + * that the TI_BRIDGE_FDB_* events are not handled and thus + * bridge takes complete control over the fdb entry deletion */ + fdb->ti_pp_fdb_status = TI_PP_FDB_INACTIVE; +#endif hlist_add_head_rcu(&fdb->fdb_node, &br->fdb_list); +#ifdef CONFIG_TI_PACKET_PROCESSOR + /* Indicate to the HIL layer that a non-local FDB entry has been created. */ + if (!test_bit(BR_FDB_LOCAL, &fdb->flags)) + ti_hil_pp_event(TI_BRIDGE_FDB_CREATED, (void *)fdb); +#endif + +#ifdef CONFIG_INTEL_MAX_BRIDGE_MACS_LIMIT + fdb_insert_cnt++; +#endif } } return fdb; @@ -616,7 +690,10 @@ clear_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags); } - +#ifdef CONFIG_TI_PACKET_PROCESSOR + /* Indicate to the HIL layer that an FDB entry has been updated. */ + ti_hil_pp_event(TI_BRIDGE_FDB_CREATED, (void *)fdb); +#endif if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); if (unlikely(fdb_modified)) {