mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
This is the 5.4.284 stable release
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmbirowACgkQONu9yGCS
aT50ww//X5S6LV/0C9V3+lq0zLBl6X6D0yyNlV4KFISFWoFPo2N13uxQ6+ZQliB5
gYNRH1b/RBJxa50LjydvCtkJTsWuraZ0uW+tx6GvsfjlC7HeRqGDzOAcFehM9Fjc
d/nn7J32amJZ2un8Xnf/B16z+WEbBzIq8ca1K2iPb/1+JQsgDFn0LGmyzNUOrdet
Q2fpsaAzdCa72v9CzKALpK/rgAv8PIcx2dObp3YOX7ccKumP2qWg8s4dLhzYgSZ2
MQNy55IxBKM7xKlqDPwaBgZipfAUHPPZrHlWYwEVQNIukn9l5ymjfhj8Wv6AqbgO
KxvSNNpOnsw7ShdczumTY0JimUxziPXVcrZMX04L1a65rWrILiCjLpWPKxIhIRyL
MIjvVg7GOWjDes+zJaKAO/X0A9oMY/inVLVrQqfWF+igXKsfwaylEqHX/qrdALZL
/TIE7LV3iVNRm7qq3f4T8lCOGiy+gIhEgnWomzo6caulgQtnm6qmRkAgq/Siuzj1
AMQt8d/3RNU6EQIuBFGKtYdLo9ccU1BNW773ekF3+szvmGrwp9vlGHCLixIdJt/a
bGp2+nBr7eOWCjj3Lcm1x3vt+GY5FHBeZJEFLQ+sgSJC16o6UxXFLJeiCLOnLmaA
r1Q3CrCCawFWDz8MBvM6xX1/XWmattoaUilMRLkqmP0SRKWmgIg=
=Ii83
-----END PGP SIGNATURE-----
Merge 5.4.284 into android11-5.4-lts
Changes in 5.4.284
drm: panel-orientation-quirks: Add quirk for OrangePi Neo
i2c: Fix conditional for substituting empty ACPI functions
net: usb: qmi_wwan: add MeiG Smart SRM825L
drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr
drm/amdgpu: fix overflowed array index read warning
drm/amd/display: Check gpio_id before used as array index
drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6
drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[]
drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create
drm/amdgpu: fix ucode out-of-bounds read warning
drm/amdgpu: fix mc_data out-of-bounds read warning
drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device
apparmor: fix possible NULL pointer dereference
ionic: fix potential irq name truncation
usbip: Don't submit special requests twice
usb: typec: ucsi: Fix null pointer dereference in trace
smack: tcp: ipv4, fix incorrect labeling
wifi: cfg80211: make hash table duplicates more survivable
drm/amd/display: Skip wbscl_set_scaler_filter if filter is null
media: uvcvideo: Enforce alignment of frame and interval
block: initialize integrity buffer to zero before writing it to media
net: set SOCK_RCU_FREE before inserting socket into hashtable
virtio_net: Fix napi_skb_cache_put warning
udf: Limit file size to 4TB
i2c: Use IS_REACHABLE() for substituting empty ACPI functions
sch/netem: fix use after free in netem_dequeue
ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius devices
ata: libata: Fix memory leak for error path in ata_host_alloc()
irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
mmc: sdhci-of-aspeed: fix module autoloading
fuse: update stats for pages in dropped aux writeback list
fuse: use unsigned type for getxattr/listxattr size truncation
reset: hi6220: Add support for AO reset controller
clk: hi6220: use CLK_OF_DECLARE_DRIVER
clk: qcom: clk-alpha-pll: Fix the pll post div mask
clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
ila: call nf_unregister_net_hooks() sooner
sched: sch_cake: fix bulk flow accounting logic for host fairness
nilfs2: fix missing cleanup on rollforward recovery error
nilfs2: fix state management in error path of log writing function
ALSA: hda: Add input value sanity checks to HDMI channel map controls
smack: unix sockets: fix accept()ed socket label
irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
af_unix: Remove put_pid()/put_cred() in copy_peercred().
netfilter: nf_conncount: fix wrong variable type
udf: Avoid excessive partition lengths
wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
usb: uas: set host status byte on data completion error
PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
pcmcia: Use resource_size function on resource object
can: bcm: Remove proc entry when dev is unregistered.
igb: Fix not clearing TimeSync interrupts for 82580
platform/x86: dell-smbios: Fix error path in dell_smbios_init()
tcp_bpf: fix return value of tcp_bpf_sendmsg()
cx82310_eth: re-enable ethernet mode after router reboot
drivers/net/usb: Remove all strcpy() uses
net: usb: don't write directly to netdev->dev_addr
usbnet: modern method to get random MAC
net: bridge: fdb: convert is_local to bitops
net: bridge: fdb: convert is_static to bitops
net: bridge: fdb: convert is_sticky to bitops
net: bridge: fdb: convert added_by_user to bitops
net: bridge: fdb: convert added_by_external_learn to use bitops
net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
net: dsa: vsc73xx: fix possible subblocks range of CAPT block
ASoC: topology: Properly initialize soc_enum values
dm init: Handle minors larger than 255
iommu/vt-d: Handle volatile descriptor status read
cgroup: Protect css->cgroup write under css_set_lock
um: line: always fill *error_out in setup_one_line()
devres: Initialize an uninitialized struct member
pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
hwmon: (adc128d818) Fix underflows seen when writing limit attributes
hwmon: (lm95234) Fix underflows seen when writing limit attributes
hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
btrfs: replace BUG_ON with ASSERT in walk_down_proc()
btrfs: clean up our handling of refs == 0 in snapshot delete
PCI: Add missing bridge lock to pci_bus_lock()
btrfs: initialize location to fix -Wmaybe-uninitialized in btrfs_lookup_dentry()
HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
Input: uinput - reject requests with unreasonable number of slots
usbnet: ipheth: race between ipheth_close and error handling
Squashfs: sanity check symbolic link size
of/irq: Prevent device address out-of-bounds read in interrupt map walk
lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
ata: pata_macio: Use WARN instead of BUG
NFSv4: Add missing rescheduling points in nfs_client_return_marked_delegations
staging: iio: frequency: ad9834: Validate frequency parameter value
iio: buffer-dmaengine: fix releasing dma channel on error
iio: fix scale application in iio_convert_raw_to_processed_unlocked
binder: fix UAF caused by offsets overwrite
nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc
uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind
Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic
VMCI: Fix use-after-free when removing resource in vmci_resource_remove()
clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
clocksource/drivers/timer-of: Remove percpu irq related code
uprobes: Use kzalloc to allocate xol area
ring-buffer: Rename ring_buffer_read() to read_buffer_iter_advance()
tracing: Avoid possible softlockup in tracing_iter_reset()
nilfs2: replace snprintf in show functions with sysfs_emit
nilfs2: protect references to superblock parameters exposed in sysfs
ACPI: processor: Return an error if acpi_processor_get_info() fails in processor_add()
ACPI: processor: Fix memory leaks in error paths of processor_add()
arm64: acpi: Move get_cpu_for_acpi_id() to a header
arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
nvmet-tcp: fix kernel crash if commands allocation fails
drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
drm/i915/fence: Mark debug_fence_free() with __maybe_unused
rtmutex: Drop rt_mutex::wait_lock before scheduling
net, sunrpc: Remap EPERM in case of connection failure in xs_tcp_setup_socket
cx82310_eth: fix error return code in cx82310_bind()
Revert "parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367"
Linux 5.4.284
Change-Id: Iafe252fcdd21fee8cffd209d616f8af16c9f4153
Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
commit
97009b56c6
119 changed files with 898 additions and 396 deletions
|
|
@ -75,8 +75,9 @@ static inline unsigned long hold_time(const struct net_bridge *br)
|
|||
static inline int has_expired(const struct net_bridge *br,
|
||||
const struct net_bridge_fdb_entry *fdb)
|
||||
{
|
||||
return !fdb->is_static && !fdb->added_by_external_learn &&
|
||||
time_before_eq(fdb->updated + hold_time(br), jiffies);
|
||||
return !test_bit(BR_FDB_STATIC, &fdb->flags) &&
|
||||
!test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) &&
|
||||
time_before_eq(fdb->updated + hold_time(br), jiffies);
|
||||
}
|
||||
|
||||
static void fdb_rcu_free(struct rcu_head *head)
|
||||
|
|
@ -197,7 +198,7 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
|
|||
{
|
||||
trace_fdb_delete(br, f);
|
||||
|
||||
if (f->is_static)
|
||||
if (test_bit(BR_FDB_STATIC, &f->flags))
|
||||
fdb_del_hw_addr(br, f->key.addr.addr);
|
||||
|
||||
hlist_del_init_rcu(&f->fdb_node);
|
||||
|
|
@ -224,7 +225,7 @@ static void fdb_delete_local(struct net_bridge *br,
|
|||
if (op != p && ether_addr_equal(op->dev->dev_addr, addr) &&
|
||||
(!vid || br_vlan_find(vg, vid))) {
|
||||
f->dst = op;
|
||||
f->added_by_user = 0;
|
||||
clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -235,7 +236,7 @@ static void fdb_delete_local(struct net_bridge *br,
|
|||
if (p && ether_addr_equal(br->dev->dev_addr, addr) &&
|
||||
(!vid || (v && br_vlan_should_use(v)))) {
|
||||
f->dst = NULL;
|
||||
f->added_by_user = 0;
|
||||
clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +251,8 @@ void br_fdb_find_delete_local(struct net_bridge *br,
|
|||
|
||||
spin_lock_bh(&br->hash_lock);
|
||||
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) &&
|
||||
!test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p)
|
||||
fdb_delete_local(br, p, f);
|
||||
spin_unlock_bh(&br->hash_lock);
|
||||
}
|
||||
|
|
@ -265,7 +267,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
|
|||
spin_lock_bh(&br->hash_lock);
|
||||
vg = nbp_vlan_group(p);
|
||||
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) &&
|
||||
!test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) {
|
||||
/* delete old one */
|
||||
fdb_delete_local(br, p, f);
|
||||
|
||||
|
|
@ -306,7 +309,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. */
|
||||
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 && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
|
||||
fdb_delete_local(br, NULL, f);
|
||||
|
||||
fdb_insert(br, NULL, newaddr, 0);
|
||||
|
|
@ -321,7 +325,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
|
|||
if (!br_vlan_should_use(v))
|
||||
continue;
|
||||
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 && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
|
||||
fdb_delete_local(br, NULL, f);
|
||||
fdb_insert(br, NULL, newaddr, v->vid);
|
||||
}
|
||||
|
|
@ -346,7 +351,8 @@ void br_fdb_cleanup(struct work_struct *work)
|
|||
hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
|
||||
unsigned long this_timer;
|
||||
|
||||
if (f->is_static || f->added_by_external_learn)
|
||||
if (test_bit(BR_FDB_STATIC, &f->flags) ||
|
||||
test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags))
|
||||
continue;
|
||||
this_timer = f->updated + delay;
|
||||
if (time_after(this_timer, now)) {
|
||||
|
|
@ -373,7 +379,7 @@ void br_fdb_flush(struct net_bridge *br)
|
|||
|
||||
spin_lock_bh(&br->hash_lock);
|
||||
hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
|
||||
if (!f->is_static)
|
||||
if (!test_bit(BR_FDB_STATIC, &f->flags))
|
||||
fdb_delete(br, f, true);
|
||||
}
|
||||
spin_unlock_bh(&br->hash_lock);
|
||||
|
|
@ -397,10 +403,11 @@ void br_fdb_delete_by_port(struct net_bridge *br,
|
|||
continue;
|
||||
|
||||
if (!do_all)
|
||||
if (f->is_static || (vid && f->key.vlan_id != vid))
|
||||
if (test_bit(BR_FDB_STATIC, &f->flags) ||
|
||||
(vid && f->key.vlan_id != vid))
|
||||
continue;
|
||||
|
||||
if (f->is_local)
|
||||
if (test_bit(BR_FDB_LOCAL, &f->flags))
|
||||
fdb_delete_local(br, p, f);
|
||||
else
|
||||
fdb_delete(br, f, true);
|
||||
|
|
@ -469,8 +476,8 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
|
|||
fe->port_no = f->dst->port_no;
|
||||
fe->port_hi = f->dst->port_no >> 8;
|
||||
|
||||
fe->is_local = f->is_local;
|
||||
if (!f->is_static)
|
||||
fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags);
|
||||
if (!test_bit(BR_FDB_STATIC, &f->flags))
|
||||
fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
|
||||
++fe;
|
||||
++num;
|
||||
|
|
@ -494,12 +501,12 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
|
|||
memcpy(fdb->key.addr.addr, addr, ETH_ALEN);
|
||||
fdb->dst = source;
|
||||
fdb->key.vlan_id = vid;
|
||||
fdb->is_local = is_local;
|
||||
fdb->is_static = is_static;
|
||||
fdb->added_by_user = 0;
|
||||
fdb->added_by_external_learn = 0;
|
||||
fdb->flags = 0;
|
||||
if (is_local)
|
||||
set_bit(BR_FDB_LOCAL, &fdb->flags);
|
||||
if (is_static)
|
||||
set_bit(BR_FDB_STATIC, &fdb->flags);
|
||||
fdb->offloaded = 0;
|
||||
fdb->is_sticky = 0;
|
||||
fdb->updated = fdb->used = jiffies;
|
||||
if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl,
|
||||
&fdb->rhnode,
|
||||
|
|
@ -526,7 +533,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
|
|||
/* it is okay to have multiple ports with same
|
||||
* address, just use the first one.
|
||||
*/
|
||||
if (fdb->is_local)
|
||||
if (test_bit(BR_FDB_LOCAL, &fdb->flags))
|
||||
return 0;
|
||||
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);
|
||||
|
|
@ -572,7 +579,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
|
|||
fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
|
||||
if (likely(fdb)) {
|
||||
/* 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())
|
||||
br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n",
|
||||
source->dev->name, addr, vid);
|
||||
|
|
@ -580,17 +587,18 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
|
|||
unsigned long now = jiffies;
|
||||
|
||||
/* fastpath: update of existing entry */
|
||||
if (unlikely(source != fdb->dst && !fdb->is_sticky)) {
|
||||
if (unlikely(source != fdb->dst &&
|
||||
!test_bit(BR_FDB_STICKY, &fdb->flags))) {
|
||||
fdb->dst = source;
|
||||
fdb_modified = true;
|
||||
/* Take over HW learned entry */
|
||||
if (unlikely(fdb->added_by_external_learn))
|
||||
fdb->added_by_external_learn = 0;
|
||||
test_and_clear_bit(BR_FDB_ADDED_BY_EXT_LEARN,
|
||||
&fdb->flags);
|
||||
}
|
||||
if (now != fdb->updated)
|
||||
fdb->updated = now;
|
||||
if (unlikely(added_by_user))
|
||||
fdb->added_by_user = 1;
|
||||
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
|
||||
if (unlikely(fdb_modified)) {
|
||||
trace_br_fdb_update(br, source, addr, vid, added_by_user);
|
||||
fdb_notify(br, fdb, RTM_NEWNEIGH, true);
|
||||
|
|
@ -601,7 +609,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
|
|||
fdb = fdb_create(br, source, addr, vid, 0, 0);
|
||||
if (fdb) {
|
||||
if (unlikely(added_by_user))
|
||||
fdb->added_by_user = 1;
|
||||
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
|
||||
trace_br_fdb_update(br, source, addr, vid,
|
||||
added_by_user);
|
||||
fdb_notify(br, fdb, RTM_NEWNEIGH, true);
|
||||
|
|
@ -616,9 +624,9 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
|
|||
static int fdb_to_nud(const struct net_bridge *br,
|
||||
const struct net_bridge_fdb_entry *fdb)
|
||||
{
|
||||
if (fdb->is_local)
|
||||
if (test_bit(BR_FDB_LOCAL, &fdb->flags))
|
||||
return NUD_PERMANENT;
|
||||
else if (fdb->is_static)
|
||||
else if (test_bit(BR_FDB_STATIC, &fdb->flags))
|
||||
return NUD_NOARP;
|
||||
else if (has_expired(br, fdb))
|
||||
return NUD_STALE;
|
||||
|
|
@ -650,9 +658,9 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
|
|||
|
||||
if (fdb->offloaded)
|
||||
ndm->ndm_flags |= NTF_OFFLOADED;
|
||||
if (fdb->added_by_external_learn)
|
||||
if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
|
||||
ndm->ndm_flags |= NTF_EXT_LEARNED;
|
||||
if (fdb->is_sticky)
|
||||
if (test_bit(BR_FDB_STICKY, &fdb->flags))
|
||||
ndm->ndm_flags |= NTF_STICKY;
|
||||
|
||||
if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.addr))
|
||||
|
|
@ -799,7 +807,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
|
|||
const u8 *addr, u16 state, u16 flags, u16 vid,
|
||||
u8 ndm_flags)
|
||||
{
|
||||
u8 is_sticky = !!(ndm_flags & NTF_STICKY);
|
||||
bool is_sticky = !!(ndm_flags & NTF_STICKY);
|
||||
struct net_bridge_fdb_entry *fdb;
|
||||
bool modified = false;
|
||||
|
||||
|
|
@ -840,34 +848,28 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
|
|||
|
||||
if (fdb_to_nud(br, fdb) != state) {
|
||||
if (state & NUD_PERMANENT) {
|
||||
fdb->is_local = 1;
|
||||
if (!fdb->is_static) {
|
||||
fdb->is_static = 1;
|
||||
set_bit(BR_FDB_LOCAL, &fdb->flags);
|
||||
if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
|
||||
fdb_add_hw_addr(br, addr);
|
||||
}
|
||||
} else if (state & NUD_NOARP) {
|
||||
fdb->is_local = 0;
|
||||
if (!fdb->is_static) {
|
||||
fdb->is_static = 1;
|
||||
clear_bit(BR_FDB_LOCAL, &fdb->flags);
|
||||
if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
|
||||
fdb_add_hw_addr(br, addr);
|
||||
}
|
||||
} else {
|
||||
fdb->is_local = 0;
|
||||
if (fdb->is_static) {
|
||||
fdb->is_static = 0;
|
||||
clear_bit(BR_FDB_LOCAL, &fdb->flags);
|
||||
if (test_and_clear_bit(BR_FDB_STATIC, &fdb->flags))
|
||||
fdb_del_hw_addr(br, addr);
|
||||
}
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (is_sticky != fdb->is_sticky) {
|
||||
fdb->is_sticky = is_sticky;
|
||||
if (is_sticky != test_bit(BR_FDB_STICKY, &fdb->flags)) {
|
||||
change_bit(BR_FDB_STICKY, &fdb->flags);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
fdb->added_by_user = 1;
|
||||
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
|
||||
|
||||
fdb->used = jiffies;
|
||||
if (modified) {
|
||||
|
|
@ -1064,7 +1066,7 @@ int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
|
|||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
|
||||
/* We only care for static entries */
|
||||
if (!f->is_static)
|
||||
if (!test_bit(BR_FDB_STATIC, &f->flags))
|
||||
continue;
|
||||
err = dev_uc_add(p->dev, f->key.addr.addr);
|
||||
if (err)
|
||||
|
|
@ -1078,7 +1080,7 @@ done:
|
|||
rollback:
|
||||
hlist_for_each_entry_rcu(tmp, &br->fdb_list, fdb_node) {
|
||||
/* We only care for static entries */
|
||||
if (!tmp->is_static)
|
||||
if (!test_bit(BR_FDB_STATIC, &tmp->flags))
|
||||
continue;
|
||||
if (tmp == f)
|
||||
break;
|
||||
|
|
@ -1097,7 +1099,7 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
|
|||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
|
||||
/* We only care for static entries */
|
||||
if (!f->is_static)
|
||||
if (!test_bit(BR_FDB_STATIC, &f->flags))
|
||||
continue;
|
||||
|
||||
dev_uc_del(p->dev, f->key.addr.addr);
|
||||
|
|
@ -1125,8 +1127,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
|
|||
goto err_unlock;
|
||||
}
|
||||
if (swdev_notify)
|
||||
fdb->added_by_user = 1;
|
||||
fdb->added_by_external_learn = 1;
|
||||
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
|
||||
set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags);
|
||||
fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
|
||||
} else {
|
||||
fdb->updated = jiffies;
|
||||
|
|
@ -1136,17 +1138,15 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
|
|||
modified = true;
|
||||
}
|
||||
|
||||
if (fdb->added_by_external_learn) {
|
||||
if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) {
|
||||
/* Refresh entry */
|
||||
fdb->used = jiffies;
|
||||
} else if (!fdb->added_by_user) {
|
||||
/* Take over SW learned entry */
|
||||
fdb->added_by_external_learn = 1;
|
||||
} else {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (swdev_notify)
|
||||
fdb->added_by_user = 1;
|
||||
set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
|
||||
|
||||
if (modified)
|
||||
fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
|
||||
|
|
@ -1168,7 +1168,7 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
|
|||
spin_lock_bh(&br->hash_lock);
|
||||
|
||||
fdb = br_fdb_find(br, addr, vid);
|
||||
if (fdb && fdb->added_by_external_learn)
|
||||
if (fdb && test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
|
||||
fdb_delete(br, fdb, swdev_notify);
|
||||
else
|
||||
err = -ENOENT;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
|
|||
if (dst) {
|
||||
unsigned long now = jiffies;
|
||||
|
||||
if (dst->is_local)
|
||||
if (test_bit(BR_FDB_LOCAL, &dst->flags))
|
||||
return br_pass_frame_up(skb);
|
||||
|
||||
if (now != dst->used)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,15 @@ struct net_bridge_vlan_group {
|
|||
u16 pvid;
|
||||
};
|
||||
|
||||
/* bridge fdb flags */
|
||||
enum {
|
||||
BR_FDB_LOCAL,
|
||||
BR_FDB_STATIC,
|
||||
BR_FDB_STICKY,
|
||||
BR_FDB_ADDED_BY_USER,
|
||||
BR_FDB_ADDED_BY_EXT_LEARN,
|
||||
};
|
||||
|
||||
struct net_bridge_fdb_key {
|
||||
mac_addr addr;
|
||||
u16 vlan_id;
|
||||
|
|
@ -183,12 +192,8 @@ struct net_bridge_fdb_entry {
|
|||
|
||||
struct net_bridge_fdb_key key;
|
||||
struct hlist_node fdb_node;
|
||||
unsigned char is_local:1,
|
||||
is_static:1,
|
||||
is_sticky:1,
|
||||
added_by_user:1,
|
||||
added_by_external_learn:1,
|
||||
offloaded:1;
|
||||
unsigned long flags;
|
||||
unsigned char offloaded:1;
|
||||
|
||||
/* write-heavy members should not affect lookups */
|
||||
unsigned long updated ____cacheline_aligned_in_smp;
|
||||
|
|
|
|||
|
|
@ -129,14 +129,16 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
|
|||
br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
|
||||
fdb->key.vlan_id,
|
||||
fdb->dst->dev,
|
||||
fdb->added_by_user,
|
||||
test_bit(BR_FDB_ADDED_BY_USER,
|
||||
&fdb->flags),
|
||||
fdb->offloaded);
|
||||
break;
|
||||
case RTM_NEWNEIGH:
|
||||
br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
|
||||
fdb->key.vlan_id,
|
||||
fdb->dst->dev,
|
||||
fdb->added_by_user,
|
||||
test_bit(BR_FDB_ADDED_BY_USER,
|
||||
&fdb->flags),
|
||||
fdb->offloaded);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue