mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge android11-5.4.254+ (91f7025) into msm-5.4
* remotes/origin/tmp-91f7025:
UPSTREAM: arm64: efi: Make efi_rt_lock a raw_spinlock
UPSTREAM: net: sched: sch_qfq: Fix UAF in qfq_dequeue()
UPSTREAM: net/sched: sch_hfsc: Ensure inner classes have fsc curve
UPSTREAM: net/sched: sch_qfq: account for stab overhead in qfq_enqueue
UPSTREAM: netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
UPSTREAM: af_unix: Fix null-ptr-deref in unix_stream_sendpage().
BACKPORT: net: nfc: Fix use-after-free caused by nfc_llcp_find_local
Linux 5.4.254
sch_netem: fix issues in netem_change() vs get_dist_table()
alpha: remove __init annotation from exported page_is_ram()
scsi: core: Fix possible memory leak if device_add() fails
scsi: snic: Fix possible memory leak if device_add() fails
scsi: 53c700: Check that command slot is not NULL
scsi: storvsc: Fix handling of virtual Fibre Channel timeouts
scsi: core: Fix legacy /proc parsing buffer overflow
netfilter: nf_tables: report use refcount overflow
nvme-rdma: fix potential unbalanced freeze & unfreeze
nvme-tcp: fix potential unbalanced freeze & unfreeze
btrfs: set cache_block_group_error if we find an error
btrfs: don't stop integrity writeback too early
ibmvnic: Handle DMA unmapping of login buffs in release functions
net/mlx5: Allow 0 for total host VFs
dmaengine: mcf-edma: Fix a potential un-allocated memory access
wifi: cfg80211: fix sband iftype data lookup for AP_VLAN
IB/hfi1: Fix possible panic during hotplug remove
drivers: net: prevent tun_build_skb() to exceed the packet size limit
dccp: fix data-race around dp->dccps_mss_cache
bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves
net/packet: annotate data-races around tp->status
mISDN: Update parameter type of dsp_cmx_send()
selftests/rseq: Fix build with undefined __weak
drm/nouveau/disp: Revert a NULL check inside nouveau_connector_get_modes
x86: Move gds_ucode_mitigated() declaration to header
x86/mm: Fix VDSO and VVAR placement on 5-level paging machines
x86/cpu/amd: Enable Zenbleed fix for AMD Custom APU 0405
usb: common: usb-conn-gpio: Prevent bailing out if initial role is none
usb: dwc3: Properly handle processing of pending events
usb-storage: alauda: Fix uninit-value in alauda_check_media()
binder: fix memory leak in binder_init()
iio: cros_ec: Fix the allocation size for cros_ec_command
nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput
x86/pkeys: Revert a5eff72597 ("x86/pkeys: Add PKRU value to init_fpstate")
radix tree test suite: fix incorrect allocation size for pthreads
drm/nouveau/gr: enable memory loads on helper invocation on all channels
dmaengine: pl330: Return DMA_PAUSED when transaction is paused
ipv6: adjust ndisc_is_useropt() to also return true for PIO
mmc: moxart: read scr register without changing byte order
Linux 5.4.253
Revert "driver core: Annotate dev_err_probe() with __must_check"
drivers: core: fix kernel-doc markup for dev_err_probe()
driver code: print symbolic error code
driver core: Annotate dev_err_probe() with __must_check
ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node
ARM: dts: imx6sll: fixup of operating points
ARM: dts: imx: add usb alias
ARM: dts: imx: Align L2 cache-controller nodename with dtschema
ARM: dts: imx6sll: Make ssi node name same as other platforms
arm64: dts: stratix10: fix incorrect I2C property for SCL signal
ceph: defer stopping mdsc delayed_work
ceph: use kill_anon_super helper
ceph: show tasks waiting on caps in debugfs caps file
PM: sleep: wakeirq: fix wake irq arming
PM / wakeirq: support enabling wake-up irq after runtime_suspend called
selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
selftests/rseq: check if libc rseq support is registered
powerpc/mm/altmap: Fix altmap boundary check
mtd: rawnand: omap_elm: Fix incorrect type in assignment
test_firmware: return ENOMEM instead of ENOSPC on failed memory allocation
test_firmware: prevent race conditions by a correct implementation of locking
ext2: Drop fragment support
fs: Protect reconfiguration of sb read-write from racing writes
net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb
Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb
fs/sysv: Null check to prevent null-ptr-deref bug
net: tap_open(): set sk_uid from current_fsuid()
net: tun_chr_open(): set sk_uid from current_fsuid()
mtd: rawnand: meson: fix OOB available bytes for ECC
mtd: spinand: toshiba: Fix ecc_get_status
USB: zaurus: Add ID for A-300/B-500/C-700
libceph: fix potential hang in ceph_osdc_notify()
scsi: zfcp: Defer fc_rport blocking until after ADISC response
tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen
tcp_metrics: annotate data-races around tm->tcpm_net
tcp_metrics: annotate data-races around tm->tcpm_vals[]
tcp_metrics: annotate data-races around tm->tcpm_lock
tcp_metrics: annotate data-races around tm->tcpm_stamp
tcp_metrics: fix addr_same() helper
ip6mr: Fix skb_under_panic in ip6mr_cache_report()
net: dcb: choose correct policy to parse DCB_ATTR_BCN
net: ll_temac: fix error checking of irq_of_parse_and_map()
net: ll_temac: Switch to use dev_err_probe() helper
driver core: add device probe log helper
bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire
net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free
net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free
net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after-free
net: add missing data-race annotation for sk_ll_usec
net: add missing data-race annotations around sk->sk_peek_off
net: add missing READ_ONCE(sk->sk_rcvbuf) annotation
net: add missing READ_ONCE(sk->sk_sndbuf) annotation
net: add missing READ_ONCE(sk->sk_rcvlowat) annotation
net: annotate data-races around sk->sk_max_pacing_rate
mISDN: hfcpci: Fix potential deadlock on &hc->lock
net: sched: cls_u32: Fix match key mis-addressing
perf test uprobe_from_different_cu: Skip if there is no gcc
rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length
net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer()
net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx
KVM: s390: fix sthyi error handling
word-at-a-time: use the same return type for has_zero regardless of endianness
loop: Select I/O scheduler 'none' from inside add_disk()
perf: Fix function pointer case
arm64: Fix bit-shifting UB in the MIDR_CPU_MODEL() macro
arm64: Add AMPERE1 to the Spectre-BHB affected list
ASoC: cs42l51: fix driver to properly autoload with automatic module loading
net/sched: sch_qfq: account for stab overhead in qfq_enqueue
btrfs: fix race between quota disable and quota assign ioctls
btrfs: qgroup: return ENOTCONN instead of EINVAL when quotas are not enabled
btrfs: qgroup: remove one-time use variables for quota_root checks
cpufreq: intel_pstate: Drop ACPI _PSS states table patching
ACPI: processor: perflib: Avoid updating frequency QoS unnecessarily
ACPI: processor: perflib: Use the "no limit" frequency QoS
dm cache policy smq: ensure IO doesn't prevent cleaner policy progress
ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register
s390/dasd: fix hanging device after quiesce/resume
virtio-net: fix race between set queues and probe
btrfs: check if the transaction was aborted at btrfs_wait_for_commit()
irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
tpm_tis: Explicitly check for error code
btrfs: check for commit error at btrfs_attach_transaction_barrier()
hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext()
Documentation: security-bugs.rst: clarify CVE handling
Documentation: security-bugs.rst: update preferences when dealing with the linux-distros group
Revert "usb: xhci: tegra: Fix error check"
usb: xhci-mtk: set the dma max_seg_size
USB: quirks: add quirk for Focusrite Scarlett
usb: ohci-at91: Fix the unhandle interrupt when resume
usb: dwc3: don't reset device side if dwc3 was configured as host-only
usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy
Revert "usb: dwc3: core: Enable AutoRetry feature in the controller"
can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED
USB: serial: simple: sort driver entries
USB: serial: simple: add Kaufmann RKS+CAN VCP
USB: serial: option: add Quectel EC200A module support
USB: serial: option: support Quectel EM060K_128
serial: sifive: Fix sifive_serial_console_setup() section
serial: 8250_dw: Preserve original value of DLF register
tracing: Fix warning in trace_buffered_event_disable()
ring-buffer: Fix wrong stat of cpu_buffer->read
ata: pata_ns87415: mark ns87560_tf_read static
dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
block: Fix a source code comment in include/uapi/linux/blkzoned.h
ASoC: fsl_spdif: Silence output on stop
drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
drm/msm/adreno: Fix snapshot BINDLESS_DATA size
drm/msm/dpu: drop enum dpu_core_perf_data_bus_id
RDMA/mlx4: Make check for invalid flags stricter
benet: fix return value check in be_lancer_xmit_workarounds()
net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64
net/sched: mqprio: add extack to mqprio_parse_nlattr()
net/sched: mqprio: refactor nlattr parsing to a separate function
platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100
team: reset team's flags when down link is P2P device
bonding: reset bond's flags when down link is P2P device
tcp: Reduce chance of collisions in inet6_hashfn().
ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new temporary address
ethernet: atheros: fix return value check in atl1e_tso_csum()
phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe()
vxlan: calculate correct header length for GPE
i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir()
ext4: fix to check return value of freeze_bdev() in ext4_shutdown()
keys: Fix linking a duplicate key to a keyring's assoc_array
uapi: General notification queue definitions
scsi: qla2xxx: Array index may go out of bound
scsi: qla2xxx: Fix inconsistent format argument type in qla_os.c
pwm: meson: fix handling of period/duty if greater than UINT_MAX
pwm: meson: Simplify duplicated per-channel tracking
pwm: meson: Remove redundant assignment to variable fin_freq
ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()
ftrace: Store the order of pages allocated in ftrace_page
ftrace: Check if pages were allocated before calling free_pages()
ftrace: Add information on number of page groups allocated
fs: dlm: interrupt posix locks only when process is killed
dlm: rearrange async condition return
dlm: cleanup plock_op vs plock_xop
PCI/ASPM: Avoid link retraining race
PCI/ASPM: Factor out pcie_wait_for_retrain()
PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link()
ext4: Fix reusing stale buffer heads from last failed mounting
ext4: rename journal_dev to s_journal_dev inside ext4_sb_info
btrfs: fix extent buffer leak after tree mod log failure at split_node()
btrfs: fix race between quota disable and relocation
btrfs: qgroup: catch reserved space leaks at unmount time
bcache: Fix __bch_btree_node_alloc to make the failure behavior consistent
bcache: remove 'int n' from parameter list of bch_bucket_alloc_set()
gpio: tps68470: Make tps68470_gpio_output() always set the initial value
jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint
jbd2: recheck chechpointing non-dirty buffer
jbd2: remove redundant buffer io error checks
jbd2: fix kernel-doc markups
jbd2: fix incorrect code style
Linux 5.4.252
x86: fix backwards merge of GDS/SRSO bit
xen/netback: Fix buffer overrun triggered by unusual packet
x86/cpu, kvm: Add support for CPUID_80000021_EAX
x86/bugs: Increase the x86 bugs vector size to two u32s
tools headers cpufeatures: Sync with the kernel sources
x86/cpufeatures: Assign dedicated feature word for CPUID_0x8000001F[EAX]
x86/cpu: Add VM page flush MSR availablility as a CPUID feature
x86/cpufeatures: Add SEV-ES CPU feature
Documentation/x86: Fix backwards on/off logic about YMM support
x86/mm: Initialize text poking earlier
mm: Move mm_cachep initialization to mm_init()
x86/mm: Use mm_alloc() in poking_init()
x86/mm: fix poking_init() for Xen PV guests
x86/xen: Fix secondary processors' FPU initialization
KVM: Add GDS_NO support to KVM
x86/speculation: Add Kconfig option for GDS
x86/speculation: Add force option to GDS mitigation
x86/speculation: Add Gather Data Sampling mitigation
x86/fpu: Move FPU initialization into arch_cpu_finalize_init()
x86/fpu: Mark init functions __init
x86/fpu: Remove cpuinfo argument from init functions
init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init()
init: Invoke arch_cpu_finalize_init() earlier
init: Remove check_bugs() leftovers
um/cpu: Switch to arch_cpu_finalize_init()
sparc/cpu: Switch to arch_cpu_finalize_init()
sh/cpu: Switch to arch_cpu_finalize_init()
mips/cpu: Switch to arch_cpu_finalize_init()
m68k/cpu: Switch to arch_cpu_finalize_init()
ia64/cpu: Switch to arch_cpu_finalize_init()
ARM: cpu: Switch to arch_cpu_finalize_init()
x86/cpu: Switch to arch_cpu_finalize_init()
init: Provide arch_cpu_finalize_init()
Revert "posix-timers: Ensure timer ID search-loop limit is valid"
Revert "drm/panel: Initialise panel dev and funcs through drm_panel_init()"
Revert "drm/panel: Add and fill drm_panel type field"
Revert "drm/panel: simple: Add connector_type for innolux_at043tn24"
Revert "Revert "8250: add support for ASIX devices with a FIFO bug""
Linux 5.4.251
tracing/histograms: Return an error if we fail to add histogram to hist_vars list
tcp: annotate data-races around fastopenq.max_qlen
tcp: annotate data-races around tp->notsent_lowat
tcp: annotate data-races around rskq_defer_accept
tcp: annotate data-races around tp->linger2
net: Replace the limit of TCP_LINGER2 with TCP_FIN_TIMEOUT_MAX
tcp: annotate data-races around tp->tcp_tx_delay
netfilter: nf_tables: can't schedule in nft_chain_validate
netfilter: nf_tables: fix spurious set element insertion failure
llc: Don't drop packet from non-root netns.
fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe
Revert "tcp: avoid the lookup process failing to get sk in ehash table"
net:ipv6: check return value of pskb_trim()
iavf: Fix use-after-free in free_netdev
net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()
pinctrl: amd: Use amd_pinconf_set() for all config options
fbdev: imxfb: warn about invalid left/right margin
spi: bcm63xx: fix max prepend length
igb: Fix igb_down hung on surprise removal
wifi: iwlwifi: mvm: avoid baid size integer overflow
wifi: wext-core: Fix -Wstringop-overflow warning in ioctl_standard_iw_point()
devlink: report devlink_port_type_warn source device
bpf: Address KCSAN report on bpf_lru_list
sched/fair: Don't balance task to its current running CPU
arm64: mm: fix VA-range sanity check
posix-timers: Ensure timer ID search-loop limit is valid
md/raid10: prevent soft lockup while flush writes
md: fix data corruption for raid456 when reshape restart while grow up
nbd: Add the maximum limit of allocated index in nbd_dev_add
debugobjects: Recheck debug_objects_enabled before reporting
ext4: correct inline offset when handling xattrs in inode body
drm/client: Fix memory leak in drm_client_modeset_probe
drm/client: Fix memory leak in drm_client_target_cloned
can: bcm: Fix UAF in bcm_proc_show()
selftests: tc: set timeout to 15 minutes
fuse: revalidate: don't invalidate if interrupted
btrfs: fix warning when putting transaction with qgroups enabled after abort
perf probe: Add test for regression introduced by switch to die_get_decl_file()
drm/atomic: Fix potential use-after-free in nonblocking commits
scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue
scsi: qla2xxx: Pointer may be dereferenced
scsi: qla2xxx: Correct the index of array
scsi: qla2xxx: Check valid rport returned by fc_bsg_to_rport()
scsi: qla2xxx: Fix potential NULL pointer dereference
scsi: qla2xxx: Wait for io return on terminate rport
tracing/probes: Fix not to count error code to total length
tracing: Fix null pointer dereference in tracing_err_log_open()
xtensa: ISS: fix call to split_if_spec
ring-buffer: Fix deadloop issue on reading trace_pipe
tracing/histograms: Add histograms to hist_vars if they have referenced variables
tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when iterating clk
tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in case of error
Revert "8250: add support for ASIX devices with a FIFO bug"
meson saradc: fix clock divider mask length
ceph: don't let check_caps skip sending responses for revoke msgs
hwrng: imx-rngc - fix the timeout for init and self check
firmware: stratix10-svc: Fix a potential resource leak in svc_create_memory_pool()
serial: atmel: don't enable IRQs prematurely
drm/rockchip: vop: Leave vblank enabled in self-refresh
drm/atomic: Allow vblank-enabled + self-refresh "disable"
fs: dlm: return positive pid value for F_GETLK
md/raid0: add discard support for the 'original' layout
misc: pci_endpoint_test: Re-init completion for every test
misc: pci_endpoint_test: Free IRQs before removing the device
PCI: rockchip: Set address alignment for endpoint mode
PCI: rockchip: Use u32 variable to access 32-bit registers
PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core
PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked
PCI: rockchip: Write PCI Device ID to correct register
PCI: rockchip: Assert PCI Configuration Enable bit after probe
PCI: qcom: Disable write access to read only registers for IP v2.3.3
PCI: Add function 1 DMA alias quirk for Marvell 88SE9235
PCI/PM: Avoid putting EloPOS E2/S2/H2 PCIe Ports in D3cold
jfs: jfs_dmap: Validate db_l2nbperpage while mounting
ext4: only update i_reserved_data_blocks on successful block allocation
ext4: fix wrong unit use in ext4_mb_clear_bb
erofs: fix compact 4B support for 16k block size
SUNRPC: Fix UAF in svc_tcp_listen_data_ready()
misc: fastrpc: Create fastrpc scalar with correct buffer count
powerpc: Fail build if using recordmcount with binutils v2.37
net: bcmgenet: Ensure MDIO unregistration has clocks enabled
mtd: rawnand: meson: fix unaligned DMA buffers handling
tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation
pinctrl: amd: Only use special debounce behavior for GPIO 0
pinctrl: amd: Detect internal GPIO0 debounce handling
pinctrl: amd: Fix mistake in handling clearing pins at startup
net/sched: make psched_mtu() RTNL-less safe
net/sched: flower: Ensure both minimum and maximum ports are specified
cls_flower: Add extack support for src and dst port range options
wifi: airo: avoid uninitialized warning in airo_get_rate()
erofs: avoid infinite loop in z_erofs_do_read_page() when reading beyond EOF
platform/x86: wmi: Break possible infinite loop when parsing GUID
platform/x86: wmi: move variables
platform/x86: wmi: use guid_t and guid_equal()
platform/x86: wmi: remove unnecessary argument
platform/x86: wmi: Fix indentation in some cases
platform/x86: wmi: Replace UUID redefinitions by their originals
ipv6/addrconf: fix a potential refcount underflow for idev
NTB: ntb_tool: Add check for devm_kcalloc
NTB: ntb_transport: fix possible memory leak while device_register() fails
ntb: intel: Fix error handling in intel_ntb_pci_driver_init()
NTB: amd: Fix error handling in amd_ntb_pci_driver_init()
ntb: idt: Fix error handling in idt_pci_driver_init()
udp6: fix udp6_ehashfn() typo
icmp6: Fix null-ptr-deref of ip6_null_entry->rt6i_idev in icmp6_dev().
ionic: remove WARN_ON to prevent panic_on_warn
ionic: ionic_intr_free parameter change
ionic: move irq request to qcq alloc
ionic: clean irq affinity on queue deinit
ionic: improve irq numa locality
net/sched: cls_fw: Fix improper refcount update leads to use-after-free
net: mvneta: fix txq_map in case of txq_number==1
scsi: qla2xxx: Fix error code in qla2x00_start_sp()
igc: set TP bit in 'supported' and 'advertising' fields of ethtool_link_ksettings
igc: Remove delay during TX ring configuration
drm/panel: simple: Add connector_type for innolux_at043tn24
drm/panel: Add and fill drm_panel type field
drm/panel: Initialise panel dev and funcs through drm_panel_init()
workqueue: clean up WORK_* constant types, clarify masking
net: lan743x: Don't sleep in atomic context
block/partition: fix signedness issue for Amiga partitions
tty: serial: fsl_lpuart: add earlycon for imx8ulp platform
netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
netfilter: conntrack: Avoid nf_ct_helper_hash uses after free
netfilter: nf_tables: fix scheduling-while-atomic splat
netfilter: nf_tables: unbind non-anonymous set if rule construction fails
netfilter: nf_tables: reject unbound anonymous set before commit phase
netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound set/chain
netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE
netfilter: nf_tables: add rescheduling points during loop detection walks
netfilter: nf_tables: use net_generic infra for transaction data
netfilter: add helper function to set up the nfnetlink header and use it
netfilter: nftables: add helper function to set the base sequence number
netfilter: nf_tables: fix nat hook table deletion
block: add overflow checks for Amiga partition support
fanotify: disallow mount/sb marks on kernel internal pseudo fs
fs: no need to check source
ARM: orion5x: fix d2net gpio initialization
btrfs: fix race when deleting quota root from the dirty cow roots list
fs: Lock moved directories
fs: Establish locking order for unrelated directories
Revert "f2fs: fix potential corruption when moving a directory"
ext4: Remove ext4 locking of moved directory
fs: avoid empty option when generating legacy mount string
jffs2: reduce stack usage in jffs2_build_xattr_subsystem()
integrity: Fix possible multiple allocation in integrity_inode_get()
bcache: Remove unnecessary NULL point check in node allocations
mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is used.
mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M
mmc: core: disable TRIM on Kingston EMMC04G-M627
NFSD: add encoding of op_recall flag for write delegation
ALSA: jack: Fix mutex call in snd_jack_report()
i2c: xiic: Don't try to handle more interrupt events after error
i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process()
sh: dma: Fix DMA channel offset calculation
net: dsa: tag_sja1105: fix MAC DA patching from meta frames
net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX
xsk: Honor SO_BINDTODEVICE on bind
xsk: Improve documentation for AF_XDP
tcp: annotate data races in __tcp_oow_rate_limited()
net: bridge: keep ports without IFF_UNICAST_FLT in BR_PROMISC mode
powerpc: allow PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y
f2fs: fix error path handling in truncate_dnode()
mailbox: ti-msgmgr: Fill non-message tx data fields with 0x0
spi: bcm-qspi: return error if neither hif_mspi nor mspi is available
Add MODULE_FIRMWARE() for FIRMWARE_TG357766.
sctp: fix potential deadlock on &net->sctp.addr_wq_lock
rtc: st-lpc: Release some resources in st_rtc_probe() in case of error
pwm: sysfs: Do not apply state to already disabled PWMs
pwm: imx-tpm: force 'real_period' to be zero in suspend
mfd: stmpe: Only disable the regulators if they are enabled
KVM: s390: vsie: fix the length of APCB bitmap
mfd: stmfx: Fix error path in stmfx_chip_init
serial: 8250_omap: Use force_suspend and resume for system suspend
mfd: intel-lpss: Add missing check for platform_get_resource
usb: dwc3: qcom: Release the correct resources in dwc3_qcom_remove()
KVM: s390: fix KVM_S390_GET_CMMA_BITS for GFNs in memslot holes
mfd: rt5033: Drop rt5033-battery sub-device
usb: hide unused usbfs_notify_suspend/resume functions
usb: phy: phy-tahvo: fix memory leak in tahvo_usb_probe()
extcon: Fix kernel doc of property capability fields to avoid warnings
extcon: Fix kernel doc of property fields to avoid warnings
usb: dwc3: qcom: Fix potential memory leak
media: usb: siano: Fix warning due to null work_func_t function pointer
media: videodev2.h: Fix struct v4l2_input tuner index comment
media: usb: Check az6007_read() return value
sh: j2: Use ioremap() to translate device tree address into kernel memory
w1: fix loop in w1_fini()
block: change all __u32 annotations to __be32 in affs_hardblocks.h
block: fix signed int overflow in Amiga partition support
usb: dwc3: gadget: Propagate core init errors to UDC during pullup
USB: serial: option: add LARA-R6 01B PIDs
hwrng: st - keep clock enabled while hwrng is registered
hwrng: st - Fix W=1 unused variable warning
NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION
ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard
modpost: fix off by one in is_executable_section()
crypto: marvell/cesa - Fix type mismatch warning
modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
modpost: fix section mismatch message for R_ARM_ABS32
crypto: nx - fix build warnings when DEBUG_FS is not enabled
hwrng: virtio - Fix race on data_avail and actual data
hwrng: virtio - always add a pending request
hwrng: virtio - don't waste entropy
hwrng: virtio - don't wait on cleanup
hwrng: virtio - add an internal buffer
powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross-boundary
pinctrl: at91-pio4: check return value of devm_kasprintf()
perf dwarf-aux: Fix off-by-one in die_get_varname()
pinctrl: cherryview: Return correct value if pin in push-pull mode
PCI: Add pci_clear_master() stub for non-CONFIG_PCI
PCI: ftpci100: Release the clock resources
PCI: pciehp: Cancel bringup sequence if card is not present
scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe()
PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free
scsi: qedf: Fix NULL dereference in error handling
ASoC: imx-audmix: check return value of devm_kasprintf()
clk: keystone: sci-clk: check return value of kasprintf()
clk: cdce925: check return value of kasprintf()
ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer
clk: tegra: tegra124-emc: Fix potential memory leak
drm/radeon: fix possible division-by-zero errors
drm/amdkfd: Fix potential deallocation of previously deallocated memory.
fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe()
arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1
IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
soc/fsl/qe: fix usb.c build errors
ASoC: es8316: Do not set rate constraints for unsupported MCLKs
ASoC: es8316: Increment max value for ALC Capture Target Volume control
memory: brcmstb_dpfe: fix testing array offset after use
ARM: ep93xx: fix missing-prototype warnings
drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H
arm64: dts: qcom: msm8916: correct camss unit address
ARM: dts: gta04: Move model property out of pinctrl node
RDMA/bnxt_re: Fix to remove an unnecessary log
drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks`
Input: adxl34x - do not hardcode interrupt trigger type
ARM: dts: BCM5301X: Drop "clock-names" from the SPI node
Input: drv260x - sleep between polling GO bit
radeon: avoid double free in ci_dpm_init()
netlink: Add __sock_i_ino() for __netlink_diag_dump().
ipvlan: Fix return value of ipvlan_queue_xmit()
netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return value.
netfilter: conntrack: dccp: copy entire header to stack buffer, not just basic one
lib/ts_bm: reset initial match offset for every block of text
net: nfc: Fix use-after-free caused by nfc_llcp_find_local
nfc: llcp: simplify llcp_sock_connect() error paths
gtp: Fix use-after-free in __gtp_encap_destroy().
selftests: rtnetlink: remove netdevsim device after ipsec offload test
netlink: do not hard code device address lenth in fdb dumps
netlink: fix potential deadlock in netlink_set_err()
wifi: ath9k: convert msecs to jiffies where needed
wifi: cfg80211: rewrite merging of inherited elements
wifi: iwlwifi: pull from TXQs with softirqs disabled
rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key()
memstick r592: make memstick_debug_get_tpc_name() static
kexec: fix a memory leak in crash_shrink_memory()
watchdog/perf: more properly prevent false positives with turbo modes
watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct config
wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes
wifi: ray_cs: Fix an error handling path in ray_probe()
wifi: ray_cs: Drop useless status variable in parse_addr()
wifi: ray_cs: Utilize strnlen() in parse_addr()
wifi: wl3501_cs: Fix an error handling path in wl3501_probe()
wl3501_cs: use eth_hw_addr_set()
net: create netdev->dev_addr assignment helpers
wl3501_cs: Fix misspelling and provide missing documentation
wl3501_cs: Remove unnecessary NULL check
wl3501_cs: Fix a bunch of formatting issues related to function docs
wifi: atmel: Fix an error handling path in atmel_probe()
wifi: orinoco: Fix an error handling path in orinoco_cs_probe()
wifi: orinoco: Fix an error handling path in spectrum_cs_probe()
regulator: core: Streamline debugfs operations
regulator: core: Fix more error checking for debugfs_create_dir()
nfc: llcp: fix possible use of uninitialized variable in nfc_llcp_send_connect()
nfc: constify several pointers to u8, char and sk_buff
wifi: mwifiex: Fix the size of a memory allocation in mwifiex_ret_802_11_scan()
spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG
samples/bpf: Fix buffer overflow in tcp_basertt
wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx
wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation
ima: Fix build warnings
pstore/ram: Add check for kstrdup
evm: Complete description of evm_inode_setattr()
ARM: 9303/1: kprobes: avoid missing-declaration warnings
powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
PM: domains: fix integer overflow issues in genpd_parse_state()
clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe
clocksource/drivers/cadence-ttc: Use ttc driver as platform driver
tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode().
irqchip/jcore-aic: Fix missing allocation of IRQ descriptors
irqchip/jcore-aic: Kill use of irq_create_strict_mappings()
md/raid10: fix io loss while replacement replace rdev
md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request
md/raid10: fix wrong setting of max_corr_read_errors
md/raid10: fix overflow of md/safe_mode_delay
md/raid10: check slab-out-of-bounds in md_bitmap_get_counter
x86/resctrl: Only show tasks' pid in current pid namespace
x86/resctrl: Use is_closid_match() in more places
bgmac: fix *initial* chip reset to support BCM5358
drm/amdgpu: Validate VM ioctl flags.
scripts/tags.sh: Resolve gtags empty index generation
drm/i915: Initialise outparam for error return from wait_for_register
HID: wacom: Use ktime_t rather than int when dealing with timestamps
fbdev: imsttfb: Fix use after free bug in imsttfb_probe
video: imsttfb: check for ioremap() failures
x86/smp: Use dedicated cache-line for mwait_play_dead()
gfs2: Don't deref jdesc in evict
Linux 5.4.250
x86/cpu/amd: Add a Zenbleed fix
x86/cpu/amd: Move the errata checking functionality up
x86/microcode/AMD: Load late on both threads too
Conflict:
drivers/usb/dwc3/gadget.c
Change-Id: Ibfc470316e278f29831f47d6c76bade3f8514073
Signed-off-by: kamasali Satyanarayan <[email protected]>
This commit is contained in:
commit
36579e50d8
522 changed files with 5426 additions and 3047 deletions
|
|
@ -157,8 +157,9 @@ void br_manage_promisc(struct net_bridge *br)
|
|||
* This lets us disable promiscuous mode and write
|
||||
* this config to hw.
|
||||
*/
|
||||
if (br->auto_cnt == 0 ||
|
||||
(br->auto_cnt == 1 && br_auto_port(p)))
|
||||
if ((p->dev->priv_flags & IFF_UNICAST_FLT) &&
|
||||
(br->auto_cnt == 0 ||
|
||||
(br->auto_cnt == 1 && br_auto_port(p))))
|
||||
br_port_clear_promisc(p);
|
||||
else
|
||||
br_port_set_promisc(p);
|
||||
|
|
|
|||
|
|
@ -1523,6 +1523,12 @@ static int bcm_release(struct socket *sock)
|
|||
|
||||
lock_sock(sk);
|
||||
|
||||
#if IS_ENABLED(CONFIG_PROC_FS)
|
||||
/* remove procfs entry */
|
||||
if (net->can.bcmproc_dir && bo->bcm_proc_read)
|
||||
remove_proc_entry(bo->procname, net->can.bcmproc_dir);
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
list_for_each_entry_safe(op, next, &bo->tx_ops, list)
|
||||
bcm_remove_op(op);
|
||||
|
||||
|
|
@ -1558,12 +1564,6 @@ static int bcm_release(struct socket *sock)
|
|||
list_for_each_entry_safe(op, next, &bo->rx_ops, list)
|
||||
bcm_remove_op(op);
|
||||
|
||||
#if IS_ENABLED(CONFIG_PROC_FS)
|
||||
/* remove procfs entry */
|
||||
if (net->can.bcmproc_dir && bo->bcm_proc_read)
|
||||
remove_proc_entry(bo->procname, net->can.bcmproc_dir);
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
/* remove device reference */
|
||||
if (bo->bound) {
|
||||
bo->bound = 0;
|
||||
|
|
|
|||
|
|
@ -3249,17 +3249,24 @@ static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq)
|
|||
int ret;
|
||||
|
||||
dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
|
||||
ret = wait_for_completion_interruptible(&lreq->reg_commit_wait);
|
||||
ret = wait_for_completion_killable(&lreq->reg_commit_wait);
|
||||
return ret ?: lreq->reg_commit_error;
|
||||
}
|
||||
|
||||
static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq)
|
||||
static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq,
|
||||
unsigned long timeout)
|
||||
{
|
||||
int ret;
|
||||
long left;
|
||||
|
||||
dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
|
||||
ret = wait_for_completion_interruptible(&lreq->notify_finish_wait);
|
||||
return ret ?: lreq->notify_finish_error;
|
||||
left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait,
|
||||
ceph_timeout_jiffies(timeout));
|
||||
if (left <= 0)
|
||||
left = left ?: -ETIMEDOUT;
|
||||
else
|
||||
left = lreq->notify_finish_error; /* completed */
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4875,7 +4882,8 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc,
|
|||
linger_submit(lreq);
|
||||
ret = linger_reg_commit_wait(lreq);
|
||||
if (!ret)
|
||||
ret = linger_notify_finish_wait(lreq);
|
||||
ret = linger_notify_finish_wait(lreq,
|
||||
msecs_to_jiffies(2 * timeout * MSEC_PER_SEC));
|
||||
else
|
||||
dout("lreq %p failed to initiate notify %d\n", lreq, ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -6299,7 +6299,10 @@ EXPORT_SYMBOL_GPL(devlink_free);
|
|||
|
||||
static void devlink_port_type_warn(struct work_struct *work)
|
||||
{
|
||||
WARN(true, "Type was not set for devlink port.");
|
||||
struct devlink_port *port = container_of(to_delayed_work(work),
|
||||
struct devlink_port,
|
||||
type_warn_dw);
|
||||
dev_warn(port->devlink->dev, "Type was not set for devlink port.");
|
||||
}
|
||||
|
||||
static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
|
||||
|
|
|
|||
|
|
@ -922,24 +922,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
|
|||
nla_total_size(sizeof(struct ifla_vf_rate)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_link_state)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
|
||||
nla_total_size(0) + /* nest IFLA_VF_STATS */
|
||||
/* IFLA_VF_STATS_RX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_BROADCAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_MULTICAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_trust)));
|
||||
if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
|
||||
size += num_vfs *
|
||||
(nla_total_size(0) + /* nest IFLA_VF_STATS */
|
||||
/* IFLA_VF_STATS_RX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_BROADCAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_MULTICAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)));
|
||||
}
|
||||
return size;
|
||||
} else
|
||||
return 0;
|
||||
|
|
@ -1189,7 +1192,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
|
|||
static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
int vfs_num,
|
||||
struct nlattr *vfinfo)
|
||||
struct nlattr *vfinfo,
|
||||
u32 ext_filter_mask)
|
||||
{
|
||||
struct ifla_vf_rss_query_en vf_rss_query_en;
|
||||
struct nlattr *vf, *vfstats, *vfvlanlist;
|
||||
|
|
@ -1279,33 +1283,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
|||
goto nla_put_vf_failure;
|
||||
}
|
||||
nla_nest_end(skb, vfvlanlist);
|
||||
memset(&vf_stats, 0, sizeof(vf_stats));
|
||||
if (dev->netdev_ops->ndo_get_vf_stats)
|
||||
dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
|
||||
&vf_stats);
|
||||
vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
|
||||
if (!vfstats)
|
||||
goto nla_put_vf_failure;
|
||||
if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
|
||||
vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
|
||||
vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
|
||||
vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
|
||||
vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
|
||||
vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
|
||||
vf_stats.multicast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
|
||||
vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
|
||||
vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
|
||||
nla_nest_cancel(skb, vfstats);
|
||||
goto nla_put_vf_failure;
|
||||
if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
|
||||
memset(&vf_stats, 0, sizeof(vf_stats));
|
||||
if (dev->netdev_ops->ndo_get_vf_stats)
|
||||
dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
|
||||
&vf_stats);
|
||||
vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
|
||||
if (!vfstats)
|
||||
goto nla_put_vf_failure;
|
||||
if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
|
||||
vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
|
||||
vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
|
||||
vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
|
||||
vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
|
||||
vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
|
||||
vf_stats.multicast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
|
||||
vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
|
||||
vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
|
||||
nla_nest_cancel(skb, vfstats);
|
||||
goto nla_put_vf_failure;
|
||||
}
|
||||
nla_nest_end(skb, vfstats);
|
||||
}
|
||||
nla_nest_end(skb, vfstats);
|
||||
nla_nest_end(skb, vf);
|
||||
return 0;
|
||||
|
||||
|
|
@ -1338,7 +1344,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
|
|||
return -EMSGSIZE;
|
||||
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
|
||||
if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask))
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
|
|
@ -3580,7 +3586,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
|
|||
ndm->ndm_ifindex = dev->ifindex;
|
||||
ndm->ndm_state = ndm_state;
|
||||
|
||||
if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
|
||||
if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr))
|
||||
goto nla_put_failure;
|
||||
if (vid)
|
||||
if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid))
|
||||
|
|
@ -3594,10 +3600,10 @@ nla_put_failure:
|
|||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static inline size_t rtnl_fdb_nlmsg_size(void)
|
||||
static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev)
|
||||
{
|
||||
return NLMSG_ALIGN(sizeof(struct ndmsg)) +
|
||||
nla_total_size(ETH_ALEN) + /* NDA_LLADDR */
|
||||
nla_total_size(dev->addr_len) + /* NDA_LLADDR */
|
||||
nla_total_size(sizeof(u16)) + /* NDA_VLAN */
|
||||
0;
|
||||
}
|
||||
|
|
@ -3609,7 +3615,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type,
|
|||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
|
||||
skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
|
||||
skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC);
|
||||
if (!skb)
|
||||
goto errout;
|
||||
|
||||
|
|
@ -4584,13 +4590,17 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
||||
if (br_spec) {
|
||||
nla_for_each_nested(attr, br_spec, rem) {
|
||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) {
|
||||
if (nla_len(attr) < sizeof(flags))
|
||||
return -EINVAL;
|
||||
|
||||
have_flags = true;
|
||||
flags = nla_get_u16(attr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (nla_type(attr) == IFLA_BRIDGE_MODE) {
|
||||
if (nla_len(attr) < sizeof(u16))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,8 @@ set_rcvbuf:
|
|||
cmpxchg(&sk->sk_pacing_status,
|
||||
SK_PACING_NONE,
|
||||
SK_PACING_NEEDED);
|
||||
sk->sk_max_pacing_rate = ulval;
|
||||
/* Pairs with READ_ONCE() from sk_getsockopt() */
|
||||
WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
|
||||
sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1258,11 +1259,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||
break;
|
||||
|
||||
case SO_SNDBUF:
|
||||
v.val = sk->sk_sndbuf;
|
||||
v.val = READ_ONCE(sk->sk_sndbuf);
|
||||
break;
|
||||
|
||||
case SO_RCVBUF:
|
||||
v.val = sk->sk_rcvbuf;
|
||||
v.val = READ_ONCE(sk->sk_rcvbuf);
|
||||
break;
|
||||
|
||||
case SO_REUSEADDR:
|
||||
|
|
@ -1350,7 +1351,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||
break;
|
||||
|
||||
case SO_RCVLOWAT:
|
||||
v.val = sk->sk_rcvlowat;
|
||||
v.val = READ_ONCE(sk->sk_rcvlowat);
|
||||
break;
|
||||
|
||||
case SO_SNDLOWAT:
|
||||
|
|
@ -1444,7 +1445,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||
if (!sock->ops->set_peek_off)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
v.val = sk->sk_peek_off;
|
||||
v.val = READ_ONCE(sk->sk_peek_off);
|
||||
break;
|
||||
case SO_NOFCS:
|
||||
v.val = sock_flag(sk, SOCK_NOFCS);
|
||||
|
|
@ -1474,17 +1475,19 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
case SO_BUSY_POLL:
|
||||
v.val = sk->sk_ll_usec;
|
||||
v.val = READ_ONCE(sk->sk_ll_usec);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SO_MAX_PACING_RATE:
|
||||
/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
|
||||
if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
|
||||
lv = sizeof(v.ulval);
|
||||
v.ulval = sk->sk_max_pacing_rate;
|
||||
v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
|
||||
} else {
|
||||
/* 32bit version */
|
||||
v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
|
||||
v.val = min_t(unsigned long, ~0U,
|
||||
READ_ONCE(sk->sk_max_pacing_rate));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2090,13 +2093,24 @@ kuid_t sock_i_uid(struct sock *sk)
|
|||
}
|
||||
EXPORT_SYMBOL(sock_i_uid);
|
||||
|
||||
unsigned long __sock_i_ino(struct sock *sk)
|
||||
{
|
||||
unsigned long ino;
|
||||
|
||||
read_lock(&sk->sk_callback_lock);
|
||||
ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
|
||||
read_unlock(&sk->sk_callback_lock);
|
||||
return ino;
|
||||
}
|
||||
EXPORT_SYMBOL(__sock_i_ino);
|
||||
|
||||
unsigned long sock_i_ino(struct sock *sk)
|
||||
{
|
||||
unsigned long ino;
|
||||
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
local_bh_disable();
|
||||
ino = __sock_i_ino(sk);
|
||||
local_bh_enable();
|
||||
return ino;
|
||||
}
|
||||
EXPORT_SYMBOL(sock_i_ino);
|
||||
|
|
@ -2643,7 +2657,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim);
|
|||
|
||||
int sk_set_peek_off(struct sock *sk, int val)
|
||||
{
|
||||
sk->sk_peek_off = val;
|
||||
WRITE_ONCE(sk->sk_peek_off, val);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sk_set_peek_off);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ static void sock_map_sk_acquire(struct sock *sk)
|
|||
__acquires(&sk->sk_lock.slock)
|
||||
{
|
||||
lock_sock(sk);
|
||||
preempt_disable();
|
||||
rcu_read_lock();
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +122,6 @@ static void sock_map_sk_release(struct sock *sk)
|
|||
__releases(&sk->sk_lock.slock)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
preempt_enable();
|
||||
release_sock(sk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -946,7 +946,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested_deprecated(data, DCB_BCN_ATTR_MAX,
|
||||
tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest,
|
||||
tb[DCB_ATTR_BCN], dcbnl_bcn_nest,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
|
|||
|
||||
/* And store cached results */
|
||||
icsk->icsk_pmtu_cookie = pmtu;
|
||||
dp->dccps_mss_cache = cur_mps;
|
||||
WRITE_ONCE(dp->dccps_mss_cache, cur_mps);
|
||||
|
||||
return cur_mps;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
|
|||
return dccp_getsockopt_service(sk, len,
|
||||
(__be32 __user *)optval, optlen);
|
||||
case DCCP_SOCKOPT_GET_CUR_MPS:
|
||||
val = dp->dccps_mss_cache;
|
||||
val = READ_ONCE(dp->dccps_mss_cache);
|
||||
break;
|
||||
case DCCP_SOCKOPT_AVAILABLE_CCIDS:
|
||||
return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
|
||||
|
|
@ -766,7 +766,7 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
|
||||
trace_dccp_probe(sk, len);
|
||||
|
||||
if (len > dp->dccps_mss_cache)
|
||||
if (len > READ_ONCE(dp->dccps_mss_cache))
|
||||
return -EMSGSIZE;
|
||||
|
||||
lock_sock(sk);
|
||||
|
|
@ -799,6 +799,12 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
goto out_discard;
|
||||
}
|
||||
|
||||
/* We need to check dccps_mss_cache after socket is locked. */
|
||||
if (len > dp->dccps_mss_cache) {
|
||||
rc = -EMSGSIZE;
|
||||
goto out_discard;
|
||||
}
|
||||
|
||||
skb_reserve(skb, sk->sk_prot->max_header);
|
||||
rc = memcpy_from_msg(skb_put(skb, len), msg, len);
|
||||
if (rc != 0)
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ static void sja1105_meta_unpack(const struct sk_buff *skb,
|
|||
* a unified unpacking command for both device series.
|
||||
*/
|
||||
packing(buf, &meta->tstamp, 31, 0, 4, UNPACK, 0);
|
||||
packing(buf + 4, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
|
||||
packing(buf + 5, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
|
||||
packing(buf + 4, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
|
||||
packing(buf + 5, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
|
||||
packing(buf + 6, &meta->source_port, 7, 0, 1, UNPACK, 0);
|
||||
packing(buf + 7, &meta->switch_id, 7, 0, 1, UNPACK, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -536,20 +536,8 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
|
|||
spin_lock(lock);
|
||||
if (osk) {
|
||||
WARN_ON_ONCE(sk->sk_hash != osk->sk_hash);
|
||||
ret = sk_hashed(osk);
|
||||
if (ret) {
|
||||
/* Before deleting the node, we insert a new one to make
|
||||
* sure that the look-up-sk process would not miss either
|
||||
* of them and that at least one node would exist in ehash
|
||||
* table all the time. Otherwise there's a tiny chance
|
||||
* that lookup process could find nothing in ehash table.
|
||||
*/
|
||||
__sk_nulls_add_node_tail_rcu(sk, list);
|
||||
sk_nulls_del_node_init_rcu(osk);
|
||||
}
|
||||
goto unlock;
|
||||
}
|
||||
if (found_dup_sk) {
|
||||
ret = sk_nulls_del_node_init_rcu(osk);
|
||||
} else if (found_dup_sk) {
|
||||
*found_dup_sk = inet_ehash_lookup_by_sk(sk, list);
|
||||
if (*found_dup_sk)
|
||||
ret = false;
|
||||
|
|
@ -558,7 +546,6 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
|
|||
if (ret)
|
||||
__sk_nulls_add_node_rcu(sk, list);
|
||||
|
||||
unlock:
|
||||
spin_unlock(lock);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(inet_twsk_put);
|
||||
|
||||
static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw,
|
||||
struct hlist_nulls_head *list)
|
||||
static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw,
|
||||
struct hlist_nulls_head *list)
|
||||
{
|
||||
hlist_nulls_add_tail_rcu(&tw->tw_node, list);
|
||||
hlist_nulls_add_head_rcu(&tw->tw_node, list);
|
||||
}
|
||||
|
||||
static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
|
||||
|
|
@ -120,7 +120,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
|
|||
|
||||
spin_lock(lock);
|
||||
|
||||
inet_twsk_add_node_tail_rcu(tw, &ehead->chain);
|
||||
inet_twsk_add_node_rcu(tw, &ehead->chain);
|
||||
|
||||
/* Step 3: Remove SK from hash chain */
|
||||
if (__sk_nulls_del_node_init_rcu(sk))
|
||||
|
|
|
|||
|
|
@ -3067,18 +3067,18 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
|
|||
|
||||
case TCP_LINGER2:
|
||||
if (val < 0)
|
||||
tp->linger2 = -1;
|
||||
else if (val > net->ipv4.sysctl_tcp_fin_timeout / HZ)
|
||||
tp->linger2 = 0;
|
||||
WRITE_ONCE(tp->linger2, -1);
|
||||
else if (val > TCP_FIN_TIMEOUT_MAX / HZ)
|
||||
WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX);
|
||||
else
|
||||
tp->linger2 = val * HZ;
|
||||
WRITE_ONCE(tp->linger2, val * HZ);
|
||||
break;
|
||||
|
||||
case TCP_DEFER_ACCEPT:
|
||||
/* Translate value in seconds to number of retransmits */
|
||||
icsk->icsk_accept_queue.rskq_defer_accept =
|
||||
secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
|
||||
TCP_RTO_MAX / HZ);
|
||||
WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept,
|
||||
secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
|
||||
TCP_RTO_MAX / HZ));
|
||||
break;
|
||||
|
||||
case TCP_WINDOW_CLAMP:
|
||||
|
|
@ -3166,7 +3166,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
|
|||
err = tcp_repair_set_window(tp, optval, optlen);
|
||||
break;
|
||||
case TCP_NOTSENT_LOWAT:
|
||||
tp->notsent_lowat = val;
|
||||
WRITE_ONCE(tp->notsent_lowat, val);
|
||||
sk->sk_write_space(sk);
|
||||
break;
|
||||
case TCP_INQ:
|
||||
|
|
@ -3178,7 +3178,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
|
|||
case TCP_TX_DELAY:
|
||||
if (val)
|
||||
tcp_enable_tx_delay();
|
||||
tp->tcp_tx_delay = val;
|
||||
WRITE_ONCE(tp->tcp_tx_delay, val);
|
||||
break;
|
||||
default:
|
||||
err = -ENOPROTOOPT;
|
||||
|
|
@ -3477,13 +3477,14 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
val = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
|
||||
break;
|
||||
case TCP_LINGER2:
|
||||
val = tp->linger2;
|
||||
val = READ_ONCE(tp->linger2);
|
||||
if (val >= 0)
|
||||
val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ;
|
||||
break;
|
||||
case TCP_DEFER_ACCEPT:
|
||||
val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
|
||||
TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
|
||||
val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept);
|
||||
val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ,
|
||||
TCP_RTO_MAX / HZ);
|
||||
break;
|
||||
case TCP_WINDOW_CLAMP:
|
||||
val = tp->window_clamp;
|
||||
|
|
@ -3623,7 +3624,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
break;
|
||||
|
||||
case TCP_FASTOPEN:
|
||||
val = icsk->icsk_accept_queue.fastopenq.max_qlen;
|
||||
val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen);
|
||||
break;
|
||||
|
||||
case TCP_FASTOPEN_CONNECT:
|
||||
|
|
@ -3635,14 +3636,14 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
break;
|
||||
|
||||
case TCP_TX_DELAY:
|
||||
val = tp->tcp_tx_delay;
|
||||
val = READ_ONCE(tp->tcp_tx_delay);
|
||||
break;
|
||||
|
||||
case TCP_TIMESTAMP:
|
||||
val = tcp_time_stamp_raw() + tp->tsoffset;
|
||||
break;
|
||||
case TCP_NOTSENT_LOWAT:
|
||||
val = tp->notsent_lowat;
|
||||
val = READ_ONCE(tp->notsent_lowat);
|
||||
break;
|
||||
case TCP_INQ:
|
||||
val = tp->recvmsg_inq;
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
|
|||
static bool tcp_fastopen_queue_check(struct sock *sk)
|
||||
{
|
||||
struct fastopen_queue *fastopenq;
|
||||
int max_qlen;
|
||||
|
||||
/* Make sure the listener has enabled fastopen, and we don't
|
||||
* exceed the max # of pending TFO requests allowed before trying
|
||||
|
|
@ -324,10 +325,11 @@ static bool tcp_fastopen_queue_check(struct sock *sk)
|
|||
* temporarily vs a server not supporting Fast Open at all.
|
||||
*/
|
||||
fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq;
|
||||
if (fastopenq->max_qlen == 0)
|
||||
max_qlen = READ_ONCE(fastopenq->max_qlen);
|
||||
if (max_qlen == 0)
|
||||
return false;
|
||||
|
||||
if (fastopenq->qlen >= fastopenq->max_qlen) {
|
||||
if (fastopenq->qlen >= max_qlen) {
|
||||
struct request_sock *req1;
|
||||
spin_lock(&fastopenq->lock);
|
||||
req1 = fastopenq->rskq_rst_head;
|
||||
|
|
|
|||
|
|
@ -3446,8 +3446,11 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
|
|||
static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
|
||||
u32 *last_oow_ack_time)
|
||||
{
|
||||
if (*last_oow_ack_time) {
|
||||
s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time);
|
||||
/* Paired with the WRITE_ONCE() in this function. */
|
||||
u32 val = READ_ONCE(*last_oow_ack_time);
|
||||
|
||||
if (val) {
|
||||
s32 elapsed = (s32)(tcp_jiffies32 - val);
|
||||
|
||||
if (0 <= elapsed &&
|
||||
elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) {
|
||||
|
|
@ -3456,7 +3459,10 @@ static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
|
|||
}
|
||||
}
|
||||
|
||||
*last_oow_ack_time = tcp_jiffies32;
|
||||
/* Paired with the prior READ_ONCE() and with itself,
|
||||
* as we might be lockless.
|
||||
*/
|
||||
WRITE_ONCE(*last_oow_ack_time, tcp_jiffies32);
|
||||
|
||||
return false; /* not rate-limited: go ahead, send dupack now! */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ struct tcp_fastopen_metrics {
|
|||
|
||||
struct tcp_metrics_block {
|
||||
struct tcp_metrics_block __rcu *tcpm_next;
|
||||
possible_net_t tcpm_net;
|
||||
struct net *tcpm_net;
|
||||
struct inetpeer_addr tcpm_saddr;
|
||||
struct inetpeer_addr tcpm_daddr;
|
||||
unsigned long tcpm_stamp;
|
||||
|
|
@ -51,34 +51,38 @@ struct tcp_metrics_block {
|
|||
struct rcu_head rcu_head;
|
||||
};
|
||||
|
||||
static inline struct net *tm_net(struct tcp_metrics_block *tm)
|
||||
static inline struct net *tm_net(const struct tcp_metrics_block *tm)
|
||||
{
|
||||
return read_pnet(&tm->tcpm_net);
|
||||
/* Paired with the WRITE_ONCE() in tcpm_new() */
|
||||
return READ_ONCE(tm->tcpm_net);
|
||||
}
|
||||
|
||||
static bool tcp_metric_locked(struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx)
|
||||
{
|
||||
return tm->tcpm_lock & (1 << idx);
|
||||
/* Paired with WRITE_ONCE() in tcpm_suck_dst() */
|
||||
return READ_ONCE(tm->tcpm_lock) & (1 << idx);
|
||||
}
|
||||
|
||||
static u32 tcp_metric_get(struct tcp_metrics_block *tm,
|
||||
static u32 tcp_metric_get(const struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx)
|
||||
{
|
||||
return tm->tcpm_vals[idx];
|
||||
/* Paired with WRITE_ONCE() in tcp_metric_set() */
|
||||
return READ_ONCE(tm->tcpm_vals[idx]);
|
||||
}
|
||||
|
||||
static void tcp_metric_set(struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx,
|
||||
u32 val)
|
||||
{
|
||||
tm->tcpm_vals[idx] = val;
|
||||
/* Paired with READ_ONCE() in tcp_metric_get() */
|
||||
WRITE_ONCE(tm->tcpm_vals[idx], val);
|
||||
}
|
||||
|
||||
static bool addr_same(const struct inetpeer_addr *a,
|
||||
const struct inetpeer_addr *b)
|
||||
{
|
||||
return inetpeer_addr_cmp(a, b) == 0;
|
||||
return (a->family == b->family) && !inetpeer_addr_cmp(a, b);
|
||||
}
|
||||
|
||||
struct tcpm_hash_bucket {
|
||||
|
|
@ -89,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly;
|
|||
static unsigned int tcp_metrics_hash_log __read_mostly;
|
||||
|
||||
static DEFINE_SPINLOCK(tcp_metrics_lock);
|
||||
static DEFINE_SEQLOCK(fastopen_seqlock);
|
||||
|
||||
static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
||||
const struct dst_entry *dst,
|
||||
|
|
@ -97,7 +102,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
|||
u32 msval;
|
||||
u32 val;
|
||||
|
||||
tm->tcpm_stamp = jiffies;
|
||||
WRITE_ONCE(tm->tcpm_stamp, jiffies);
|
||||
|
||||
val = 0;
|
||||
if (dst_metric_locked(dst, RTAX_RTT))
|
||||
|
|
@ -110,30 +115,42 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
|||
val |= 1 << TCP_METRIC_CWND;
|
||||
if (dst_metric_locked(dst, RTAX_REORDERING))
|
||||
val |= 1 << TCP_METRIC_REORDERING;
|
||||
tm->tcpm_lock = val;
|
||||
/* Paired with READ_ONCE() in tcp_metric_locked() */
|
||||
WRITE_ONCE(tm->tcpm_lock, val);
|
||||
|
||||
msval = dst_metric_raw(dst, RTAX_RTT);
|
||||
tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC;
|
||||
tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC);
|
||||
|
||||
msval = dst_metric_raw(dst, RTAX_RTTVAR);
|
||||
tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC;
|
||||
tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH);
|
||||
tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND);
|
||||
tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING);
|
||||
tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC);
|
||||
tcp_metric_set(tm, TCP_METRIC_SSTHRESH,
|
||||
dst_metric_raw(dst, RTAX_SSTHRESH));
|
||||
tcp_metric_set(tm, TCP_METRIC_CWND,
|
||||
dst_metric_raw(dst, RTAX_CWND));
|
||||
tcp_metric_set(tm, TCP_METRIC_REORDERING,
|
||||
dst_metric_raw(dst, RTAX_REORDERING));
|
||||
if (fastopen_clear) {
|
||||
write_seqlock(&fastopen_seqlock);
|
||||
tm->tcpm_fastopen.mss = 0;
|
||||
tm->tcpm_fastopen.syn_loss = 0;
|
||||
tm->tcpm_fastopen.try_exp = 0;
|
||||
tm->tcpm_fastopen.cookie.exp = false;
|
||||
tm->tcpm_fastopen.cookie.len = 0;
|
||||
write_sequnlock(&fastopen_seqlock);
|
||||
}
|
||||
}
|
||||
|
||||
#define TCP_METRICS_TIMEOUT (60 * 60 * HZ)
|
||||
|
||||
static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
|
||||
static void tcpm_check_stamp(struct tcp_metrics_block *tm,
|
||||
const struct dst_entry *dst)
|
||||
{
|
||||
if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
|
||||
unsigned long limit;
|
||||
|
||||
if (!tm)
|
||||
return;
|
||||
limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT;
|
||||
if (unlikely(time_after(jiffies, limit)))
|
||||
tcpm_suck_dst(tm, dst, false);
|
||||
}
|
||||
|
||||
|
|
@ -174,20 +191,23 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
|
|||
oldest = deref_locked(tcp_metrics_hash[hash].chain);
|
||||
for (tm = deref_locked(oldest->tcpm_next); tm;
|
||||
tm = deref_locked(tm->tcpm_next)) {
|
||||
if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp))
|
||||
if (time_before(READ_ONCE(tm->tcpm_stamp),
|
||||
READ_ONCE(oldest->tcpm_stamp)))
|
||||
oldest = tm;
|
||||
}
|
||||
tm = oldest;
|
||||
} else {
|
||||
tm = kmalloc(sizeof(*tm), GFP_ATOMIC);
|
||||
tm = kzalloc(sizeof(*tm), GFP_ATOMIC);
|
||||
if (!tm)
|
||||
goto out_unlock;
|
||||
}
|
||||
write_pnet(&tm->tcpm_net, net);
|
||||
/* Paired with the READ_ONCE() in tm_net() */
|
||||
WRITE_ONCE(tm->tcpm_net, net);
|
||||
|
||||
tm->tcpm_saddr = *saddr;
|
||||
tm->tcpm_daddr = *daddr;
|
||||
|
||||
tcpm_suck_dst(tm, dst, true);
|
||||
tcpm_suck_dst(tm, dst, reclaim);
|
||||
|
||||
if (likely(!reclaim)) {
|
||||
tm->tcpm_next = tcp_metrics_hash[hash].chain;
|
||||
|
|
@ -431,7 +451,7 @@ void tcp_update_metrics(struct sock *sk)
|
|||
tp->reordering);
|
||||
}
|
||||
}
|
||||
tm->tcpm_stamp = jiffies;
|
||||
WRITE_ONCE(tm->tcpm_stamp, jiffies);
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
|
@ -534,8 +554,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_SEQLOCK(fastopen_seqlock);
|
||||
|
||||
void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
|
||||
struct tcp_fastopen_cookie *cookie)
|
||||
{
|
||||
|
|
@ -642,7 +660,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,
|
|||
}
|
||||
|
||||
if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE,
|
||||
jiffies - tm->tcpm_stamp,
|
||||
jiffies - READ_ONCE(tm->tcpm_stamp),
|
||||
TCP_METRICS_ATTR_PAD) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
@ -653,7 +671,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,
|
|||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) {
|
||||
u32 val = tm->tcpm_vals[i];
|
||||
u32 val = tcp_metric_get(tm, i);
|
||||
|
||||
if (!val)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -315,9 +315,8 @@ static void addrconf_del_dad_work(struct inet6_ifaddr *ifp)
|
|||
static void addrconf_mod_rs_timer(struct inet6_dev *idev,
|
||||
unsigned long when)
|
||||
{
|
||||
if (!timer_pending(&idev->rs_timer))
|
||||
if (!mod_timer(&idev->rs_timer, jiffies + when))
|
||||
in6_dev_hold(idev);
|
||||
mod_timer(&idev->rs_timer, jiffies + when);
|
||||
}
|
||||
|
||||
static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
|
||||
|
|
@ -2564,12 +2563,18 @@ static void manage_tempaddrs(struct inet6_dev *idev,
|
|||
ipv6_ifa_notify(0, ift);
|
||||
}
|
||||
|
||||
if ((create || list_empty(&idev->tempaddr_list)) &&
|
||||
idev->cnf.use_tempaddr > 0) {
|
||||
/* Also create a temporary address if it's enabled but no temporary
|
||||
* address currently exists.
|
||||
* However, we get called with valid_lft == 0, prefered_lft == 0, create == false
|
||||
* as part of cleanup (ie. deleting the mngtmpaddr).
|
||||
* We don't want that to result in creating a new temporary ip address.
|
||||
*/
|
||||
if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft))
|
||||
create = true;
|
||||
|
||||
if (create && idev->cnf.use_tempaddr > 0) {
|
||||
/* When a new public address is created as described
|
||||
* in [ADDRCONF], also create a new temporary address.
|
||||
* Also create a temporary address if it's enabled but
|
||||
* no temporary address currently exists.
|
||||
*/
|
||||
read_unlock_bh(&idev->lock);
|
||||
ipv6_create_tempaddr(ifp, NULL, false);
|
||||
|
|
|
|||
|
|
@ -410,7 +410,10 @@ static struct net_device *icmp6_dev(const struct sk_buff *skb)
|
|||
if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) {
|
||||
const struct rt6_info *rt6 = skb_rt6_info(skb);
|
||||
|
||||
if (rt6)
|
||||
/* The destination could be an external IP in Ext Hdr (SRv6, RPL, etc.),
|
||||
* and ip6_null_entry could be set to skb if no route is found.
|
||||
*/
|
||||
if (rt6 && rt6->rt6i_idev)
|
||||
dev = rt6->rt6i_idev->dev;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -941,7 +941,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
|
|||
goto tx_err;
|
||||
|
||||
if (skb->len > dev->mtu + dev->hard_header_len) {
|
||||
pskb_trim(skb, dev->mtu + dev->hard_header_len);
|
||||
if (pskb_trim(skb, dev->mtu + dev->hard_header_len))
|
||||
goto tx_err;
|
||||
truncate = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1065,7 +1065,7 @@ static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
|
|||
And all this only to mangle msg->im6_msgtype and
|
||||
to set msg->im6_mbz to "mbz" :-)
|
||||
*/
|
||||
skb_push(skb, -skb_network_offset(pkt));
|
||||
__skb_pull(skb, skb_network_offset(pkt));
|
||||
|
||||
skb_push(skb, sizeof(*msg));
|
||||
skb_reset_transport_header(skb);
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
|
|||
static inline int ndisc_is_useropt(const struct net_device *dev,
|
||||
struct nd_opt_hdr *opt)
|
||||
{
|
||||
return opt->nd_opt_type == ND_OPT_RDNSS ||
|
||||
return opt->nd_opt_type == ND_OPT_PREFIX_INFO ||
|
||||
opt->nd_opt_type == ND_OPT_RDNSS ||
|
||||
opt->nd_opt_type == ND_OPT_DNSSL ||
|
||||
opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL ||
|
||||
opt->nd_opt_type == ND_OPT_PREF64 ||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ static u32 udp6_ehashfn(const struct net *net,
|
|||
fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
|
||||
|
||||
return __inet6_ehashfn(lhash, lport, fhash, fport,
|
||||
udp_ipv6_hash_secret + net_hash_mix(net));
|
||||
udp6_ehash_secret + net_hash_mix(net));
|
||||
}
|
||||
|
||||
int udp_v6_get_port(struct sock *sk, unsigned short snum)
|
||||
|
|
|
|||
|
|
@ -162,9 +162,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
|
|||
void (*sta_handler)(struct sk_buff *skb);
|
||||
void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb);
|
||||
|
||||
if (!net_eq(dev_net(dev), &init_net))
|
||||
goto drop;
|
||||
|
||||
/*
|
||||
* When the interface is in promisc. mode, drop all the crap that it
|
||||
* receives, do not try to analyse it.
|
||||
|
|
|
|||
|
|
@ -811,20 +811,9 @@ static struct nlmsghdr *
|
|||
start_msg(struct sk_buff *skb, u32 portid, u32 seq, unsigned int flags,
|
||||
enum ipset_cmd cmd)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
|
||||
nlh = nlmsg_put(skb, portid, seq, nfnl_msg_type(NFNL_SUBSYS_IPSET, cmd),
|
||||
sizeof(*nfmsg), flags);
|
||||
if (!nlh)
|
||||
return NULL;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = NFPROTO_IPV4;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
return nlh;
|
||||
return nfnl_msg_put(skb, portid, seq,
|
||||
nfnl_msg_type(NFNL_SUBSYS_IPSET, cmd), flags,
|
||||
NFPROTO_IPV4, NFNETLINK_V0, 0);
|
||||
}
|
||||
|
||||
/* Create a set */
|
||||
|
|
|
|||
|
|
@ -404,6 +404,9 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
|
|||
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
|
||||
BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
|
||||
|
||||
if (!nf_ct_helper_hash)
|
||||
return -ENOENT;
|
||||
|
||||
if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -587,4 +590,5 @@ void nf_conntrack_helper_fini(void)
|
|||
{
|
||||
nf_ct_extend_unregister(&helper_extend);
|
||||
kvfree(nf_ct_helper_hash);
|
||||
nf_ct_helper_hash = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,20 +515,15 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
{
|
||||
const struct nf_conntrack_zone *zone;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct nlattr *nest_parms;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0, event;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_NEW);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, nf_ct_l3num(ct),
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = nf_ct_l3num(ct);
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
zone = nf_ct_zone(ct);
|
||||
|
||||
nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG);
|
||||
|
|
@ -685,7 +680,6 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
|
|||
const struct nf_conntrack_zone *zone;
|
||||
struct net *net;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct nlattr *nest_parms;
|
||||
struct nf_conn *ct = item->ct;
|
||||
struct sk_buff *skb;
|
||||
|
|
@ -715,15 +709,11 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
|
|||
goto errout;
|
||||
|
||||
type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, type);
|
||||
nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, item->portid, 0, type, flags, nf_ct_l3num(ct),
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = nf_ct_l3num(ct);
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
zone = nf_ct_zone(ct);
|
||||
|
||||
nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG);
|
||||
|
|
@ -2216,20 +2206,15 @@ ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
|
|||
__u16 cpu, const struct ip_conntrack_stat *st)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0, event;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK,
|
||||
IPCTNL_MSG_CT_GET_STATS_CPU);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, htons(cpu));
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = htons(cpu);
|
||||
|
||||
if (nla_put_be32(skb, CTA_STATS_FOUND, htonl(st->found)) ||
|
||||
nla_put_be32(skb, CTA_STATS_INVALID, htonl(st->invalid)) ||
|
||||
nla_put_be32(skb, CTA_STATS_IGNORE, htonl(st->ignore)) ||
|
||||
|
|
@ -2300,20 +2285,15 @@ ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
struct net *net)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0, event;
|
||||
unsigned int nr_conntracks = atomic_read(&net->ct.count);
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET_STATS);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_be32(skb, CTA_STATS_GLOBAL_ENTRIES, htonl(nr_conntracks)))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
@ -2819,19 +2799,14 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
|
|||
int event, const struct nf_conntrack_expect *exp)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags,
|
||||
exp->tuple.src.l3num, NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = exp->tuple.src.l3num;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (ctnetlink_exp_dump_expect(skb, exp) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
@ -2851,7 +2826,6 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
|
|||
struct nf_conntrack_expect *exp = item->exp;
|
||||
struct net *net = nf_ct_exp_net(exp);
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct sk_buff *skb;
|
||||
unsigned int type, group;
|
||||
int flags = 0;
|
||||
|
|
@ -2874,15 +2848,11 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
|
|||
goto errout;
|
||||
|
||||
type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, type);
|
||||
nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, item->portid, 0, type, flags,
|
||||
exp->tuple.src.l3num, NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = exp->tuple.src.l3num;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (ctnetlink_exp_dump_expect(skb, exp) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
@ -3452,20 +3422,15 @@ ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
|
|||
const struct ip_conntrack_stat *st)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0, event;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK,
|
||||
IPCTNL_MSG_EXP_GET_STATS_CPU);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, htons(cpu));
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = htons(cpu);
|
||||
|
||||
if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) ||
|
||||
nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) ||
|
||||
nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete)))
|
||||
|
|
|
|||
|
|
@ -430,9 +430,19 @@ static bool dccp_error(const struct dccp_hdr *dh,
|
|||
struct sk_buff *skb, unsigned int dataoff,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST |
|
||||
1 << DCCP_PKT_RESPONSE |
|
||||
1 << DCCP_PKT_CLOSEREQ |
|
||||
1 << DCCP_PKT_CLOSE |
|
||||
1 << DCCP_PKT_RESET |
|
||||
1 << DCCP_PKT_SYNC |
|
||||
1 << DCCP_PKT_SYNCACK;
|
||||
unsigned int dccp_len = skb->len - dataoff;
|
||||
unsigned int cscov;
|
||||
const char *msg;
|
||||
u8 type;
|
||||
|
||||
BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
|
||||
|
||||
if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
|
||||
dh->dccph_doff * 4 > dccp_len) {
|
||||
|
|
@ -457,10 +467,17 @@ static bool dccp_error(const struct dccp_hdr *dh,
|
|||
goto out_invalid;
|
||||
}
|
||||
|
||||
if (dh->dccph_type >= DCCP_PKT_INVALID) {
|
||||
type = dh->dccph_type;
|
||||
if (type >= DCCP_PKT_INVALID) {
|
||||
msg = "nf_ct_dccp: reserved packet type ";
|
||||
goto out_invalid;
|
||||
}
|
||||
|
||||
if (test_bit(type, &require_seq48) && !dh->dccph_x) {
|
||||
msg = "nf_ct_dccp: type lacks 48bit sequence numbers";
|
||||
goto out_invalid;
|
||||
}
|
||||
|
||||
return false;
|
||||
out_invalid:
|
||||
nf_l4proto_log_invalid(skb, state->net, state->pf,
|
||||
|
|
@ -468,24 +485,53 @@ out_invalid:
|
|||
return true;
|
||||
}
|
||||
|
||||
struct nf_conntrack_dccp_buf {
|
||||
struct dccp_hdr dh; /* generic header part */
|
||||
struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */
|
||||
union { /* depends on header type */
|
||||
struct dccp_hdr_ack_bits ack;
|
||||
struct dccp_hdr_request req;
|
||||
struct dccp_hdr_response response;
|
||||
struct dccp_hdr_reset rst;
|
||||
} u;
|
||||
};
|
||||
|
||||
static struct dccp_hdr *
|
||||
dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh,
|
||||
struct nf_conntrack_dccp_buf *buf)
|
||||
{
|
||||
unsigned int hdrlen = __dccp_hdr_len(dh);
|
||||
|
||||
if (hdrlen > sizeof(*buf))
|
||||
return NULL;
|
||||
|
||||
return skb_header_pointer(skb, offset, hdrlen, buf);
|
||||
}
|
||||
|
||||
int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||
struct dccp_hdr _dh, *dh;
|
||||
struct nf_conntrack_dccp_buf _dh;
|
||||
u_int8_t type, old_state, new_state;
|
||||
enum ct_dccp_roles role;
|
||||
unsigned int *timeouts;
|
||||
struct dccp_hdr *dh;
|
||||
|
||||
dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
|
||||
if (!dh)
|
||||
return NF_DROP;
|
||||
|
||||
if (dccp_error(dh, skb, dataoff, state))
|
||||
return -NF_ACCEPT;
|
||||
|
||||
/* pull again, including possible 48 bit sequences and subtype header */
|
||||
dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
|
||||
if (!dh)
|
||||
return NF_DROP;
|
||||
|
||||
type = dh->dccph_type;
|
||||
if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh))
|
||||
return -NF_ACCEPT;
|
||||
|
|
|
|||
|
|
@ -969,7 +969,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
|
|||
start += strlen(name);
|
||||
*val = simple_strtoul(start, &end, 0);
|
||||
if (start == end)
|
||||
return 0;
|
||||
return -1;
|
||||
if (matchoff && matchlen) {
|
||||
*matchoff = start - dptr;
|
||||
*matchlen = end - start;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,8 @@
|
|||
#include <net/netfilter/nf_tables_offload.h>
|
||||
#include <net/pkt_cls.h>
|
||||
|
||||
extern unsigned int nf_tables_net_id;
|
||||
|
||||
static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
|
||||
{
|
||||
struct nft_flow_rule *flow;
|
||||
|
|
@ -345,11 +347,12 @@ static int nft_flow_offload_chain(struct nft_chain *chain,
|
|||
|
||||
int nft_flow_rule_offload_commit(struct net *net)
|
||||
{
|
||||
struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
|
||||
struct nft_trans *trans;
|
||||
int err = 0;
|
||||
u8 policy;
|
||||
|
||||
list_for_each_entry(trans, &net->nft.commit_list, list) {
|
||||
list_for_each_entry(trans, &nft_net->commit_list, list) {
|
||||
if (trans->ctx.family != NFPROTO_NETDEV)
|
||||
continue;
|
||||
|
||||
|
|
@ -400,7 +403,7 @@ int nft_flow_rule_offload_commit(struct net *net)
|
|||
break;
|
||||
}
|
||||
|
||||
list_for_each_entry(trans, &net->nft.commit_list, list) {
|
||||
list_for_each_entry(trans, &nft_net->commit_list, list) {
|
||||
if (trans->ctx.family != NFPROTO_NETDEV)
|
||||
continue;
|
||||
|
||||
|
|
@ -419,14 +422,14 @@ int nft_flow_rule_offload_commit(struct net *net)
|
|||
return err;
|
||||
}
|
||||
|
||||
static struct nft_chain *__nft_offload_get_chain(struct net_device *dev)
|
||||
static struct nft_chain *__nft_offload_get_chain(const struct nftables_pernet *nft_net,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct nft_base_chain *basechain;
|
||||
struct net *net = dev_net(dev);
|
||||
const struct nft_table *table;
|
||||
struct nft_chain *chain;
|
||||
|
||||
list_for_each_entry(table, &net->nft.tables, list) {
|
||||
list_for_each_entry(table, &nft_net->tables, list) {
|
||||
if (table->family != NFPROTO_NETDEV)
|
||||
continue;
|
||||
|
||||
|
|
@ -450,18 +453,20 @@ static void nft_indr_block_cb(struct net_device *dev,
|
|||
flow_indr_block_bind_cb_t *cb, void *cb_priv,
|
||||
enum flow_block_command cmd)
|
||||
{
|
||||
struct nftables_pernet *nft_net;
|
||||
struct net *net = dev_net(dev);
|
||||
struct nft_chain *chain;
|
||||
|
||||
mutex_lock(&net->nft.commit_mutex);
|
||||
chain = __nft_offload_get_chain(dev);
|
||||
nft_net = net_generic(net, nf_tables_net_id);
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
chain = __nft_offload_get_chain(nft_net, dev);
|
||||
if (chain && chain->flags & NFT_CHAIN_HW_OFFLOAD) {
|
||||
struct nft_base_chain *basechain;
|
||||
|
||||
basechain = nft_base_chain(chain);
|
||||
nft_indr_block_ing_cmd(dev, basechain, cb, cb_priv, cmd);
|
||||
}
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
mutex_unlock(&nft_net->commit_mutex);
|
||||
}
|
||||
|
||||
static void nft_offload_chain_clean(struct nft_chain *chain)
|
||||
|
|
@ -480,17 +485,19 @@ static int nft_offload_netdev_event(struct notifier_block *this,
|
|||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct nftables_pernet *nft_net;
|
||||
struct net *net = dev_net(dev);
|
||||
struct nft_chain *chain;
|
||||
|
||||
if (event != NETDEV_UNREGISTER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
mutex_lock(&net->nft.commit_mutex);
|
||||
chain = __nft_offload_get_chain(dev);
|
||||
nft_net = net_generic(net, nf_tables_net_id);
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
chain = __nft_offload_get_chain(nft_net, dev);
|
||||
if (chain)
|
||||
nft_offload_chain_clean(chain);
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
mutex_unlock(&nft_net->commit_mutex);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,6 @@ static bool nft_trace_have_verdict_chain(struct nft_traceinfo *info)
|
|||
void nft_trace_notify(struct nft_traceinfo *info)
|
||||
{
|
||||
const struct nft_pktinfo *pkt = info->pkt;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct nlmsghdr *nlh;
|
||||
struct sk_buff *skb;
|
||||
unsigned int size;
|
||||
|
|
@ -219,15 +218,11 @@ void nft_trace_notify(struct nft_traceinfo *info)
|
|||
return;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_TRACE);
|
||||
nlh = nlmsg_put(skb, 0, 0, event, sizeof(struct nfgenmsg), 0);
|
||||
nlh = nfnl_msg_put(skb, 0, 0, event, 0, info->basechain->type->family,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nla_put_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = info->basechain->type->family;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_be32(skb, NFTA_TRACE_NFPROTO, htonl(nft_pf(pkt))))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
|
|||
|
|
@ -132,21 +132,16 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
int event, struct nf_acct *acct)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
u64 pkts, bytes;
|
||||
u32 old_flags;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_ACCT, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_string(skb, NFACCT_NAME, acct->name))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
|
|||
|
|
@ -530,20 +530,15 @@ nfnl_cthelper_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
int event, struct nf_conntrack_helper *helper)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
int status;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTHELPER, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_string(skb, NFCTH_NAME, helper->name))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,22 +160,17 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
int event, struct ctnl_timeout *timeout)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
const struct nf_conntrack_l4proto *l4proto = timeout->timeout.l4proto;
|
||||
struct nlattr *nest_parms;
|
||||
int ret;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
|
||||
nla_put_be16(skb, CTA_TIMEOUT_L3PROTO,
|
||||
htons(timeout->timeout.l3num)) ||
|
||||
|
|
@ -382,21 +377,16 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
|
|||
const unsigned int *timeouts)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
struct nlattr *nest_parms;
|
||||
int ret;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = AF_UNSPEC;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l3num)) ||
|
||||
nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
|
||||
goto nla_put_failure;
|
||||
|
|
|
|||
|
|
@ -452,20 +452,15 @@ __build_packet_message(struct nfnl_log_net *log,
|
|||
{
|
||||
struct nfulnl_msg_packet_hdr pmsg;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
sk_buff_data_t old_tail = inst->skb->tail;
|
||||
struct sock *sk;
|
||||
const unsigned char *hwhdrp;
|
||||
|
||||
nlh = nlmsg_put(inst->skb, 0, 0,
|
||||
nfnl_msg_type(NFNL_SUBSYS_ULOG, NFULNL_MSG_PACKET),
|
||||
sizeof(struct nfgenmsg), 0);
|
||||
nlh = nfnl_msg_put(inst->skb, 0, 0,
|
||||
nfnl_msg_type(NFNL_SUBSYS_ULOG, NFULNL_MSG_PACKET),
|
||||
0, pf, NFNETLINK_V0, htons(inst->group_num));
|
||||
if (!nlh)
|
||||
return -1;
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = pf;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = htons(inst->group_num);
|
||||
|
||||
memset(&pmsg, 0, sizeof(pmsg));
|
||||
pmsg.hw_protocol = skb->protocol;
|
||||
|
|
|
|||
|
|
@ -383,7 +383,6 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
|||
struct nlattr *nla;
|
||||
struct nfqnl_msg_packet_hdr *pmsg;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct sk_buff *entskb = entry->skb;
|
||||
struct net_device *indev;
|
||||
struct net_device *outdev;
|
||||
|
|
@ -469,18 +468,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
|||
goto nlmsg_failure;
|
||||
}
|
||||
|
||||
nlh = nlmsg_put(skb, 0, 0,
|
||||
nfnl_msg_type(NFNL_SUBSYS_QUEUE, NFQNL_MSG_PACKET),
|
||||
sizeof(struct nfgenmsg), 0);
|
||||
nlh = nfnl_msg_put(skb, 0, 0,
|
||||
nfnl_msg_type(NFNL_SUBSYS_QUEUE, NFQNL_MSG_PACKET),
|
||||
0, entry->state.pf, NFNETLINK_V0,
|
||||
htons(queue->queue_num));
|
||||
if (!nlh) {
|
||||
skb_tx_error(entskb);
|
||||
kfree_skb(skb);
|
||||
goto nlmsg_failure;
|
||||
}
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = entry->state.pf;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = htons(queue->queue_num);
|
||||
|
||||
nla = __nla_reserve(skb, NFQA_PACKET_HDR, sizeof(*pmsg));
|
||||
pmsg = nla_data(nla);
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ void nft_byteorder_eval(const struct nft_expr *expr,
|
|||
const struct nft_byteorder *priv = nft_expr_priv(expr);
|
||||
u32 *src = ®s->data[priv->sreg];
|
||||
u32 *dst = ®s->data[priv->dreg];
|
||||
union { u32 u32; u16 u16; } *s, *d;
|
||||
u16 *s16, *d16;
|
||||
unsigned int i;
|
||||
|
||||
s = (void *)src;
|
||||
d = (void *)dst;
|
||||
s16 = (void *)src;
|
||||
d16 = (void *)dst;
|
||||
|
||||
switch (priv->size) {
|
||||
case 8: {
|
||||
|
|
@ -61,11 +61,11 @@ void nft_byteorder_eval(const struct nft_expr *expr,
|
|||
switch (priv->op) {
|
||||
case NFT_BYTEORDER_NTOH:
|
||||
for (i = 0; i < priv->len / 4; i++)
|
||||
d[i].u32 = ntohl((__force __be32)s[i].u32);
|
||||
dst[i] = ntohl((__force __be32)src[i]);
|
||||
break;
|
||||
case NFT_BYTEORDER_HTON:
|
||||
for (i = 0; i < priv->len / 4; i++)
|
||||
d[i].u32 = (__force __u32)htonl(s[i].u32);
|
||||
dst[i] = (__force __u32)htonl(src[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -73,11 +73,11 @@ void nft_byteorder_eval(const struct nft_expr *expr,
|
|||
switch (priv->op) {
|
||||
case NFT_BYTEORDER_NTOH:
|
||||
for (i = 0; i < priv->len / 2; i++)
|
||||
d[i].u16 = ntohs((__force __be16)s[i].u16);
|
||||
d16[i] = ntohs((__force __be16)s16[i]);
|
||||
break;
|
||||
case NFT_BYTEORDER_HTON:
|
||||
for (i = 0; i < priv->len / 2; i++)
|
||||
d[i].u16 = (__force __u16)htons(s[i].u16);
|
||||
d16[i] = (__force __u16)htons(s16[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
|
|
@ -10,6 +11,8 @@
|
|||
#include <net/netfilter/nf_tables_ipv4.h>
|
||||
#include <net/netfilter/nf_tables_ipv6.h>
|
||||
|
||||
extern unsigned int nf_tables_net_id;
|
||||
|
||||
#ifdef CONFIG_NF_TABLES_IPV4
|
||||
static unsigned int nft_do_chain_ipv4(void *priv,
|
||||
struct sk_buff *skb,
|
||||
|
|
@ -315,6 +318,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
|||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct nftables_pernet *nft_net;
|
||||
struct nft_table *table;
|
||||
struct nft_chain *chain, *nr;
|
||||
struct nft_ctx ctx = {
|
||||
|
|
@ -325,8 +329,9 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
|||
event != NETDEV_CHANGENAME)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
mutex_lock(&ctx.net->nft.commit_mutex);
|
||||
list_for_each_entry(table, &ctx.net->nft.tables, list) {
|
||||
nft_net = net_generic(ctx.net, nf_tables_net_id);
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
list_for_each_entry(table, &nft_net->tables, list) {
|
||||
if (table->family != NFPROTO_NETDEV)
|
||||
continue;
|
||||
|
||||
|
|
@ -340,7 +345,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
|||
nft_netdev_event(event, dev, &ctx);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ctx.net->nft.commit_mutex);
|
||||
mutex_unlock(&nft_net->commit_mutex);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -591,19 +591,14 @@ nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
|
|||
int rev, int target)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
unsigned int flags = portid ? NLM_F_MULTI : 0;
|
||||
|
||||
event = nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT, event);
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
|
||||
if (nlh == NULL)
|
||||
nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
|
||||
NFNETLINK_V0, 0);
|
||||
if (!nlh)
|
||||
goto nlmsg_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = family;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
if (nla_put_string(skb, NFTA_COMPAT_NAME, name) ||
|
||||
nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) ||
|
||||
nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target)))
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
extern unsigned int nf_tables_net_id;
|
||||
|
||||
struct nft_dynset {
|
||||
struct nft_set *set;
|
||||
|
|
@ -129,13 +132,14 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
|||
const struct nft_expr *expr,
|
||||
const struct nlattr * const tb[])
|
||||
{
|
||||
struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
|
||||
struct nft_dynset *priv = nft_expr_priv(expr);
|
||||
u8 genmask = nft_genmask_next(ctx->net);
|
||||
struct nft_set *set;
|
||||
u64 timeout;
|
||||
int err;
|
||||
|
||||
lockdep_assert_held(&ctx->net->nft.commit_mutex);
|
||||
lockdep_assert_held(&nft_net->commit_mutex);
|
||||
|
||||
if (tb[NFTA_DYNSET_SET_NAME] == NULL ||
|
||||
tb[NFTA_DYNSET_OP] == NULL ||
|
||||
|
|
|
|||
|
|
@ -171,8 +171,10 @@ static int nft_flow_offload_init(const struct nft_ctx *ctx,
|
|||
if (IS_ERR(flowtable))
|
||||
return PTR_ERR(flowtable);
|
||||
|
||||
if (!nft_use_inc(&flowtable->use))
|
||||
return -EMFILE;
|
||||
|
||||
priv->flowtable = flowtable;
|
||||
flowtable->use++;
|
||||
|
||||
return nf_ct_netns_get(ctx->net, ctx->family);
|
||||
}
|
||||
|
|
@ -191,7 +193,7 @@ static void nft_flow_offload_activate(const struct nft_ctx *ctx,
|
|||
{
|
||||
struct nft_flow_offload *priv = nft_expr_priv(expr);
|
||||
|
||||
priv->flowtable->use++;
|
||||
nft_use_inc_restore(&priv->flowtable->use);
|
||||
}
|
||||
|
||||
static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
|
||||
|
|
|
|||
|
|
@ -41,8 +41,10 @@ static int nft_objref_init(const struct nft_ctx *ctx,
|
|||
if (IS_ERR(obj))
|
||||
return -ENOENT;
|
||||
|
||||
if (!nft_use_inc(&obj->use))
|
||||
return -EMFILE;
|
||||
|
||||
nft_objref_priv(expr) = obj;
|
||||
obj->use++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -71,7 +73,7 @@ static void nft_objref_deactivate(const struct nft_ctx *ctx,
|
|||
if (phase == NFT_TRANS_COMMIT)
|
||||
return;
|
||||
|
||||
obj->use--;
|
||||
nft_use_dec(&obj->use);
|
||||
}
|
||||
|
||||
static void nft_objref_activate(const struct nft_ctx *ctx,
|
||||
|
|
@ -79,7 +81,7 @@ static void nft_objref_activate(const struct nft_ctx *ctx,
|
|||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
obj->use++;
|
||||
nft_use_inc_restore(&obj->use);
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_objref_type;
|
||||
|
|
|
|||
|
|
@ -1601,6 +1601,7 @@ out:
|
|||
int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
|
||||
{
|
||||
struct netlink_set_err_data info;
|
||||
unsigned long flags;
|
||||
struct sock *sk;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -1610,12 +1611,12 @@ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
|
|||
/* sk->sk_err wants a positive error value */
|
||||
info.code = -code;
|
||||
|
||||
read_lock(&nl_table_lock);
|
||||
read_lock_irqsave(&nl_table_lock, flags);
|
||||
|
||||
sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
|
||||
ret += do_one_set_err(sk, &info);
|
||||
|
||||
read_unlock(&nl_table_lock);
|
||||
read_unlock_irqrestore(&nl_table_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_set_err);
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
struct net *net = sock_net(skb->sk);
|
||||
struct netlink_diag_req *req;
|
||||
struct netlink_sock *nlsk;
|
||||
unsigned long flags;
|
||||
struct sock *sk;
|
||||
int num = 2;
|
||||
int ret = 0;
|
||||
|
|
@ -152,7 +153,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
num++;
|
||||
|
||||
mc_list:
|
||||
read_lock(&nl_table_lock);
|
||||
read_lock_irqsave(&nl_table_lock, flags);
|
||||
sk_for_each_bound(sk, &tbl->mc_list) {
|
||||
if (sk_hashed(sk))
|
||||
continue;
|
||||
|
|
@ -167,13 +168,13 @@ mc_list:
|
|||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
NLM_F_MULTI,
|
||||
sock_i_ino(sk)) < 0) {
|
||||
__sock_i_ino(sk)) < 0) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
read_unlock(&nl_table_lock);
|
||||
read_unlock_irqrestore(&nl_table_lock, flags);
|
||||
|
||||
done:
|
||||
cb->args[0] = num;
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
|
||||
int nfc_set_remote_general_bytes(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
|
||||
{
|
||||
pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len);
|
||||
|
||||
|
|
@ -663,7 +663,7 @@ int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb)
|
|||
EXPORT_SYMBOL(nfc_tm_data_received);
|
||||
|
||||
int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
|
||||
u8 *gb, size_t gb_len)
|
||||
const u8 *gb, size_t gb_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ static bool llc_shdlc_x_lteq_y_lt_z(int x, int y, int z)
|
|||
return ((y >= x) || (y < z)) ? true : false;
|
||||
}
|
||||
|
||||
static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc,
|
||||
static struct sk_buff *llc_shdlc_alloc_skb(const struct llc_shdlc *shdlc,
|
||||
int payload_len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
|
@ -137,7 +137,7 @@ static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc,
|
|||
}
|
||||
|
||||
/* immediately sends an S frame. */
|
||||
static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc,
|
||||
static int llc_shdlc_send_s_frame(const struct llc_shdlc *shdlc,
|
||||
enum sframe_type sframe_type, int nr)
|
||||
{
|
||||
int r;
|
||||
|
|
@ -159,7 +159,7 @@ static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc,
|
|||
}
|
||||
|
||||
/* immediately sends an U frame. skb may contain optional payload */
|
||||
static int llc_shdlc_send_u_frame(struct llc_shdlc *shdlc,
|
||||
static int llc_shdlc_send_u_frame(const struct llc_shdlc *shdlc,
|
||||
struct sk_buff *skb,
|
||||
enum uframe_modifier uframe_modifier)
|
||||
{
|
||||
|
|
@ -361,7 +361,7 @@ static void llc_shdlc_connect_complete(struct llc_shdlc *shdlc, int r)
|
|||
wake_up(shdlc->connect_wq);
|
||||
}
|
||||
|
||||
static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc)
|
||||
static int llc_shdlc_connect_initiate(const struct llc_shdlc *shdlc)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc)
|
|||
return llc_shdlc_send_u_frame(shdlc, skb, U_FRAME_RSET);
|
||||
}
|
||||
|
||||
static int llc_shdlc_connect_send_ua(struct llc_shdlc *shdlc)
|
||||
static int llc_shdlc_connect_send_ua(const struct llc_shdlc *shdlc)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,6 @@ void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s);
|
|||
void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s);
|
||||
void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock);
|
||||
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
|
||||
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local);
|
||||
int nfc_llcp_local_put(struct nfc_llcp_local *local);
|
||||
u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
|
||||
struct nfc_llcp_sock *sock);
|
||||
|
|
@ -221,15 +220,15 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock);
|
|||
|
||||
/* TLV API */
|
||||
int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
|
||||
u8 *tlv_array, u16 tlv_array_len);
|
||||
const u8 *tlv_array, u16 tlv_array_len);
|
||||
int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
|
||||
u8 *tlv_array, u16 tlv_array_len);
|
||||
const u8 *tlv_array, u16 tlv_array_len);
|
||||
|
||||
/* Commands API */
|
||||
void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
|
||||
u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length);
|
||||
u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length);
|
||||
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap);
|
||||
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
|
||||
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
|
||||
size_t uri_len);
|
||||
void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
|
||||
void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "nfc.h"
|
||||
#include "llcp.h"
|
||||
|
||||
static u8 llcp_tlv_length[LLCP_TLV_MAX] = {
|
||||
static const u8 llcp_tlv_length[LLCP_TLV_MAX] = {
|
||||
0,
|
||||
1, /* VERSION */
|
||||
2, /* MIUX */
|
||||
|
|
@ -29,7 +29,7 @@ static u8 llcp_tlv_length[LLCP_TLV_MAX] = {
|
|||
|
||||
};
|
||||
|
||||
static u8 llcp_tlv8(u8 *tlv, u8 type)
|
||||
static u8 llcp_tlv8(const u8 *tlv, u8 type)
|
||||
{
|
||||
if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
|
||||
return 0;
|
||||
|
|
@ -37,7 +37,7 @@ static u8 llcp_tlv8(u8 *tlv, u8 type)
|
|||
return tlv[2];
|
||||
}
|
||||
|
||||
static u16 llcp_tlv16(u8 *tlv, u8 type)
|
||||
static u16 llcp_tlv16(const u8 *tlv, u8 type)
|
||||
{
|
||||
if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
|
||||
return 0;
|
||||
|
|
@ -46,37 +46,37 @@ static u16 llcp_tlv16(u8 *tlv, u8 type)
|
|||
}
|
||||
|
||||
|
||||
static u8 llcp_tlv_version(u8 *tlv)
|
||||
static u8 llcp_tlv_version(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv8(tlv, LLCP_TLV_VERSION);
|
||||
}
|
||||
|
||||
static u16 llcp_tlv_miux(u8 *tlv)
|
||||
static u16 llcp_tlv_miux(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7ff;
|
||||
}
|
||||
|
||||
static u16 llcp_tlv_wks(u8 *tlv)
|
||||
static u16 llcp_tlv_wks(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv16(tlv, LLCP_TLV_WKS);
|
||||
}
|
||||
|
||||
static u16 llcp_tlv_lto(u8 *tlv)
|
||||
static u16 llcp_tlv_lto(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv8(tlv, LLCP_TLV_LTO);
|
||||
}
|
||||
|
||||
static u8 llcp_tlv_opt(u8 *tlv)
|
||||
static u8 llcp_tlv_opt(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv8(tlv, LLCP_TLV_OPT);
|
||||
}
|
||||
|
||||
static u8 llcp_tlv_rw(u8 *tlv)
|
||||
static u8 llcp_tlv_rw(const u8 *tlv)
|
||||
{
|
||||
return llcp_tlv8(tlv, LLCP_TLV_RW) & 0xf;
|
||||
}
|
||||
|
||||
u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
|
||||
u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length)
|
||||
{
|
||||
u8 *tlv, length;
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap)
|
|||
return sdres;
|
||||
}
|
||||
|
||||
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
|
||||
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
|
||||
size_t uri_len)
|
||||
{
|
||||
struct nfc_llcp_sdp_tlv *sdreq;
|
||||
|
|
@ -190,9 +190,10 @@ void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head)
|
|||
}
|
||||
|
||||
int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
|
||||
u8 *tlv_array, u16 tlv_array_len)
|
||||
const u8 *tlv_array, u16 tlv_array_len)
|
||||
{
|
||||
u8 *tlv = tlv_array, type, length, offset = 0;
|
||||
const u8 *tlv = tlv_array;
|
||||
u8 type, length, offset = 0;
|
||||
|
||||
pr_debug("TLV array length %d\n", tlv_array_len);
|
||||
|
||||
|
|
@ -239,9 +240,10 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
|
|||
}
|
||||
|
||||
int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
|
||||
u8 *tlv_array, u16 tlv_array_len)
|
||||
const u8 *tlv_array, u16 tlv_array_len)
|
||||
{
|
||||
u8 *tlv = tlv_array, type, length, offset = 0;
|
||||
const u8 *tlv = tlv_array;
|
||||
u8 type, length, offset = 0;
|
||||
|
||||
pr_debug("TLV array length %d\n", tlv_array_len);
|
||||
|
||||
|
|
@ -295,7 +297,7 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
|
|||
return pdu;
|
||||
}
|
||||
|
||||
static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
|
||||
static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, const u8 *tlv,
|
||||
u8 tlv_length)
|
||||
{
|
||||
/* XXX Add an skb length check */
|
||||
|
|
@ -359,6 +361,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
|
|||
struct sk_buff *skb;
|
||||
struct nfc_llcp_local *local;
|
||||
u16 size = 0;
|
||||
int err;
|
||||
|
||||
pr_debug("Sending SYMM\n");
|
||||
|
||||
|
|
@ -370,8 +373,10 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
|
|||
size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
|
||||
|
||||
skb = alloc_skb(size, GFP_KERNEL);
|
||||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
if (skb == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
|
||||
|
||||
|
|
@ -381,17 +386,22 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
|
|||
|
||||
nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
|
||||
|
||||
return nfc_data_exchange(dev, local->target_idx, skb,
|
||||
err = nfc_data_exchange(dev, local->target_idx, skb,
|
||||
nfc_llcp_recv, local);
|
||||
out:
|
||||
nfc_llcp_local_put(local);
|
||||
return err;
|
||||
}
|
||||
|
||||
int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
|
||||
{
|
||||
struct nfc_llcp_local *local;
|
||||
struct sk_buff *skb;
|
||||
u8 *service_name_tlv = NULL, service_name_tlv_length;
|
||||
u8 *miux_tlv = NULL, miux_tlv_length;
|
||||
u8 *rw_tlv = NULL, rw_tlv_length, rw;
|
||||
const u8 *service_name_tlv = NULL;
|
||||
const u8 *miux_tlv = NULL;
|
||||
const u8 *rw_tlv = NULL;
|
||||
u8 service_name_tlv_length = 0;
|
||||
u8 miux_tlv_length, rw_tlv_length, rw;
|
||||
int err;
|
||||
u16 size = 0;
|
||||
__be16 miux;
|
||||
|
|
@ -465,8 +475,9 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
|
|||
{
|
||||
struct nfc_llcp_local *local;
|
||||
struct sk_buff *skb;
|
||||
u8 *miux_tlv = NULL, miux_tlv_length;
|
||||
u8 *rw_tlv = NULL, rw_tlv_length, rw;
|
||||
const u8 *miux_tlv = NULL;
|
||||
const u8 *rw_tlv = NULL;
|
||||
u8 miux_tlv_length, rw_tlv_length, rw;
|
||||
int err;
|
||||
u16 size = 0;
|
||||
__be16 miux;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
static u8 llcp_magic[3] = {0x46, 0x66, 0x6d};
|
||||
|
||||
static LIST_HEAD(llcp_devices);
|
||||
/* Protects llcp_devices list */
|
||||
static DEFINE_SPINLOCK(llcp_devices_lock);
|
||||
|
||||
static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
|
||||
|
||||
|
|
@ -143,7 +145,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
|
|||
write_unlock(&local->raw_sockets.lock);
|
||||
}
|
||||
|
||||
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||
static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||
{
|
||||
kref_get(&local->ref);
|
||||
|
||||
|
|
@ -171,7 +173,6 @@ static void local_release(struct kref *ref)
|
|||
|
||||
local = container_of(ref, struct nfc_llcp_local, ref);
|
||||
|
||||
list_del(&local->list);
|
||||
local_cleanup(local);
|
||||
kfree(local);
|
||||
}
|
||||
|
|
@ -284,12 +285,33 @@ static void nfc_llcp_sdreq_timer(struct timer_list *t)
|
|||
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
|
||||
{
|
||||
struct nfc_llcp_local *local;
|
||||
struct nfc_llcp_local *res = NULL;
|
||||
|
||||
spin_lock(&llcp_devices_lock);
|
||||
list_for_each_entry(local, &llcp_devices, list)
|
||||
if (local->dev == dev)
|
||||
return local;
|
||||
if (local->dev == dev) {
|
||||
res = nfc_llcp_local_get(local);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&llcp_devices_lock);
|
||||
|
||||
pr_debug("No device found\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev)
|
||||
{
|
||||
struct nfc_llcp_local *local, *tmp;
|
||||
|
||||
spin_lock(&llcp_devices_lock);
|
||||
list_for_each_entry_safe(local, tmp, &llcp_devices, list)
|
||||
if (local->dev == dev) {
|
||||
list_del(&local->list);
|
||||
spin_unlock(&llcp_devices_lock);
|
||||
return local;
|
||||
}
|
||||
spin_unlock(&llcp_devices_lock);
|
||||
|
||||
pr_warn("Shutting down device not found\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -302,7 +324,7 @@ static char *wks[] = {
|
|||
"urn:nfc:sn:snep",
|
||||
};
|
||||
|
||||
static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
|
||||
static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
|
||||
{
|
||||
int sap, num_wks;
|
||||
|
||||
|
|
@ -326,7 +348,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
|
|||
|
||||
static
|
||||
struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local,
|
||||
u8 *sn, size_t sn_len)
|
||||
const u8 *sn, size_t sn_len)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct nfc_llcp_sock *llcp_sock, *tmp_sock;
|
||||
|
|
@ -523,7 +545,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
|
|||
{
|
||||
u8 *gb_cur, version, version_length;
|
||||
u8 lto_length, wks_length, miux_length;
|
||||
u8 *version_tlv = NULL, *lto_tlv = NULL,
|
||||
const u8 *version_tlv = NULL, *lto_tlv = NULL,
|
||||
*wks_tlv = NULL, *miux_tlv = NULL;
|
||||
__be16 wks = cpu_to_be16(local->local_wks);
|
||||
u8 gb_len = 0;
|
||||
|
|
@ -610,12 +632,15 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
|
|||
|
||||
*general_bytes_len = local->gb_len;
|
||||
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
return local->gb;
|
||||
}
|
||||
|
||||
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
|
||||
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
|
||||
{
|
||||
struct nfc_llcp_local *local;
|
||||
int err;
|
||||
|
||||
if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN)
|
||||
return -EINVAL;
|
||||
|
|
@ -632,35 +657,39 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
|
|||
|
||||
if (memcmp(local->remote_gb, llcp_magic, 3)) {
|
||||
pr_err("MAC does not support LLCP\n");
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return nfc_llcp_parse_gb_tlv(local,
|
||||
err = nfc_llcp_parse_gb_tlv(local,
|
||||
&local->remote_gb[3],
|
||||
local->remote_gb_len - 3);
|
||||
out:
|
||||
nfc_llcp_local_put(local);
|
||||
return err;
|
||||
}
|
||||
|
||||
static u8 nfc_llcp_dsap(struct sk_buff *pdu)
|
||||
static u8 nfc_llcp_dsap(const struct sk_buff *pdu)
|
||||
{
|
||||
return (pdu->data[0] & 0xfc) >> 2;
|
||||
}
|
||||
|
||||
static u8 nfc_llcp_ptype(struct sk_buff *pdu)
|
||||
static u8 nfc_llcp_ptype(const struct sk_buff *pdu)
|
||||
{
|
||||
return ((pdu->data[0] & 0x03) << 2) | ((pdu->data[1] & 0xc0) >> 6);
|
||||
}
|
||||
|
||||
static u8 nfc_llcp_ssap(struct sk_buff *pdu)
|
||||
static u8 nfc_llcp_ssap(const struct sk_buff *pdu)
|
||||
{
|
||||
return pdu->data[1] & 0x3f;
|
||||
}
|
||||
|
||||
static u8 nfc_llcp_ns(struct sk_buff *pdu)
|
||||
static u8 nfc_llcp_ns(const struct sk_buff *pdu)
|
||||
{
|
||||
return pdu->data[2] >> 4;
|
||||
}
|
||||
|
||||
static u8 nfc_llcp_nr(struct sk_buff *pdu)
|
||||
static u8 nfc_llcp_nr(const struct sk_buff *pdu)
|
||||
{
|
||||
return pdu->data[2] & 0xf;
|
||||
}
|
||||
|
|
@ -802,7 +831,7 @@ out:
|
|||
}
|
||||
|
||||
static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
|
||||
u8 *sn, size_t sn_len)
|
||||
const u8 *sn, size_t sn_len)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
|
||||
|
|
@ -816,9 +845,10 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
|
|||
return llcp_sock;
|
||||
}
|
||||
|
||||
static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
|
||||
static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
|
||||
{
|
||||
u8 *tlv = &skb->data[2], type, length;
|
||||
u8 type, length;
|
||||
const u8 *tlv = &skb->data[2];
|
||||
size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0;
|
||||
|
||||
while (offset < tlv_array_len) {
|
||||
|
|
@ -876,7 +906,7 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local,
|
|||
}
|
||||
|
||||
static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
|
||||
struct sk_buff *skb)
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
struct sock *new_sk, *parent;
|
||||
struct nfc_llcp_sock *sock, *new_sock;
|
||||
|
|
@ -894,7 +924,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
|
|||
goto fail;
|
||||
}
|
||||
} else {
|
||||
u8 *sn;
|
||||
const u8 *sn;
|
||||
size_t sn_len;
|
||||
|
||||
sn = nfc_llcp_connect_sn(skb, &sn_len);
|
||||
|
|
@ -1113,7 +1143,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
|
|||
}
|
||||
|
||||
static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
|
||||
struct sk_buff *skb)
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
struct sock *sk;
|
||||
|
|
@ -1156,7 +1186,8 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
|
|||
nfc_llcp_sock_put(llcp_sock);
|
||||
}
|
||||
|
||||
static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
|
||||
static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
struct sock *sk;
|
||||
|
|
@ -1189,7 +1220,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
|
|||
nfc_llcp_sock_put(llcp_sock);
|
||||
}
|
||||
|
||||
static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
|
||||
static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
struct sock *sk;
|
||||
|
|
@ -1227,12 +1259,13 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
|
||||
struct sk_buff *skb)
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
u8 dsap, ssap, *tlv, type, length, tid, sap;
|
||||
u8 dsap, ssap, type, length, tid, sap;
|
||||
const u8 *tlv;
|
||||
u16 tlv_len, offset;
|
||||
char *service_name;
|
||||
const char *service_name;
|
||||
size_t service_name_len;
|
||||
struct nfc_llcp_sdp_tlv *sdp;
|
||||
HLIST_HEAD(llc_sdres_list);
|
||||
|
|
@ -1523,6 +1556,8 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
|
|||
|
||||
__nfc_llcp_recv(local, skb);
|
||||
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1539,6 +1574,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
|
|||
|
||||
/* Close and purge all existing sockets */
|
||||
nfc_llcp_socket_release(local, true, 0);
|
||||
|
||||
nfc_llcp_local_put(local);
|
||||
}
|
||||
|
||||
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
||||
|
|
@ -1564,6 +1601,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
|||
mod_timer(&local->link_timer,
|
||||
jiffies + msecs_to_jiffies(local->remote_lto));
|
||||
}
|
||||
|
||||
nfc_llcp_local_put(local);
|
||||
}
|
||||
|
||||
int nfc_llcp_register_device(struct nfc_dev *ndev)
|
||||
|
|
@ -1614,7 +1653,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
|
|||
|
||||
void nfc_llcp_unregister_device(struct nfc_dev *dev)
|
||||
{
|
||||
struct nfc_llcp_local *local = nfc_llcp_find_local(dev);
|
||||
struct nfc_llcp_local *local = nfc_llcp_remove_local(dev);
|
||||
|
||||
if (local == NULL) {
|
||||
pr_debug("No such device\n");
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
|||
}
|
||||
|
||||
llcp_sock->dev = dev;
|
||||
llcp_sock->local = nfc_llcp_local_get(local);
|
||||
llcp_sock->local = local;
|
||||
llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
|
||||
llcp_sock->service_name_len = min_t(unsigned int,
|
||||
llcp_addr.service_name_len,
|
||||
|
|
@ -181,7 +181,7 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr,
|
|||
}
|
||||
|
||||
llcp_sock->dev = dev;
|
||||
llcp_sock->local = nfc_llcp_local_get(local);
|
||||
llcp_sock->local = local;
|
||||
llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
|
||||
|
||||
nfc_llcp_sock_link(&local->raw_sockets, sk);
|
||||
|
|
@ -698,24 +698,22 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
|
|||
if (dev->dep_link_up == false) {
|
||||
ret = -ENOLINK;
|
||||
device_unlock(&dev->dev);
|
||||
goto put_dev;
|
||||
goto sock_llcp_put_local;
|
||||
}
|
||||
device_unlock(&dev->dev);
|
||||
|
||||
if (local->rf_mode == NFC_RF_INITIATOR &&
|
||||
addr->target_idx != local->target_idx) {
|
||||
ret = -ENOLINK;
|
||||
goto put_dev;
|
||||
goto sock_llcp_put_local;
|
||||
}
|
||||
|
||||
llcp_sock->dev = dev;
|
||||
llcp_sock->local = nfc_llcp_local_get(local);
|
||||
llcp_sock->local = local;
|
||||
llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
|
||||
if (llcp_sock->ssap == LLCP_SAP_MAX) {
|
||||
nfc_llcp_local_put(llcp_sock->local);
|
||||
llcp_sock->local = NULL;
|
||||
ret = -ENOMEM;
|
||||
goto put_dev;
|
||||
goto sock_llcp_nullify;
|
||||
}
|
||||
|
||||
llcp_sock->reserved_ssap = llcp_sock->ssap;
|
||||
|
|
@ -760,8 +758,13 @@ sock_unlink:
|
|||
|
||||
sock_llcp_release:
|
||||
nfc_llcp_put_ssap(local, llcp_sock->ssap);
|
||||
nfc_llcp_local_put(llcp_sock->local);
|
||||
|
||||
sock_llcp_nullify:
|
||||
llcp_sock->local = NULL;
|
||||
llcp_sock->dev = NULL;
|
||||
|
||||
sock_llcp_put_local:
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
put_dev:
|
||||
nfc_put_device(dev);
|
||||
|
|
|
|||
|
|
@ -1047,11 +1047,14 @@ static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
|
|||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
goto put_local;
|
||||
}
|
||||
|
||||
rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
|
||||
|
||||
put_local:
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
exit:
|
||||
device_unlock(&dev->dev);
|
||||
|
||||
|
|
@ -1113,7 +1116,7 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
|
||||
if (dev->dep_link_up) {
|
||||
rc = -EINPROGRESS;
|
||||
goto exit;
|
||||
goto put_local;
|
||||
}
|
||||
|
||||
local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
|
||||
|
|
@ -1125,6 +1128,9 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
|
||||
local->miux = cpu_to_be16(miux);
|
||||
|
||||
put_local:
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
exit:
|
||||
device_unlock(&dev->dev);
|
||||
|
||||
|
|
@ -1180,7 +1186,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (rc != 0) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
goto put_local;
|
||||
}
|
||||
|
||||
if (!sdp_attrs[NFC_SDP_ATTR_URI])
|
||||
|
|
@ -1199,7 +1205,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
|
|||
sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
|
||||
if (sdreq == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
goto put_local;
|
||||
}
|
||||
|
||||
tlvs_len += sdreq->tlv_len;
|
||||
|
|
@ -1209,10 +1215,14 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (hlist_empty(&sdreq_list)) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
goto put_local;
|
||||
}
|
||||
|
||||
rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
|
||||
|
||||
put_local:
|
||||
nfc_llcp_local_put(local);
|
||||
|
||||
exit:
|
||||
device_unlock(&dev->dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,10 +48,11 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
|||
u8 comm_mode, u8 rf_mode);
|
||||
int nfc_llcp_register_device(struct nfc_dev *dev);
|
||||
void nfc_llcp_unregister_device(struct nfc_dev *dev);
|
||||
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
|
||||
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len);
|
||||
u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
|
||||
int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
|
||||
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
|
||||
int nfc_llcp_local_put(struct nfc_llcp_local *local);
|
||||
int __init nfc_llcp_init(void);
|
||||
void nfc_llcp_exit(void);
|
||||
void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
|
||||
|
|
|
|||
|
|
@ -363,18 +363,20 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
|
|||
{
|
||||
union tpacket_uhdr h;
|
||||
|
||||
/* WRITE_ONCE() are paired with READ_ONCE() in __packet_get_status */
|
||||
|
||||
h.raw = frame;
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
h.h1->tp_status = status;
|
||||
WRITE_ONCE(h.h1->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
break;
|
||||
case TPACKET_V2:
|
||||
h.h2->tp_status = status;
|
||||
WRITE_ONCE(h.h2->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
break;
|
||||
case TPACKET_V3:
|
||||
h.h3->tp_status = status;
|
||||
WRITE_ONCE(h.h3->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h3->tp_status));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -391,17 +393,19 @@ static int __packet_get_status(const struct packet_sock *po, void *frame)
|
|||
|
||||
smp_rmb();
|
||||
|
||||
/* READ_ONCE() are paired with WRITE_ONCE() in __packet_set_status */
|
||||
|
||||
h.raw = frame;
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
return h.h1->tp_status;
|
||||
return READ_ONCE(h.h1->tp_status);
|
||||
case TPACKET_V2:
|
||||
flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
return h.h2->tp_status;
|
||||
return READ_ONCE(h.h2->tp_status);
|
||||
case TPACKET_V3:
|
||||
flush_dcache_page(pgv_to_page(&h.h3->tp_status));
|
||||
return h.h3->tp_status;
|
||||
return READ_ONCE(h.h3->tp_status);
|
||||
default:
|
||||
WARN(1, "TPACKET version not supported.\n");
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ static struct tc_action_ops act_pedit_ops;
|
|||
|
||||
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
|
||||
[TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) },
|
||||
[TCA_PEDIT_PARMS_EX] = { .len = sizeof(struct tc_pedit) },
|
||||
[TCA_PEDIT_KEYS_EX] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -719,7 +719,8 @@ static void fl_set_key_val(struct nlattr **tb,
|
|||
}
|
||||
|
||||
static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
|
||||
struct fl_flow_key *mask)
|
||||
struct fl_flow_key *mask,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
fl_set_key_val(tb, &key->tp_range.tp_min.dst,
|
||||
TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_range.tp_min.dst,
|
||||
|
|
@ -734,13 +735,32 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
|
|||
TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src,
|
||||
TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
|
||||
|
||||
if ((mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
|
||||
htons(key->tp_range.tp_max.dst) <=
|
||||
htons(key->tp_range.tp_min.dst)) ||
|
||||
(mask->tp_range.tp_min.src && mask->tp_range.tp_max.src &&
|
||||
htons(key->tp_range.tp_max.src) <=
|
||||
htons(key->tp_range.tp_min.src)))
|
||||
if (mask->tp_range.tp_min.dst != mask->tp_range.tp_max.dst) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Both min and max destination ports must be specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mask->tp_range.tp_min.src != mask->tp_range.tp_max.src) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Both min and max source ports must be specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
|
||||
htons(key->tp_range.tp_max.dst) <=
|
||||
htons(key->tp_range.tp_min.dst)) {
|
||||
NL_SET_ERR_MSG_ATTR(extack,
|
||||
tb[TCA_FLOWER_KEY_PORT_DST_MIN],
|
||||
"Invalid destination port range (min must be strictly smaller than max)");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mask->tp_range.tp_min.src && mask->tp_range.tp_max.src &&
|
||||
htons(key->tp_range.tp_max.src) <=
|
||||
htons(key->tp_range.tp_min.src)) {
|
||||
NL_SET_ERR_MSG_ATTR(extack,
|
||||
tb[TCA_FLOWER_KEY_PORT_SRC_MIN],
|
||||
"Invalid source port range (min must be strictly smaller than max)");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1211,7 +1231,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
|
|||
if (key->basic.ip_proto == IPPROTO_TCP ||
|
||||
key->basic.ip_proto == IPPROTO_UDP ||
|
||||
key->basic.ip_proto == IPPROTO_SCTP) {
|
||||
ret = fl_set_key_port_range(tb, key, mask);
|
||||
ret = fl_set_key_port_range(tb, key, mask, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1003,18 +1003,62 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* At this point, we need to derive the new handle that will be used to
|
||||
* uniquely map the identity of this table match entry. The
|
||||
* identity of the entry that we need to construct is 32 bits made of:
|
||||
* htid(12b):bucketid(8b):node/entryid(12b)
|
||||
*
|
||||
* At this point _we have the table(ht)_ in which we will insert this
|
||||
* entry. We carry the table's id in variable "htid".
|
||||
* Note that earlier code picked the ht selection either by a) the user
|
||||
* providing the htid specified via TCA_U32_HASH attribute or b) when
|
||||
* no such attribute is passed then the root ht, is default to at ID
|
||||
* 0x[800][00][000]. Rule: the root table has a single bucket with ID 0.
|
||||
* If OTOH the user passed us the htid, they may also pass a bucketid of
|
||||
* choice. 0 is fine. For example a user htid is 0x[600][01][000] it is
|
||||
* indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be
|
||||
* passed via the htid, so even if it was non-zero it will be ignored.
|
||||
*
|
||||
* We may also have a handle, if the user passed one. The handle also
|
||||
* carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b).
|
||||
* Rule: the bucketid on the handle is ignored even if one was passed;
|
||||
* rather the value on "htid" is always assumed to be the bucketid.
|
||||
*/
|
||||
if (handle) {
|
||||
/* Rule: The htid from handle and tableid from htid must match */
|
||||
if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch");
|
||||
return -EINVAL;
|
||||
}
|
||||
handle = htid | TC_U32_NODE(handle);
|
||||
err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle,
|
||||
GFP_KERNEL);
|
||||
if (err)
|
||||
return err;
|
||||
} else
|
||||
/* Ok, so far we have a valid htid(12b):bucketid(8b) but we
|
||||
* need to finalize the table entry identification with the last
|
||||
* part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for
|
||||
* entries. Rule: nodeid of 0 is reserved only for tables(see
|
||||
* earlier code which processes TC_U32_DIVISOR attribute).
|
||||
* Rule: The nodeid can only be derived from the handle (and not
|
||||
* htid).
|
||||
* Rule: if the handle specified zero for the node id example
|
||||
* 0x60000000, then pick a new nodeid from the pool of IDs
|
||||
* this hash table has been allocating from.
|
||||
* If OTOH it is specified (i.e for example the user passed a
|
||||
* handle such as 0x60000123), then we use it generate our final
|
||||
* handle which is used to uniquely identify the match entry.
|
||||
*/
|
||||
if (!TC_U32_NODE(handle)) {
|
||||
handle = gen_new_kid(ht, htid);
|
||||
} else {
|
||||
handle = htid | TC_U32_NODE(handle);
|
||||
err = idr_alloc_u32(&ht->handle_idr, NULL, &handle,
|
||||
handle, GFP_KERNEL);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* The user did not give us a handle; lets just generate one
|
||||
* from the table's pool of nodeids.
|
||||
*/
|
||||
handle = gen_new_kid(ht, htid);
|
||||
}
|
||||
|
||||
if (tb[TCA_U32_SEL] == NULL) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Selector not specified");
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
if (parent == NULL)
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -130,6 +130,97 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
|
||||
struct nlattr *opt,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mqprio_sched *priv = qdisc_priv(sch);
|
||||
struct nlattr *tb[TCA_MQPRIO_MAX + 1];
|
||||
struct nlattr *attr;
|
||||
int i, rem, err;
|
||||
|
||||
err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
|
||||
sizeof(*qopt));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!qopt->hw) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MODE]) {
|
||||
priv->flags |= TC_MQPRIO_F_MODE;
|
||||
priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_SHAPER]) {
|
||||
priv->flags |= TC_MQPRIO_F_SHAPER;
|
||||
priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MIN_RATE64]) {
|
||||
if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
|
||||
"min_rate accepted only when shaper is in bw_rlimit mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
|
||||
rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr,
|
||||
"Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nla_len(attr) != sizeof(u64)) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr,
|
||||
"Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (i >= qopt->num_tc)
|
||||
break;
|
||||
priv->min_rate[i] = *(u64 *)nla_data(attr);
|
||||
i++;
|
||||
}
|
||||
priv->flags |= TC_MQPRIO_F_MIN_RATE;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MAX_RATE64]) {
|
||||
if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
|
||||
"max_rate accepted only when shaper is in bw_rlimit mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
|
||||
rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr,
|
||||
"Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nla_len(attr) != sizeof(u64)) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr,
|
||||
"Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (i >= qopt->num_tc)
|
||||
break;
|
||||
priv->max_rate[i] = *(u64 *)nla_data(attr);
|
||||
i++;
|
||||
}
|
||||
priv->flags |= TC_MQPRIO_F_MAX_RATE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
|
|
@ -139,9 +230,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
struct Qdisc *qdisc;
|
||||
int i, err = -EOPNOTSUPP;
|
||||
struct tc_mqprio_qopt *qopt = NULL;
|
||||
struct nlattr *tb[TCA_MQPRIO_MAX + 1];
|
||||
struct nlattr *attr;
|
||||
int rem;
|
||||
int len;
|
||||
|
||||
BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
|
||||
|
|
@ -166,55 +254,9 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
|
||||
len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
|
||||
if (len > 0) {
|
||||
err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
|
||||
sizeof(*qopt));
|
||||
if (err < 0)
|
||||
err = mqprio_parse_nlattr(sch, qopt, opt, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!qopt->hw)
|
||||
return -EINVAL;
|
||||
|
||||
if (tb[TCA_MQPRIO_MODE]) {
|
||||
priv->flags |= TC_MQPRIO_F_MODE;
|
||||
priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_SHAPER]) {
|
||||
priv->flags |= TC_MQPRIO_F_SHAPER;
|
||||
priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MIN_RATE64]) {
|
||||
if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
|
||||
return -EINVAL;
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
|
||||
rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
|
||||
return -EINVAL;
|
||||
if (i >= qopt->num_tc)
|
||||
break;
|
||||
priv->min_rate[i] = *(u64 *)nla_data(attr);
|
||||
i++;
|
||||
}
|
||||
priv->flags |= TC_MQPRIO_F_MIN_RATE;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MAX_RATE64]) {
|
||||
if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
|
||||
return -EINVAL;
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
|
||||
rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
|
||||
return -EINVAL;
|
||||
if (i >= qopt->num_tc)
|
||||
break;
|
||||
priv->max_rate[i] = *(u64 *)nla_data(attr);
|
||||
i++;
|
||||
}
|
||||
priv->flags |= TC_MQPRIO_F_MAX_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* pre-allocate qdisc, attachment can't fail */
|
||||
|
|
|
|||
|
|
@ -773,12 +773,10 @@ static void dist_free(struct disttable *d)
|
|||
* signed 16 bit values.
|
||||
*/
|
||||
|
||||
static int get_dist_table(struct Qdisc *sch, struct disttable **tbl,
|
||||
const struct nlattr *attr)
|
||||
static int get_dist_table(struct disttable **tbl, const struct nlattr *attr)
|
||||
{
|
||||
size_t n = nla_len(attr)/sizeof(__s16);
|
||||
const __s16 *data = nla_data(attr);
|
||||
spinlock_t *root_lock;
|
||||
struct disttable *d;
|
||||
int i;
|
||||
|
||||
|
|
@ -793,13 +791,7 @@ static int get_dist_table(struct Qdisc *sch, struct disttable **tbl,
|
|||
for (i = 0; i < n; i++)
|
||||
d->table[i] = data[i];
|
||||
|
||||
root_lock = qdisc_root_sleeping_lock(sch);
|
||||
|
||||
spin_lock_bh(root_lock);
|
||||
swap(*tbl, d);
|
||||
spin_unlock_bh(root_lock);
|
||||
|
||||
dist_free(d);
|
||||
*tbl = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -956,6 +948,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
{
|
||||
struct netem_sched_data *q = qdisc_priv(sch);
|
||||
struct nlattr *tb[TCA_NETEM_MAX + 1];
|
||||
struct disttable *delay_dist = NULL;
|
||||
struct disttable *slot_dist = NULL;
|
||||
struct tc_netem_qopt *qopt;
|
||||
struct clgstate old_clg;
|
||||
int old_loss_model = CLG_RANDOM;
|
||||
|
|
@ -969,6 +963,18 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (tb[TCA_NETEM_DELAY_DIST]) {
|
||||
ret = get_dist_table(&delay_dist, tb[TCA_NETEM_DELAY_DIST]);
|
||||
if (ret)
|
||||
goto table_free;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_SLOT_DIST]) {
|
||||
ret = get_dist_table(&slot_dist, tb[TCA_NETEM_SLOT_DIST]);
|
||||
if (ret)
|
||||
goto table_free;
|
||||
}
|
||||
|
||||
sch_tree_lock(sch);
|
||||
/* backup q->clg and q->loss_model */
|
||||
old_clg = q->clg;
|
||||
|
|
@ -978,26 +984,17 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
ret = get_loss_clg(q, tb[TCA_NETEM_LOSS]);
|
||||
if (ret) {
|
||||
q->loss_model = old_loss_model;
|
||||
q->clg = old_clg;
|
||||
goto unlock;
|
||||
}
|
||||
} else {
|
||||
q->loss_model = CLG_RANDOM;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_DELAY_DIST]) {
|
||||
ret = get_dist_table(sch, &q->delay_dist,
|
||||
tb[TCA_NETEM_DELAY_DIST]);
|
||||
if (ret)
|
||||
goto get_table_failure;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_SLOT_DIST]) {
|
||||
ret = get_dist_table(sch, &q->slot_dist,
|
||||
tb[TCA_NETEM_SLOT_DIST]);
|
||||
if (ret)
|
||||
goto get_table_failure;
|
||||
}
|
||||
|
||||
if (delay_dist)
|
||||
swap(q->delay_dist, delay_dist);
|
||||
if (slot_dist)
|
||||
swap(q->slot_dist, slot_dist);
|
||||
sch->limit = qopt->limit;
|
||||
|
||||
q->latency = PSCHED_TICKS2NS(qopt->latency);
|
||||
|
|
@ -1047,17 +1044,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
|
||||
unlock:
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
table_free:
|
||||
dist_free(delay_dist);
|
||||
dist_free(slot_dist);
|
||||
return ret;
|
||||
|
||||
get_table_failure:
|
||||
/* recover clg and loss_model, in case of
|
||||
* q->clg and q->loss_model were modified
|
||||
* in get_loss_clg()
|
||||
*/
|
||||
q->clg = old_clg;
|
||||
q->loss_model = old_loss_model;
|
||||
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
static int netem_init(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ static struct Qdisc_ops plug_qdisc_ops __read_mostly = {
|
|||
.priv_size = sizeof(struct plug_sched_data),
|
||||
.enqueue = plug_enqueue,
|
||||
.dequeue = plug_dequeue,
|
||||
.peek = qdisc_peek_head,
|
||||
.peek = qdisc_peek_dequeued,
|
||||
.init = plug_init,
|
||||
.change = plug_change,
|
||||
.reset = qdisc_reset_queue,
|
||||
|
|
|
|||
|
|
@ -375,8 +375,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight,
|
|||
u32 lmax)
|
||||
{
|
||||
struct qfq_sched *q = qdisc_priv(sch);
|
||||
struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight);
|
||||
struct qfq_aggregate *new_agg;
|
||||
|
||||
/* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */
|
||||
if (lmax > (1UL << QFQ_MTU_SHIFT))
|
||||
return -EINVAL;
|
||||
|
||||
new_agg = qfq_find_agg(q, lmax, weight);
|
||||
if (new_agg == NULL) { /* create new aggregate */
|
||||
new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC);
|
||||
if (new_agg == NULL)
|
||||
|
|
@ -970,10 +975,13 @@ static void qfq_update_eligible(struct qfq_sched *q)
|
|||
}
|
||||
|
||||
/* Dequeue head packet of the head class in the DRR queue of the aggregate. */
|
||||
static void agg_dequeue(struct qfq_aggregate *agg,
|
||||
struct qfq_class *cl, unsigned int len)
|
||||
static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg,
|
||||
struct qfq_class *cl, unsigned int len)
|
||||
{
|
||||
qdisc_dequeue_peeked(cl->qdisc);
|
||||
struct sk_buff *skb = qdisc_dequeue_peeked(cl->qdisc);
|
||||
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
cl->deficit -= (int) len;
|
||||
|
||||
|
|
@ -983,6 +991,8 @@ static void agg_dequeue(struct qfq_aggregate *agg,
|
|||
cl->deficit += agg->lmax;
|
||||
list_move_tail(&cl->alist, &agg->active);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
|
||||
|
|
@ -1128,11 +1138,18 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
|
|||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
qdisc_qstats_backlog_dec(sch, skb);
|
||||
sch->q.qlen--;
|
||||
|
||||
skb = agg_dequeue(in_serv_agg, cl, len);
|
||||
|
||||
if (!skb) {
|
||||
sch->q.qlen++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdisc_qstats_backlog_dec(sch, skb);
|
||||
qdisc_bstats_update(sch, skb);
|
||||
|
||||
agg_dequeue(in_serv_agg, cl, len);
|
||||
/* If lmax is lowered, through qfq_change_class, for a class
|
||||
* owning pending packets with larger size than the new value
|
||||
* of lmax, then the following condition may hold.
|
||||
|
|
|
|||
|
|
@ -362,9 +362,9 @@ static void sctp_auto_asconf_init(struct sctp_sock *sp)
|
|||
struct net *net = sock_net(&sp->inet.sk);
|
||||
|
||||
if (net->sctp.default_auto_asconf) {
|
||||
spin_lock(&net->sctp.addr_wq_lock);
|
||||
spin_lock_bh(&net->sctp.addr_wq_lock);
|
||||
list_add_tail(&sp->auto_asconf_list, &net->sctp.auto_asconf_splist);
|
||||
spin_unlock(&net->sctp.addr_wq_lock);
|
||||
spin_unlock_bh(&net->sctp.addr_wq_lock);
|
||||
sp->do_auto_asconf = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -728,12 +728,6 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
|
|||
dprintk("svc: socket %p TCP (listen) state change %d\n",
|
||||
sk, sk->sk_state);
|
||||
|
||||
if (svsk) {
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_odata(sk);
|
||||
}
|
||||
|
||||
/*
|
||||
* This callback may called twice when a new connection
|
||||
* is established as a child socket inherits everything
|
||||
|
|
@ -742,15 +736,20 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
|
|||
* when one of child sockets become ESTABLISHED.
|
||||
* 2) data_ready method of the child socket may be called
|
||||
* when it receives data before the socket is accepted.
|
||||
* In case of 2, we should ignore it silently.
|
||||
* In case of 2, we should ignore it silently and DO NOT
|
||||
* dereference svsk.
|
||||
*/
|
||||
if (sk->sk_state == TCP_LISTEN) {
|
||||
if (svsk) {
|
||||
set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
|
||||
svc_xprt_enqueue(&svsk->sk_xprt);
|
||||
} else
|
||||
printk("svc: socket %p: no user data\n", sk);
|
||||
}
|
||||
if (sk->sk_state != TCP_LISTEN)
|
||||
return;
|
||||
|
||||
if (svsk) {
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_odata(sk);
|
||||
set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
|
||||
svc_xprt_enqueue(&svsk->sk_xprt);
|
||||
} else
|
||||
printk("svc: socket %p: no user data\n", sk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -701,7 +701,7 @@ static int unix_set_peek_off(struct sock *sk, int val)
|
|||
if (mutex_lock_interruptible(&u->iolock))
|
||||
return -EINTR;
|
||||
|
||||
sk->sk_peek_off = val;
|
||||
WRITE_ONCE(sk->sk_peek_off, val);
|
||||
mutex_unlock(&u->iolock);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1979,6 +1979,7 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
|
|||
|
||||
if (false) {
|
||||
alloc_skb:
|
||||
spin_unlock(&other->sk_receive_queue.lock);
|
||||
unix_state_unlock(other);
|
||||
mutex_unlock(&unix_sk(other)->iolock);
|
||||
newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
|
||||
|
|
@ -2018,6 +2019,7 @@ alloc_skb:
|
|||
init_scm = false;
|
||||
}
|
||||
|
||||
spin_lock(&other->sk_receive_queue.lock);
|
||||
skb = skb_peek_tail(&other->sk_receive_queue);
|
||||
if (tail && tail == skb) {
|
||||
skb = newskb;
|
||||
|
|
@ -2048,14 +2050,11 @@ alloc_skb:
|
|||
refcount_add(size, &sk->sk_wmem_alloc);
|
||||
|
||||
if (newskb) {
|
||||
err = unix_scm_to_skb(&scm, skb, false);
|
||||
if (err)
|
||||
goto err_state_unlock;
|
||||
spin_lock(&other->sk_receive_queue.lock);
|
||||
unix_scm_to_skb(&scm, skb, false);
|
||||
__skb_queue_tail(&other->sk_receive_queue, newskb);
|
||||
spin_unlock(&other->sk_receive_queue.lock);
|
||||
}
|
||||
|
||||
spin_unlock(&other->sk_receive_queue.lock);
|
||||
unix_state_unlock(other);
|
||||
mutex_unlock(&unix_sk(other)->iolock);
|
||||
|
||||
|
|
|
|||
|
|
@ -223,117 +223,152 @@ bool cfg80211_is_element_inherited(const struct element *elem,
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_is_element_inherited);
|
||||
|
||||
static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
|
||||
const u8 *subelement, size_t subie_len,
|
||||
u8 *new_ie, gfp_t gfp)
|
||||
static size_t cfg80211_copy_elem_with_frags(const struct element *elem,
|
||||
const u8 *ie, size_t ie_len,
|
||||
u8 **pos, u8 *buf, size_t buf_len)
|
||||
{
|
||||
u8 *pos, *tmp;
|
||||
const u8 *tmp_old, *tmp_new;
|
||||
const struct element *non_inherit_elem;
|
||||
u8 *sub_copy;
|
||||
|
||||
/* copy subelement as we need to change its content to
|
||||
* mark an ie after it is processed.
|
||||
*/
|
||||
sub_copy = kmemdup(subelement, subie_len, gfp);
|
||||
if (!sub_copy)
|
||||
if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len ||
|
||||
elem->data + elem->datalen > ie + ie_len))
|
||||
return 0;
|
||||
|
||||
pos = &new_ie[0];
|
||||
if (elem->datalen + 2 > buf + buf_len - *pos)
|
||||
return 0;
|
||||
|
||||
/* set new ssid */
|
||||
tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
|
||||
if (tmp_new) {
|
||||
memcpy(pos, tmp_new, tmp_new[1] + 2);
|
||||
pos += (tmp_new[1] + 2);
|
||||
memcpy(*pos, elem, elem->datalen + 2);
|
||||
*pos += elem->datalen + 2;
|
||||
|
||||
/* Finish if it is not fragmented */
|
||||
if (elem->datalen != 255)
|
||||
return *pos - buf;
|
||||
|
||||
ie_len = ie + ie_len - elem->data - elem->datalen;
|
||||
ie = (const u8 *)elem->data + elem->datalen;
|
||||
|
||||
for_each_element(elem, ie, ie_len) {
|
||||
if (elem->id != WLAN_EID_FRAGMENT)
|
||||
break;
|
||||
|
||||
if (elem->datalen + 2 > buf + buf_len - *pos)
|
||||
return 0;
|
||||
|
||||
memcpy(*pos, elem, elem->datalen + 2);
|
||||
*pos += elem->datalen + 2;
|
||||
|
||||
if (elem->datalen != 255)
|
||||
break;
|
||||
}
|
||||
|
||||
/* get non inheritance list if exists */
|
||||
non_inherit_elem =
|
||||
cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
|
||||
sub_copy, subie_len);
|
||||
return *pos - buf;
|
||||
}
|
||||
|
||||
/* go through IEs in ie (skip SSID) and subelement,
|
||||
* merge them into new_ie
|
||||
static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
|
||||
const u8 *subie, size_t subie_len,
|
||||
u8 *new_ie, size_t new_ie_len)
|
||||
{
|
||||
const struct element *non_inherit_elem, *parent, *sub;
|
||||
u8 *pos = new_ie;
|
||||
u8 id, ext_id;
|
||||
unsigned int match_len;
|
||||
|
||||
non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
|
||||
subie, subie_len);
|
||||
|
||||
/* We copy the elements one by one from the parent to the generated
|
||||
* elements.
|
||||
* If they are not inherited (included in subie or in the non
|
||||
* inheritance element), then we copy all occurrences the first time
|
||||
* we see this element type.
|
||||
*/
|
||||
tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
|
||||
tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
|
||||
for_each_element(parent, ie, ielen) {
|
||||
if (parent->id == WLAN_EID_FRAGMENT)
|
||||
continue;
|
||||
|
||||
if (parent->id == WLAN_EID_EXTENSION) {
|
||||
if (parent->datalen < 1)
|
||||
continue;
|
||||
|
||||
id = WLAN_EID_EXTENSION;
|
||||
ext_id = parent->data[0];
|
||||
match_len = 1;
|
||||
} else {
|
||||
id = parent->id;
|
||||
match_len = 0;
|
||||
}
|
||||
|
||||
/* Find first occurrence in subie */
|
||||
sub = cfg80211_find_elem_match(id, subie, subie_len,
|
||||
&ext_id, match_len, 0);
|
||||
|
||||
/* Copy from parent if not in subie and inherited */
|
||||
if (!sub &&
|
||||
cfg80211_is_element_inherited(parent, non_inherit_elem)) {
|
||||
if (!cfg80211_copy_elem_with_frags(parent,
|
||||
ie, ielen,
|
||||
&pos, new_ie,
|
||||
new_ie_len))
|
||||
return 0;
|
||||
|
||||
while (tmp_old + 2 - ie <= ielen &&
|
||||
tmp_old + tmp_old[1] + 2 - ie <= ielen) {
|
||||
if (tmp_old[0] == 0) {
|
||||
tmp_old++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tmp_old[0] == WLAN_EID_EXTENSION)
|
||||
tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
|
||||
subie_len);
|
||||
else
|
||||
tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
|
||||
subie_len);
|
||||
/* Already copied if an earlier element had the same type */
|
||||
if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie,
|
||||
&ext_id, match_len, 0))
|
||||
continue;
|
||||
|
||||
if (!tmp) {
|
||||
const struct element *old_elem = (void *)tmp_old;
|
||||
/* Not inheriting, copy all similar elements from subie */
|
||||
while (sub) {
|
||||
if (!cfg80211_copy_elem_with_frags(sub,
|
||||
subie, subie_len,
|
||||
&pos, new_ie,
|
||||
new_ie_len))
|
||||
return 0;
|
||||
|
||||
/* ie in old ie but not in subelement */
|
||||
if (cfg80211_is_element_inherited(old_elem,
|
||||
non_inherit_elem)) {
|
||||
memcpy(pos, tmp_old, tmp_old[1] + 2);
|
||||
pos += tmp_old[1] + 2;
|
||||
}
|
||||
} else {
|
||||
/* ie in transmitting ie also in subelement,
|
||||
* copy from subelement and flag the ie in subelement
|
||||
* as copied (by setting eid field to WLAN_EID_SSID,
|
||||
* which is skipped anyway).
|
||||
* For vendor ie, compare OUI + type + subType to
|
||||
* determine if they are the same ie.
|
||||
*/
|
||||
if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
|
||||
if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
|
||||
!memcmp(tmp_old + 2, tmp + 2, 5)) {
|
||||
/* same vendor ie, copy from
|
||||
* subelement
|
||||
*/
|
||||
memcpy(pos, tmp, tmp[1] + 2);
|
||||
pos += tmp[1] + 2;
|
||||
tmp[0] = WLAN_EID_SSID;
|
||||
} else {
|
||||
memcpy(pos, tmp_old, tmp_old[1] + 2);
|
||||
pos += tmp_old[1] + 2;
|
||||
}
|
||||
} else {
|
||||
/* copy ie from subelement into new ie */
|
||||
memcpy(pos, tmp, tmp[1] + 2);
|
||||
pos += tmp[1] + 2;
|
||||
tmp[0] = WLAN_EID_SSID;
|
||||
}
|
||||
sub = cfg80211_find_elem_match(id,
|
||||
sub->data + sub->datalen,
|
||||
subie_len + subie -
|
||||
(sub->data +
|
||||
sub->datalen),
|
||||
&ext_id, match_len, 0);
|
||||
}
|
||||
|
||||
if (tmp_old + tmp_old[1] + 2 - ie == ielen)
|
||||
break;
|
||||
|
||||
tmp_old += tmp_old[1] + 2;
|
||||
}
|
||||
|
||||
/* go through subelement again to check if there is any ie not
|
||||
* copied to new ie, skip ssid, capability, bssid-index ie
|
||||
/* The above misses elements that are included in subie but not in the
|
||||
* parent, so do a pass over subie and append those.
|
||||
* Skip the non-tx BSSID caps and non-inheritance element.
|
||||
*/
|
||||
tmp_new = sub_copy;
|
||||
while (tmp_new + 2 - sub_copy <= subie_len &&
|
||||
tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
|
||||
if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
|
||||
tmp_new[0] == WLAN_EID_SSID)) {
|
||||
memcpy(pos, tmp_new, tmp_new[1] + 2);
|
||||
pos += tmp_new[1] + 2;
|
||||
for_each_element(sub, subie, subie_len) {
|
||||
if (sub->id == WLAN_EID_NON_TX_BSSID_CAP)
|
||||
continue;
|
||||
|
||||
if (sub->id == WLAN_EID_FRAGMENT)
|
||||
continue;
|
||||
|
||||
if (sub->id == WLAN_EID_EXTENSION) {
|
||||
if (sub->datalen < 1)
|
||||
continue;
|
||||
|
||||
id = WLAN_EID_EXTENSION;
|
||||
ext_id = sub->data[0];
|
||||
match_len = 1;
|
||||
|
||||
if (ext_id == WLAN_EID_EXT_NON_INHERITANCE)
|
||||
continue;
|
||||
} else {
|
||||
id = sub->id;
|
||||
match_len = 0;
|
||||
}
|
||||
if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
|
||||
break;
|
||||
tmp_new += tmp_new[1] + 2;
|
||||
|
||||
/* Processed if one was included in the parent */
|
||||
if (cfg80211_find_elem_match(id, ie, ielen,
|
||||
&ext_id, match_len, 0))
|
||||
continue;
|
||||
|
||||
if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len,
|
||||
&pos, new_ie, new_ie_len))
|
||||
return 0;
|
||||
}
|
||||
|
||||
kfree(sub_copy);
|
||||
return pos - new_ie;
|
||||
}
|
||||
|
||||
|
|
@ -1659,7 +1694,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
|
|||
new_ie_len = cfg80211_gen_new_ie(ie, ielen,
|
||||
profile,
|
||||
profile_len, new_ie,
|
||||
gfp);
|
||||
IEEE80211_MAX_DATA_LEN);
|
||||
if (!new_ie_len)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -796,6 +796,12 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
|
|||
}
|
||||
}
|
||||
|
||||
/* Sanity-check to ensure we never end up _allocating_ zero
|
||||
* bytes of data for extra.
|
||||
*/
|
||||
if (extra_size <= 0)
|
||||
return -EFAULT;
|
||||
|
||||
/* kzalloc() ensures NULL-termination for essid_compat. */
|
||||
extra = kzalloc(extra_size, GFP_KERNEL);
|
||||
if (!extra)
|
||||
|
|
|
|||
|
|
@ -613,6 +613,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
|||
struct sock *sk = sock->sk;
|
||||
struct xdp_sock *xs = xdp_sk(sk);
|
||||
struct net_device *dev;
|
||||
int bound_dev_if;
|
||||
u32 flags, qid;
|
||||
int err = 0;
|
||||
|
||||
|
|
@ -626,6 +627,10 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
|||
XDP_USE_NEED_WAKEUP))
|
||||
return -EINVAL;
|
||||
|
||||
bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
|
||||
if (bound_dev_if && bound_dev_if != sxdp->sxdp_ifindex)
|
||||
return -EINVAL;
|
||||
|
||||
rtnl_lock();
|
||||
mutex_lock(&xs->mutex);
|
||||
if (xs->state != XSK_READY) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue