* refs/heads/tmp-443485d:
Linux 4.19.146
gcov: add support for GCC 10.1
usb: typec: ucsi: acpi: Check the _DEP dependencies
usb: Fix out of sync data toggle if a configured device is reconfigured
USB: serial: option: add support for SIM7070/SIM7080/SIM7090 modules
USB: serial: option: support dynamic Quectel USB compositions
USB: serial: ftdi_sio: add IDs for Xsens Mti USB converter
usb: core: fix slab-out-of-bounds Read in read_descriptors
phy: qcom-qmp: Use correct values for ipq8074 PCIe Gen2 PHY init
staging: greybus: audio: fix uninitialized value issue
video: fbdev: fix OOB read in vga_8planes_imageblit()
ARM: dts: vfxxx: Add syscon compatible with OCOTP
KVM: VMX: Don't freeze guest when event delivery causes an APIC-access exit
fbcon: remove now unusued 'softback_lines' cursor() argument
fbcon: remove soft scrollback code
vgacon: remove software scrollback support
RDMA/rxe: Fix the parent sysfs read when the interface has 15 chars
rbd: require global CAP_SYS_ADMIN for mapping and unmapping
drm/msm: Disable preemption on all 5xx targets
drm/tve200: Stabilize enable/disable
scsi: target: iscsi: Fix hang in iscsit_access_np() when getting tpg->np_login_sem
scsi: target: iscsi: Fix data digest calculation
regulator: push allocation in set_consumer_device_supply() out of lock
btrfs: fix wrong address when faulting in pages in the search ioctl
btrfs: fix lockdep splat in add_missing_dev
btrfs: require only sector size alignment for parent eb bytenr
staging: wlan-ng: fix out of bounds read in prism2sta_probe_usb()
iio:accel:mma8452: Fix timestamp alignment and prevent data leak.
iio:accel:mma7455: Fix timestamp alignment and prevent data leak.
iio: accel: kxsd9: Fix alignment of local buffer.
iio:chemical:ccs811: Fix timestamp alignment and prevent data leak.
iio:light:max44000 Fix timestamp alignment and prevent data leak.
iio:magnetometer:ak8975 Fix alignment and data leak issues.
iio:adc:ti-adc081c Fix alignment and data leak issues
iio:adc:max1118 Fix alignment of timestamp and data leak issues
iio:adc:ina2xx Fix timestamp alignment issue.
iio:adc:ti-adc084s021 Fix alignment and data leak issues.
iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak.
iio:light:ltr501 Fix timestamp alignment issue.
iio: adc: ti-ads1015: fix conversion when CONFIG_PM is not set
iio: adc: mcp3422: fix locking on error path
iio: adc: mcp3422: fix locking scope
gcov: Disable gcov build with GCC 10
iommu/amd: Do not use IOMMUv2 functionality when SME is active
drm/amdgpu: Fix bug in reporting voltage for CIK
ALSA: hda: fix a runtime pm issue in SOF when integrated GPU is disabled
cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled
cpufreq: intel_pstate: Refuse to turn off with HWP enabled
ARC: [plat-hsdk]: Switch ethernet phy-mode to rgmii-id
HID: elan: Fix memleak in elan_input_configured
drivers/net/wan/hdlc_cisco: Add hard_header_len
HID: quirks: Set INCREMENT_USAGE_ON_DUPLICATE for all Saitek X52 devices
nvme-rdma: serialize controller teardown sequences
nvme-fabrics: don't check state NVME_CTRL_NEW for request acceptance
irqchip/eznps: Fix build error for !ARC700 builds
xfs: initialize the shortform attr header padding entry
drivers/net/wan/lapbether: Set network_header before transmitting
ALSA: hda: Fix 2 channel swapping for Tegra
firestream: Fix memleak in fs_open
NFC: st95hf: Fix memleak in st95hf_in_send_cmd
drivers/net/wan/lapbether: Added needed_tailroom
netfilter: conntrack: allow sctp hearbeat after connection re-use
dmaengine: acpi: Put the CSRT table after using it
ARC: HSDK: wireup perf irq
arm64: dts: ns2: Fixed QSPI compatible string
ARM: dts: BCM5301X: Fixed QSPI compatible string
ARM: dts: NSP: Fixed QSPI compatible string
ARM: dts: bcm: HR2: Fixed QSPI compatible string
mmc: sdhci-msm: Add retries when all tuning phases are found valid
RDMA/core: Fix reported speed and width
scsi: libsas: Set data_dir as DMA_NONE if libata marks qc as NODATA
drm/sun4i: Fix dsi dcs long write function
RDMA/bnxt_re: Do not report transparent vlan from QP1
RDMA/rxe: Drop pointless checks in rxe_init_ports
RDMA/rxe: Fix memleak in rxe_mem_init_user
ARM: dts: ls1021a: fix QuadSPI-memory reg range
ARM: dts: socfpga: fix register entry for timer3 on Arria10
ARM: dts: logicpd-som-lv-baseboard: Fix broken audio
ARM: dts: logicpd-torpedo-baseboard: Fix broken audio
ANDROID: ABI: refresh with latest libabigail 94f5d4ae
Linux 4.19.145
net/mlx5e: Don't support phys switch id if not in switchdev mode
net: disable netpoll on fresh napis
tipc: fix shutdown() of connectionless socket
sctp: not disable bh in the whole sctp_get_port_local()
net: usb: dm9601: Add USB ID of Keenetic Plus DSL
netlabel: fix problems with mapping removal
block: ensure bdi->io_pages is always initialized
ALSA; firewire-tascam: exclude Tascam FE-8 from detection
FROMGIT: binder: print warnings when detecting oneway spamming.
Linux 4.19.144
net: usb: Fix uninit-was-stored issue in asix_read_phy_addr()
cfg80211: regulatory: reject invalid hints
mm/hugetlb: fix a race between hugetlb sysctl handlers
checkpatch: fix the usage of capture group ( ... )
vfio/pci: Fix SR-IOV VF handling with MMIO blocking
KVM: arm64: Set HCR_EL2.PTW to prevent AT taking synchronous exception
KVM: arm64: Survive synchronous exceptions caused by AT instructions
KVM: arm64: Defer guest entry when an asynchronous exception is pending
KVM: arm64: Add kvm_extable for vaxorcism code
mm: slub: fix conversion of freelist_corrupted()
dm thin metadata: Avoid returning cmd->bm wild pointer on error
dm cache metadata: Avoid returning cmd->bm wild pointer on error
dm writecache: handle DAX to partitions on persistent memory correctly
libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks
block: allow for_each_bvec to support zero len bvec
affs: fix basic permission bits to actually work
media: rc: uevent sysfs file races with rc_unregister_device()
media: rc: do not access device via sysfs after rc_unregister_device()
ALSA: hda - Fix silent audio output and corrupted input on MSI X570-A PRO
ALSA: firewire-digi00x: exclude Avid Adrenaline from detection
ALSA: hda/hdmi: always check pin power status in i915 pin fixup
ALSA: pcm: oss: Remove superfluous WARN_ON() for mulaw sanity check
ALSA: ca0106: fix error code handling
usb: qmi_wwan: add D-Link DWM-222 A2 device ID
net: usb: qmi_wwan: add Telit 0x1050 composition
btrfs: fix potential deadlock in the search ioctl
uaccess: Add non-pagefault user-space write function
uaccess: Add non-pagefault user-space read functions
btrfs: set the lockdep class for log tree extent buffers
btrfs: Remove extraneous extent_buffer_get from tree_mod_log_rewind
btrfs: Remove redundant extent_buffer_get in get_old_root
vfio-pci: Invalidate mmaps and block MMIO access on disabled memory
vfio-pci: Fault mmaps to enable vma tracking
vfio/type1: Support faulting PFNMAP vmas
btrfs: drop path before adding new uuid tree entry
xfs: don't update mtime on COW faults
ext2: don't update mtime on COW faults
include/linux/log2.h: add missing () around n in roundup_pow_of_two()
thermal: ti-soc-thermal: Fix bogus thermal shutdowns for omap4430
iommu/vt-d: Serialize IOMMU GCMD register modifications
x86, fakenuma: Fix invalid starting node ID
tg3: Fix soft lockup when tg3_reset_task() fails.
perf jevents: Fix suspicious code in fixregex()
xfs: fix xfs_bmap_validate_extent_raw when checking attr fork of rt files
net: gemini: Fix another missing clk_disable_unprepare() in probe
fix regression in "epoll: Keep a reference on files added to the check list"
net: ethernet: mlx4: Fix memory allocation in mlx4_buddy_init()
perf tools: Correct SNOOPX field offset
nvmet-fc: Fix a missed _irqsave version of spin_lock in 'nvmet_fc_fod_op_done()'
netfilter: nfnetlink: nfnetlink_unicast() reports EAGAIN instead of ENOBUFS
selftests/bpf: Fix massive output from test_maps
bnxt: don't enable NAPI until rings are ready
xfs: fix boundary test in xfs_attr_shortform_verify
bnxt_en: fix HWRM error when querying VF temperature
bnxt_en: Fix PCI AER error recovery flow
bnxt_en: Check for zero dir entries in NVRAM.
bnxt_en: Don't query FW when netif_running() is false.
gtp: add GTPA_LINK info to msg sent to userspace
dmaengine: pl330: Fix burst length if burst size is smaller than bus width
net: arc_emac: Fix memleak in arc_mdio_probe
ravb: Fixed to be able to unload modules
net: systemport: Fix memleak in bcm_sysport_probe
net: hns: Fix memleak in hns_nic_dev_probe
netfilter: nf_tables: fix destination register zeroing
netfilter: nf_tables: incorrect enum nft_list_attributes definition
netfilter: nf_tables: add NFTA_SET_USERDATA if not null
MIPS: BMIPS: Also call bmips_cpu_setup() for secondary cores
MIPS: mm: BMIPS5000 has inclusive physical caches
dmaengine: at_hdmac: check return value of of_find_device_by_node() in at_dma_xlate()
batman-adv: bla: use netif_rx_ni when not in interrupt context
batman-adv: Fix own OGM check in aggregated OGMs
batman-adv: Avoid uninitialized chaddr when handling DHCP
dmaengine: of-dma: Fix of_dma_router_xlate's of_dma_xlate handling
xen/xenbus: Fix granting of vmalloc'd memory
s390: don't trace preemption in percpu macros
cpuidle: Fixup IRQ state
ceph: don't allow setlease on cephfs
drm/msm/a6xx: fix gmu start on newer firmware
nvmet: Disable keep-alive timer when kato is cleared to 0h
hwmon: (applesmc) check status earlier.
drm/msm: add shutdown support for display platform_driver
tty: serial: qcom_geni_serial: Drop __init from qcom_geni_console_setup
scsi: target: tcmu: Optimize use of flush_dcache_page
scsi: target: tcmu: Fix size in calls to tcmu_flush_dcache_range
perf record/stat: Explicitly call out event modifiers in the documentation
HID: core: Sanitize event code and type when mapping input
HID: core: Correctly handle ReportSize being zero
Linux 4.19.143
ALSA: usb-audio: Update documentation comment for MS2109 quirk
HID: hiddev: Fix slab-out-of-bounds write in hiddev_ioctl_usage()
tpm: Unify the mismatching TPM space buffer sizes
usb: dwc3: gadget: Handle ZLP for sg requests
usb: dwc3: gadget: Fix handling ZLP
usb: dwc3: gadget: Don't setup more than requested
btrfs: check the right error variable in btrfs_del_dir_entries_in_log
usb: storage: Add unusual_uas entry for Sony PSZ drives
USB: cdc-acm: rework notification_buffer resizing
USB: gadget: u_f: Unbreak offset calculation in VLAs
USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()
USB: gadget: u_f: add overflow checks to VLA macros
usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe()
USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge
USB: quirks: Ignore duplicate endpoint on Sound Devices MixPre-D
USB: quirks: Add no-lpm quirk for another Raydium touchscreen
usb: uas: Add quirk for PNY Pro Elite
USB: yurex: Fix bad gfp argument
drm/amd/pm: correct Vega12 swctf limit setting
drm/amd/pm: correct Vega10 swctf limit setting
drm/amdgpu: Fix buffer overflow in INFO ioctl
irqchip/stm32-exti: Avoid losing interrupts due to clearing pending bits by mistake
genirq/matrix: Deal with the sillyness of for_each_cpu() on UP
device property: Fix the secondary firmware node handling in set_primary_fwnode()
PM: sleep: core: Fix the handling of pending runtime resume requests
xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed
xhci: Do warm-reset when both CAS and XDEV_RESUME are set
usb: host: xhci: fix ep context print mismatch in debugfs
XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.
writeback: Fix sync livelock due to b_dirty_time processing
writeback: Avoid skipping inode writeback
writeback: Protect inode->i_io_list with inode->i_lock
serial: 8250: change lock order in serial8250_do_startup()
serial: 8250_exar: Fix number of ports for Commtech PCIe cards
serial: pl011: Don't leak amba_ports entry on driver register error
serial: pl011: Fix oops on -EPROBE_DEFER
serial: samsung: Removes the IRQ not found warning
vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize()
vt: defer kfree() of vc_screenbuf in vc_do_resize()
USB: lvtest: return proper error code in probe
fbcon: prevent user font height or width change from causing potential out-of-bounds access
btrfs: fix space cache memory leak after transaction abort
btrfs: reset compression level for lzo on remount
blk-mq: order adding requests to hctx->dispatch and checking SCHED_RESTART
HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands
block: loop: set discard granularity and alignment for block device backed loop
powerpc/perf: Fix soft lockups due to missed interrupt accounting
net: gianfar: Add of_node_put() before goto statement
macvlan: validate setting of multiple remote source MAC addresses
Revert "scsi: qla2xxx: Fix crash on qla2x00_mailbox_command"
scsi: qla2xxx: Fix null pointer access during disconnect from subsystem
scsi: qla2xxx: Check if FW supports MQ before enabling
scsi: ufs: Clean up completed request without interrupt notification
scsi: ufs: Improve interrupt handling for shared interrupts
scsi: ufs: Fix possible infinite loop in ufshcd_hold
scsi: fcoe: Fix I/O path allocation
ASoC: wm8994: Avoid attempts to read unreadable registers
s390/cio: add cond_resched() in the slow_eval_known_fn() loop
spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate
fs: prevent BUG_ON in submit_bh_wbc()
ext4: correctly restore system zone info when remount fails
ext4: handle error of ext4_setup_system_zone() on remount
ext4: handle option set by mount flags correctly
jbd2: abort journal if free a async write error metadata buffer
ext4: handle read only external journal device
ext4: don't BUG on inconsistent journal feature
jbd2: make sure jh have b_transaction set in refile/unfile_buffer
usb: gadget: f_tcm: Fix some resource leaks in some error paths
i2c: rcar: in slave mode, clear NACK earlier
null_blk: fix passing of REQ_FUA flag in null_handle_rq
nvme-fc: Fix wrong return value in __nvme_fc_init_request()
drm/msm/adreno: fix updating ring fence
media: gpio-ir-tx: improve precision of transmitted signal due to scheduling
Revert "ath10k: fix DMA related firmware crashes on multiple devices"
efi: provide empty efi_enter_virtual_mode implementation
USB: sisusbvga: Fix a potential UB casued by left shifting a negative value
powerpc/spufs: add CONFIG_COREDUMP dependency
KVM: arm64: Fix symbol dependency in __hyp_call_panic_nvhe
EDAC/ie31200: Fallback if host bridge device is already initialized
scsi: fcoe: Memory leak fix in fcoe_sysfs_fcf_del()
ceph: fix potential mdsc use-after-free crash
scsi: iscsi: Do not put host in iscsi_set_flashnode_param()
btrfs: file: reserve qgroup space after the hole punch range is locked
locking/lockdep: Fix overflow in presentation of average lock-time
drm/nouveau: Fix reference count leak in nouveau_connector_detect
drm/nouveau: fix reference count leak in nv50_disp_atomic_commit
drm/nouveau/drm/noveau: fix reference count leak in nouveau_fbcon_open
f2fs: fix use-after-free issue
HID: quirks: add NOGET quirk for Logitech GROUP
cec-api: prevent leaking memory through hole in structure
mips/vdso: Fix resource leaks in genvdso.c
rtlwifi: rtl8192cu: Prevent leaking urb
ARM: dts: ls1021a: output PPS signal on FIPER2
PCI: Fix pci_create_slot() reference count leak
omapfb: fix multiple reference count leaks due to pm_runtime_get_sync
f2fs: fix error path in do_recover_data()
selftests/powerpc: Purge extra count_pmc() calls of ebb selftests
xfs: Don't allow logging of XFS_ISTALE inodes
scsi: lpfc: Fix shost refcount mismatch when deleting vport
drm/amdgpu/display: fix ref count leak when pm_runtime_get_sync fails
drm/amdgpu: fix ref count leak in amdgpu_display_crtc_set_config
drm/amd/display: fix ref count leak in amdgpu_drm_ioctl
drm/amdgpu: fix ref count leak in amdgpu_driver_open_kms
drm/radeon: fix multiple reference count leak
drm/amdkfd: Fix reference count leaks.
iommu/iova: Don't BUG on invalid PFNs
scsi: target: tcmu: Fix crash on ARM during cmd completion
blktrace: ensure our debugfs dir exists
media: pci: ttpci: av7110: fix possible buffer overflow caused by bad DMA value in debiirq()
powerpc/xive: Ignore kmemleak false positives
arm64: dts: qcom: msm8916: Pull down PDM GPIOs during sleep
mfd: intel-lpss: Add Intel Emmitsburg PCH PCI IDs
ASoC: tegra: Fix reference count leaks.
ASoC: img-parallel-out: Fix a reference count leak
ASoC: img: Fix a reference count leak in img_i2s_in_set_fmt
ALSA: pci: delete repeated words in comments
ipvlan: fix device features
net: ena: Make missed_tx stat incremental
tipc: fix uninit skb->data in tipc_nl_compat_dumpit()
net/smc: Prevent kernel-infoleak in __smc_diag_dump()
net: qrtr: fix usage of idr in port assignment to socket
net: Fix potential wrong skb->protocol in skb_vlan_untag()
gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY
powerpc/64s: Don't init FSCR_DSCR in __init_FSCR()
ANDROID: gki_defconfig: initialize locals with zeroes
UPSTREAM: security: allow using Clang's zero initialization for stack variables
Revert "binder: Prevent context manager from incrementing ref 0"
ANDROID: GKI: update the ABI xml
BACKPORT: recordmcount: support >64k sections
UPSTREAM: arm64: vdso: Build vDSO with -ffixed-x18
UPSTREAM: cgroup: Remove unused cgrp variable
UPSTREAM: cgroup: freezer: call cgroup_enter_frozen() with preemption disabled in ptrace_stop()
UPSTREAM: cgroup: freezer: fix frozen state inheritance
UPSTREAM: signal: unconditionally leave the frozen state in ptrace_stop()
BACKPORT: cgroup: cgroup v2 freezer
UPSTREAM: cgroup: implement __cgroup_task_count() helper
UPSTREAM: cgroup: rename freezer.c into legacy_freezer.c
UPSTREAM: cgroup: remove extra cgroup_migrate_finish() call
UPSTREAM: cgroup: saner refcounting for cgroup_root
UPSTREAM: cgroup: Add named hierarchy disabling to cgroup_no_v1 boot param
UPSTREAM: cgroup: remove unnecessary unlikely()
UPSTREAM: cgroup: Simplify cgroup_ancestor
Linux 4.19.142
KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set
KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
clk: Evict unregistered clks from parent caches
xen: don't reschedule in preemption off sections
mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible
do_epoll_ctl(): clean the failure exits up a bit
epoll: Keep a reference on files added to the check list
efi: add missed destroy_workqueue when efisubsys_init fails
powerpc/pseries: Do not initiate shutdown when system is running on UPS
net: dsa: b53: check for timeout
hv_netvsc: Fix the queue_mapping in netvsc_vf_xmit()
net: gemini: Fix missing free_netdev() in error path of gemini_ethernet_port_probe()
net: ena: Prevent reset after device destruction
bonding: fix active-backup failover for current ARP slave
afs: Fix NULL deref in afs_dynroot_depopulate()
RDMA/bnxt_re: Do not add user qps to flushlist
Fix build error when CONFIG_ACPI is not set/enabled:
efi: avoid error message when booting under Xen
kconfig: qconf: fix signal connection to invalid slots
kconfig: qconf: do not limit the pop-up menu to the first row
kvm: x86: Toggling CR4.PKE does not load PDPTEs in PAE mode
kvm: x86: Toggling CR4.SMAP does not load PDPTEs in PAE mode
vfio/type1: Add proper error unwind for vfio_iommu_replay()
ASoC: intel: Fix memleak in sst_media_open
ASoC: msm8916-wcd-analog: fix register Interrupt offset
s390/ptrace: fix storage key handling
s390/runtime_instrumentation: fix storage key handling
bonding: fix a potential double-unregister
bonding: show saner speed for broadcast mode
net: fec: correct the error path for regulator disable in probe
i40e: Fix crash during removing i40e driver
i40e: Set RX_ONLY mode for unicast promiscuous on VLAN
ASoC: q6routing: add dummy register read/write function
ext4: don't allow overlapping system zones
ext4: fix potential negative array index in do_split()
fs/signalfd.c: fix inconsistent return codes for signalfd4
alpha: fix annotation of io{read,write}{16,32}be()
xfs: Fix UBSAN null-ptr-deref in xfs_sysfs_init
tools/testing/selftests/cgroup/cgroup_util.c: cg_read_strcmp: fix null pointer dereference
virtio_ring: Avoid loop when vq is broken in virtqueue_poll
scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases
cpufreq: intel_pstate: Fix cpuinfo_max_freq when MSR_TURBO_RATIO_LIMIT is 0
ceph: fix use-after-free for fsc->mdsc
jffs2: fix UAF problem
xfs: fix inode quota reservation checks
svcrdma: Fix another Receive buffer leak
m68knommu: fix overwriting of bits in ColdFire V3 cache control
Input: psmouse - add a newline when printing 'proto' by sysfs
media: vpss: clean up resources in init
rtc: goldfish: Enable interrupt in set_alarm() when necessary
media: budget-core: Improve exception handling in budget_register()
scsi: target: tcmu: Fix crash in tcmu_flush_dcache_range on ARM
scsi: ufs: Add DELAY_BEFORE_LPM quirk for Micron devices
spi: Prevent adding devices below an unregistering controller
kthread: Do not preempt current task if it is going to call schedule()
drm/amd/display: fix pow() crashing when given base 0
scsi: zfcp: Fix use-after-free in request timeout handlers
jbd2: add the missing unlock_buffer() in the error path of jbd2_write_superblock()
ext4: fix checking of directory entry validity for inline directories
mm, page_alloc: fix core hung in free_pcppages_bulk()
mm: include CMA pages in lowmem_reserve at boot
kernel/relay.c: fix memleak on destroy relay channel
romfs: fix uninitialized memory leak in romfs_dev_read()
btrfs: sysfs: use NOFS for device creation
btrfs: inode: fix NULL pointer dereference if inode doesn't need compression
btrfs: Move free_pages_out label in inline extent handling branch in compress_file_range
btrfs: don't show full path of bind mounts in subvol=
btrfs: export helpers for subvolume name/id resolution
khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter()
khugepaged: khugepaged_test_exit() check mmget_still_valid()
perf probe: Fix memory leakage when the probe point is not found
drm/vgem: Replace opencoded version of drm_gem_dumb_map_offset()
ANDROID: tty: fix tty name overflow
ANDROID: Revert "PCI: Probe bridge window attributes once at enumeration-time"
Linux 4.19.141
drm/amdgpu: Fix bug where DPM is not enabled after hibernate and resume
drm: Added orientation quirk for ASUS tablet model T103HAF
arm64: dts: marvell: espressobin: add ethernet alias
khugepaged: retract_page_tables() remember to test exit
sh: landisk: Add missing initialization of sh_io_port_base
tools build feature: Quote CC and CXX for their arguments
perf bench mem: Always memset source before memcpy
ALSA: echoaudio: Fix potential Oops in snd_echo_resume()
mfd: dln2: Run event handler loop under spinlock
test_kmod: avoid potential double free in trigger_config_run_type()
fs/ufs: avoid potential u32 multiplication overflow
fs/minix: remove expected error message in block_to_path()
fs/minix: fix block limit check for V1 filesystems
fs/minix: set s_maxbytes correctly
nfs: Fix getxattr kernel panic and memory overflow
net: qcom/emac: add missed clk_disable_unprepare in error path of emac_clks_phase1_init
drm/vmwgfx: Fix two list_for_each loop exit tests
drm/vmwgfx: Use correct vmw_legacy_display_unit pointer
Input: sentelic - fix error return when fsp_reg_write fails
watchdog: initialize device before misc_register
scsi: lpfc: nvmet: Avoid hang / use-after-free again when destroying targetport
openrisc: Fix oops caused when dumping stack
i2c: rcar: avoid race when unregistering slave
tools build feature: Use CC and CXX from parent
pwm: bcm-iproc: handle clk_get_rate() return
clk: clk-atlas6: fix return value check in atlas6_clk_init()
i2c: rcar: slave: only send STOP event when we have been addressed
iommu/vt-d: Enforce PASID devTLB field mask
iommu/omap: Check for failure of a call to omap_iommu_dump_ctx
selftests/powerpc: ptrace-pkey: Don't update expected UAMOR value
selftests/powerpc: ptrace-pkey: Update the test to mark an invalid pkey correctly
selftests/powerpc: ptrace-pkey: Rename variables to make it easier to follow code
dm rq: don't call blk_mq_queue_stopped() in dm_stop_queue()
gpu: ipu-v3: image-convert: Combine rotate/no-rotate irq handlers
mmc: renesas_sdhi_internal_dmac: clean up the code for dma complete
USB: serial: ftdi_sio: clean up receive processing
USB: serial: ftdi_sio: make process-packet buffer unsigned
media: rockchip: rga: Only set output CSC mode for RGB input
media: rockchip: rga: Introduce color fmt macros and refactor CSC mode logic
RDMA/ipoib: Fix ABBA deadlock with ipoib_reap_ah()
RDMA/ipoib: Return void from ipoib_ib_dev_stop()
mfd: arizona: Ensure 32k clock is put on driver unbind and error
drm/imx: imx-ldb: Disable both channels for split mode in enc->disable()
remoteproc: qcom: q6v5: Update running state before requesting stop
perf intel-pt: Fix FUP packet state
module: Correctly truncate sysfs sections output
pseries: Fix 64 bit logical memory block panic
watchdog: f71808e_wdt: clear watchdog timeout occurred flag
watchdog: f71808e_wdt: remove use of wrong watchdog_info option
watchdog: f71808e_wdt: indicate WDIOF_CARDRESET support in watchdog_info.options
tracing: Use trace_sched_process_free() instead of exit() for pid tracing
tracing/hwlat: Honor the tracing_cpumask
kprobes: Fix NULL pointer dereference at kprobe_ftrace_handler
ftrace: Setup correct FTRACE_FL_REGS flags for module
mm/page_counter.c: fix protection usage propagation
ocfs2: change slot number type s16 to u16
ext2: fix missing percpu_counter_inc
MIPS: CPU#0 is not hotpluggable
driver core: Avoid binding drivers to dead devices
mac80211: fix misplaced while instead of if
bcache: fix overflow in offset_to_stripe()
bcache: allocate meta data pages as compound pages
md/raid5: Fix Force reconstruct-write io stuck in degraded raid5
net/compat: Add missing sock updates for SCM_RIGHTS
net: stmmac: dwmac1000: provide multicast filter fallback
net: ethernet: stmmac: Disable hardware multicast filter
media: vsp1: dl: Fix NULL pointer dereference on unbind
powerpc: Fix circular dependency between percpu.h and mmu.h
powerpc: Allow 4224 bytes of stack expansion for the signal frame
cifs: Fix leak when handling lease break for cached root fid
xtensa: fix xtensa_pmu_setup prototype
iio: dac: ad5592r: fix unbalanced mutex unlocks in ad5592r_read_raw()
dt-bindings: iio: io-channel-mux: Fix compatible string in example code
btrfs: fix return value mixup in btrfs_get_extent
btrfs: fix memory leaks after failure to lookup checksums during inode logging
btrfs: only search for left_info if there is no right_info in try_merge_free_space
btrfs: fix messages after changing compression level by remount
btrfs: open device without device_list_mutex
btrfs: don't traverse into the seed devices in show_devname
btrfs: ref-verify: fix memory leak in add_block_entry
btrfs: don't allocate anonymous block device for user invisible roots
btrfs: free anon block device right after subvolume deletion
PCI: Probe bridge window attributes once at enumeration-time
PCI: qcom: Add support for tx term offset for rev 2.1.0
PCI: qcom: Define some PARF params needed for ipq8064 SoC
PCI: Add device even if driver attach failed
PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken
PCI: hotplug: ACPI: Fix context refcounting in acpiphp_grab_context()
genirq/affinity: Make affinity setting if activated opt-in
smb3: warn on confusing error scenario with sec=krb5
ANDROID: ABI: update the ABI xml representation
Revert "ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109"
Linux 4.19.140
xen/gntdev: Fix dmabuf import with non-zero sgt offset
xen/balloon: make the balloon wait interruptible
xen/balloon: fix accounting in alloc_xenballooned_pages error path
irqdomain/treewide: Free firmware node after domain removal
ARM: 8992/1: Fix unwind_frame for clang-built kernels
parisc: mask out enable and reserved bits from sba imask
parisc: Implement __smp_store_release and __smp_load_acquire barriers
mtd: rawnand: qcom: avoid write to unavailable register
spi: spidev: Align buffers for DMA
include/asm-generic/vmlinux.lds.h: align ro_after_init
cpufreq: dt: fix oops on armada37xx
NFS: Don't return layout segments that are in use
NFS: Don't move layouts to plh_return_segs list while in use
drm/ttm/nouveau: don't call tt destroy callback on alloc failure.
9p: Fix memory leak in v9fs_mount
ALSA: usb-audio: add quirk for Pioneer DDJ-RB
fs/minix: reject too-large maximum file size
fs/minix: don't allow getting deleted inodes
fs/minix: check return value of sb_getblk()
bitfield.h: don't compile-time validate _val in FIELD_FIT
crypto: cpt - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified
crypto: ccp - Fix use of merged scatterlists
crypto: qat - fix double free in qat_uclo_create_batch_init_list
crypto: hisilicon - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified
pstore: Fix linking when crypto API disabled
ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109
ALSA: usb-audio: fix overeager device match for MacroSilicon MS2109
ALSA: usb-audio: Creative USB X-Fi Pro SB1095 volume knob support
ALSA: hda - fix the micmute led status for Lenovo ThinkCentre AIO
USB: serial: cp210x: enable usb generic throttle/unthrottle
USB: serial: cp210x: re-enable auto-RTS on open
net: initialize fastreuse on inet_inherit_port
net: refactor bind_bucket fastreuse into helper
net/tls: Fix kmap usage
net: Set fput_needed iff FDPUT_FPUT is set
net/nfc/rawsock.c: add CAP_NET_RAW check.
drivers/net/wan/lapbether: Added needed_headroom and a skb->len check
af_packet: TPACKET_V3: fix fill status rwlock imbalance
crypto: aesni - add compatibility with IAS
x86/fsgsbase/64: Fix NULL deref in 86_fsgsbase_read_task
svcrdma: Fix page leak in svc_rdma_recv_read_chunk()
pinctrl-single: fix pcs_parse_pinconf() return value
ocfs2: fix unbalanced locking
dlm: Fix kobject memleak
fsl/fman: fix eth hash table allocation
fsl/fman: check dereferencing null pointer
fsl/fman: fix unreachable code
fsl/fman: fix dereference null return value
fsl/fman: use 32-bit unsigned integer
net: spider_net: Fix the size used in a 'dma_free_coherent()' call
liquidio: Fix wrong return value in cn23xx_get_pf_num()
net: ethernet: aquantia: Fix wrong return value
tools, build: Propagate build failures from tools/build/Makefile.build
wl1251: fix always return 0 error
s390/qeth: don't process empty bridge port events
ASoC: meson: axg-tdm-interface: fix link fmt setup
selftests/powerpc: Fix online CPU selection
PCI: Release IVRS table in AMD ACS quirk
selftests/powerpc: Fix CPU affinity for child process
powerpc/boot: Fix CONFIG_PPC_MPC52XX references
net: dsa: rtl8366: Fix VLAN set-up
net: dsa: rtl8366: Fix VLAN semantics
Bluetooth: hci_serdev: Only unregister device if it was registered
Bluetooth: hci_h5: Set HCI_UART_RESET_ON_INIT to correct flags
power: supply: check if calc_soc succeeded in pm860x_init_battery
Smack: prevent underflow in smk_set_cipso()
Smack: fix another vsscanf out of bounds
RDMA/core: Fix return error value in _ib_modify_qp() to negative
PCI: cadence: Fix updating Vendor ID and Subsystem Vendor ID register
net: dsa: mv88e6xxx: MV88E6097 does not support jumbo configuration
scsi: mesh: Fix panic after host or bus reset
usb: dwc2: Fix error path in gadget registration
MIPS: OCTEON: add missing put_device() call in dwc3_octeon_device_init()
coresight: tmc: Fix TMC mode read in tmc_read_unprepare_etb()
thermal: ti-soc-thermal: Fix reversed condition in ti_thermal_expose_sensor()
usb: core: fix quirks_param_set() writing to a const pointer
USB: serial: iuu_phoenix: fix led-activity helpers
drm/imx: tve: fix regulator_disable error path
powerpc/book3s64/pkeys: Use PVR check instead of cpu feature
PCI/ASPM: Add missing newline in sysfs 'policy'
staging: rtl8192u: fix a dubious looking mask before a shift
RDMA/rxe: Prevent access to wr->next ptr afrer wr is posted to send queue
RDMA/qedr: SRQ's bug fixes
powerpc/vdso: Fix vdso cpu truncation
mwifiex: Prevent memory corruption handling keys
scsi: scsi_debug: Add check for sdebug_max_queue during module init
drm/bridge: sil_sii8620: initialize return of sii8620_readb
phy: exynos5-usbdrd: Calibrating makes sense only for USB2.0 PHY
drm: panel: simple: Fix bpc for LG LB070WV8 panel
leds: core: Flush scheduled work for system suspend
PCI: Fix pci_cfg_wait queue locking problem
RDMA/rxe: Skip dgid check in loopback mode
xfs: fix reflink quota reservation accounting error
xfs: don't eat an EIO/ENOSPC writeback error when scrubbing data fork
media: exynos4-is: Add missed check for pinctrl_lookup_state()
media: firewire: Using uninitialized values in node_probe()
ipvs: allow connection reuse for unconfirmed conntrack
scsi: eesox: Fix different dev_id between request_irq() and free_irq()
scsi: powertec: Fix different dev_id between request_irq() and free_irq()
drm/radeon: fix array out-of-bounds read and write issues
cxl: Fix kobject memleak
drm/mipi: use dcs write for mipi_dsi_dcs_set_tear_scanline
scsi: cumana_2: Fix different dev_id between request_irq() and free_irq()
ASoC: Intel: bxt_rt298: add missing .owner field
media: omap3isp: Add missed v4l2_ctrl_handler_free() for preview_init_entities()
leds: lm355x: avoid enum conversion warning
drm/arm: fix unintentional integer overflow on left shift
drm/etnaviv: Fix error path on failure to enable bus clk
iio: improve IIO_CONCENTRATION channel type description
ath10k: Acquire tx_lock in tx error paths
video: pxafb: Fix the function used to balance a 'dma_alloc_coherent()' call
console: newport_con: fix an issue about leak related system resources
video: fbdev: sm712fb: fix an issue about iounmap for a wrong address
agp/intel: Fix a memory leak on module initialisation failure
drm/msm: ratelimit crtc event overflow error
ACPICA: Do not increment operation_region reference counts for field units
bcache: fix super block seq numbers comparision in register_cache_set()
dyndbg: fix a BUG_ON in ddebug_describe_flags
usb: bdc: Halt controller on suspend
bdc: Fix bug causing crash after multiple disconnects
usb: gadget: net2280: fix memory leak on probe error handling paths
gpu: host1x: debug: Fix multiple channels emitting messages simultaneously
iwlegacy: Check the return value of pcie_capability_read_*()
brcmfmac: set state of hanger slot to FREE when flushing PSQ
brcmfmac: To fix Bss Info flag definition Bug
brcmfmac: keep SDIO watchdog running when console_interval is non-zero
mm/mmap.c: Add cond_resched() for exit_mmap() CPU stalls
irqchip/irq-mtk-sysirq: Replace spinlock with raw_spinlock
drm/radeon: disable AGP by default
drm/debugfs: fix plain echo to connector "force" attribute
usb: mtu3: clear dual mode of u3port when disable device
drm/nouveau: fix multiple instances of reference count leaks
drm/etnaviv: fix ref count leak via pm_runtime_get_sync
arm64: dts: hisilicon: hikey: fixes to comply with adi, adv7533 DT binding
md-cluster: fix wild pointer of unlock_all_bitmaps()
video: fbdev: neofb: fix memory leak in neo_scan_monitor()
crypto: aesni - Fix build with LLVM_IAS=1
drm/radeon: Fix reference count leaks caused by pm_runtime_get_sync
drm/amdgpu: avoid dereferencing a NULL pointer
fs/btrfs: Add cond_resched() for try_release_extent_mapping() stalls
loop: be paranoid on exit and prevent new additions / removals
Bluetooth: add a mutex lock to avoid UAF in do_enale_set
soc: qcom: rpmh-rsc: Set suppress_bind_attrs flag
drm/tilcdc: fix leak & null ref in panel_connector_get_modes
ARM: socfpga: PM: add missing put_device() call in socfpga_setup_ocram_self_refresh()
spi: lantiq: fix: Rx overflow error in full duplex mode
ARM: at91: pm: add missing put_device() call in at91_pm_sram_init()
ARM: dts: gose: Fix ports node name for adv7612
ARM: dts: gose: Fix ports node name for adv7180
platform/x86: intel-vbtn: Fix return value check in check_acpi_dev()
platform/x86: intel-hid: Fix return value check in check_acpi_dev()
m68k: mac: Fix IOP status/control register writes
m68k: mac: Don't send IOP message until channel is idle
clk: scmi: Fix min and max rate when registering clocks with discrete rates
arm64: dts: exynos: Fix silent hang after boot on Espresso
firmware: arm_scmi: Fix SCMI genpd domain probing
crypto: ccree - fix resource leak on error path
arm64: dts: qcom: msm8916: Replace invalid bias-pull-none property
EDAC: Fix reference count leaks
arm64: dts: rockchip: fix rk3399-puma gmac reset gpio
arm64: dts: rockchip: fix rk3399-puma vcc5v0-host gpio
arm64: dts: rockchip: fix rk3368-lion gmac reset gpio
sched: correct SD_flags returned by tl->sd_flags()
sched/fair: Fix NOHZ next idle balance
x86/mce/inject: Fix a wrong assignment of i_mce.status
cgroup: add missing skcd->no_refcnt check in cgroup_sk_clone()
HID: input: Fix devices that return multiple bytes in battery report
tracepoint: Mark __tracepoint_string's __used
ANDROID: fix a bug in quota2
ANDROID: Update the ABI xml based on the new driver core padding
ANDROID: GKI: add some padding to some driver core structures
ANDROID: GKI: Update the ABI xml representation
ANDROID: sched: add "frozen" field to task_struct
ANDROID: cgroups: add v2 freezer ABI changes
ANDROID: cgroups: ABI padding
Linux 4.19.139
Smack: fix use-after-free in smk_write_relabel_self()
i40e: Memory leak in i40e_config_iwarp_qvlist
i40e: Fix of memory leak and integer truncation in i40e_virtchnl.c
i40e: Wrong truncation from u16 to u8
i40e: add num_vectors checker in iwarp handler
rxrpc: Fix race between recvmsg and sendmsg on immediate call failure
selftests/net: relax cpu affinity requirement in msg_zerocopy test
Revert "vxlan: fix tos value before xmit"
openvswitch: Prevent kernel-infoleak in ovs_ct_put_key()
net: thunderx: use spin_lock_bh in nicvf_set_rx_mode_task()
net: gre: recompute gre csum for sctp over gre tunnels
hv_netvsc: do not use VF device if link is down
net: lan78xx: replace bogus endpoint lookup
vxlan: Ensure FDB dump is performed under RCU
net: ethernet: mtk_eth_soc: fix MTU warnings
ipv6: fix memory leaks on IPV6_ADDRFORM path
ipv4: Silence suspicious RCU usage warning
xattr: break delegations in {set,remove}xattr
Drivers: hv: vmbus: Ignore CHANNELMSG_TL_CONNECT_RESULT(23)
tools lib traceevent: Fix memory leak in process_dynamic_array_len
atm: fix atm_dev refcnt leaks in atmtcp_remove_persistent
igb: reinit_locked() should be called with rtnl_lock
cfg80211: check vendor command doit pointer before use
firmware: Fix a reference count leak.
usb: hso: check for return value in hso_serial_common_create()
i2c: slave: add sanity check when unregistering
i2c: slave: improve sanity check when registering
drm/nouveau/fbcon: zero-initialise the mode_cmd2 structure
drm/nouveau/fbcon: fix module unload when fbcon init has failed for some reason
net/9p: validate fds in p9_fd_open
leds: 88pm860x: fix use-after-free on unbind
leds: lm3533: fix use-after-free on unbind
leds: da903x: fix use-after-free on unbind
leds: wm831x-status: fix use-after-free on unbind
mtd: properly check all write ioctls for permissions
vgacon: Fix for missing check in scrollback handling
binder: Prevent context manager from incrementing ref 0
omapfb: dss: Fix max fclk divider for omap36xx
Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_with_rssi_evt()
Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_evt()
Bluetooth: Fix slab-out-of-bounds read in hci_extended_inquiry_result_evt()
staging: android: ashmem: Fix lockdep warning for write operation
ALSA: seq: oss: Serialize ioctls
Revert "ALSA: hda: call runtime_allow() for all hda controllers"
usb: xhci: Fix ASMedia ASM1142 DMA addressing
usb: xhci: define IDs for various ASMedia host controllers
USB: iowarrior: fix up report size handling for some devices
USB: serial: qcserial: add EM7305 QDL product ID
BACKPORT: loop: Fix wrong masking of status flags
BACKPORT: loop: Add LOOP_CONFIGURE ioctl
BACKPORT: loop: Clean up LOOP_SET_STATUS lo_flags handling
BACKPORT: loop: Rework lo_ioctl() __user argument casting
BACKPORT: loop: Move loop_set_status_from_info() and friends up
BACKPORT: loop: Factor out configuring loop from status
BACKPORT: loop: Remove figure_loop_size()
BACKPORT: loop: Refactor loop_set_status() size calculation
BACKPORT: loop: Factor out setting loop device size
BACKPORT: loop: Remove sector_t truncation checks
BACKPORT: loop: Call loop_config_discard() only after new config is applied
Linux 4.19.138
ext4: fix direct I/O read error
random32: move the pseudo-random 32-bit definitions to prandom.h
random32: remove net_rand_state from the latent entropy gcc plugin
random: fix circular include dependency on arm64 after addition of percpu.h
ARM: percpu.h: fix build error
random32: update the net random state on interrupt and activity
ANDROID: GKI: update the ABI xml
ANDROID: GKI: power: Add property to enable/disable cc toggle
ANDROID: Enforce KMI stability
Linux 4.19.137
x86/i8259: Use printk_deferred() to prevent deadlock
KVM: LAPIC: Prevent setting the tscdeadline timer if the lapic is hw disabled
xen-netfront: fix potential deadlock in xennet_remove()
cxgb4: add missing release on skb in uld_send()
x86/unwind/orc: Fix ORC for newly forked tasks
Revert "i2c: cadence: Fix the hold bit setting"
net: ethernet: ravb: exit if re-initialization fails in tx timeout
parisc: add support for cmpxchg on u8 pointers
nfc: s3fwrn5: add missing release on skb in s3fwrn5_recv_frame
qed: Disable "MFW indication via attention" SPAM every 5 minutes
usb: hso: Fix debug compile warning on sparc32
net/mlx5e: fix bpf_prog reference count leaks in mlx5e_alloc_rq
net: gemini: Fix missing clk_disable_unprepare() in error path of gemini_ethernet_port_probe()
Bluetooth: fix kernel oops in store_pending_adv_report
arm64: csum: Fix handling of bad packets
arm64/alternatives: move length validation inside the subsection
mac80211: mesh: Free pending skb when destroying a mpath
mac80211: mesh: Free ie data when leaving mesh
bpf: Fix map leak in HASH_OF_MAPS map
ibmvnic: Fix IRQ mapping disposal in error path
mlxsw: core: Free EMAD transactions using kfree_rcu()
mlxsw: core: Increase scope of RCU read-side critical section
mlx4: disable device on shutdown
net: lan78xx: fix transfer-buffer memory leak
net: lan78xx: add missing endpoint sanity check
net/mlx5: Verify Hardware supports requested ptp function on a given pin
sh: Fix validation of system call number
selftests/net: psock_fanout: fix clang issues for target arch PowerPC
selftests/net: rxtimestamp: fix clang issues for target arch PowerPC
xfrm: Fix crash when the hold queue is used.
net/x25: Fix null-ptr-deref in x25_disconnect
net/x25: Fix x25_neigh refcnt leak when x25 disconnect
xfs: fix missed wakeup on l_flush_wait
rds: Prevent kernel-infoleak in rds_notify_queue_get()
drm: hold gem reference until object is no longer accessed
drm/amdgpu: Prevent kernel-infoleak in amdgpu_info_ioctl()
Revert "drm/amdgpu: Fix NULL dereference in dpm sysfs handlers"
ARM: 8986/1: hw_breakpoint: Don't invoke overflow handler on uaccess watchpoints
wireless: Use offsetof instead of custom macro.
9p/trans_fd: Fix concurrency del of req_list in p9_fd_cancelled/p9_read_work
PCI/ASPM: Disable ASPM on ASMedia ASM1083/1085 PCIe-to-PCI bridge
Btrfs: fix selftests failure due to uninitialized i_mode in test inodes
sctp: implement memory accounting on tx path
btrfs: inode: Verify inode mode to avoid NULL pointer dereference
drm/amd/display: prevent memory leak
ath9k: release allocated buffer if timed out
ath9k_htc: release allocated buffer if timed out
tracing: Have error path in predicate_parse() free its allocated memory
drm/amdgpu: fix multiple memory leaks in acp_hw_init
iio: imu: adis16400: fix memory leak
media: rc: prevent memory leak in cx23888_ir_probe
crypto: ccp - Release all allocated memory if sha type is invalid
ANDROID: GKI: kernel: tick-sched: Move wake callback registration code
Conflicts:
Documentation/devicetree/bindings
Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.txt
drivers/clk/clk.c
drivers/hwtracing/coresight/coresight-tmc-etf.c
drivers/mmc/host/sdhci-msm.c
drivers/power/supply/power_supply_sysfs.c
include/linux/power_supply.h
include/linux/sched.h
kernel/signal.c
net/qrtr/qrtr.c
Change-Id: I0d8f44f054a9a56bb292460260cb3062be9e08ed
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
1142 lines
32 KiB
C
1142 lines
32 KiB
C
/*
|
|
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
|
* operating system. INET is implemented using the BSD Socket
|
|
* interface as the means of communication with the user level.
|
|
*
|
|
* Support for INET connection oriented protocols.
|
|
*
|
|
* Authors: See the TCP sources
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or(at your option) any later version.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/jhash.h>
|
|
|
|
#include <net/inet_connection_sock.h>
|
|
#include <net/inet_hashtables.h>
|
|
#include <net/inet_timewait_sock.h>
|
|
#include <net/ip.h>
|
|
#include <net/route.h>
|
|
#include <net/tcp_states.h>
|
|
#include <net/xfrm.h>
|
|
#include <net/tcp.h>
|
|
#include <net/sock_reuseport.h>
|
|
#include <net/addrconf.h>
|
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
/* match_sk*_wildcard == true: IPV6_ADDR_ANY equals to any IPv6 addresses
|
|
* if IPv6 only, and any IPv4 addresses
|
|
* if not IPv6 only
|
|
* match_sk*_wildcard == false: addresses must be exactly the same, i.e.
|
|
* IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY,
|
|
* and 0.0.0.0 equals to 0.0.0.0 only
|
|
*/
|
|
static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6,
|
|
const struct in6_addr *sk2_rcv_saddr6,
|
|
__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr,
|
|
bool sk1_ipv6only, bool sk2_ipv6only,
|
|
bool match_sk1_wildcard,
|
|
bool match_sk2_wildcard)
|
|
{
|
|
int addr_type = ipv6_addr_type(sk1_rcv_saddr6);
|
|
int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
|
|
|
|
/* if both are mapped, treat as IPv4 */
|
|
if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
|
|
if (!sk2_ipv6only) {
|
|
if (sk1_rcv_saddr == sk2_rcv_saddr)
|
|
return true;
|
|
return (match_sk1_wildcard && !sk1_rcv_saddr) ||
|
|
(match_sk2_wildcard && !sk2_rcv_saddr);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (addr_type == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY)
|
|
return true;
|
|
|
|
if (addr_type2 == IPV6_ADDR_ANY && match_sk2_wildcard &&
|
|
!(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
|
|
return true;
|
|
|
|
if (addr_type == IPV6_ADDR_ANY && match_sk1_wildcard &&
|
|
!(sk1_ipv6only && addr_type2 == IPV6_ADDR_MAPPED))
|
|
return true;
|
|
|
|
if (sk2_rcv_saddr6 &&
|
|
ipv6_addr_equal(sk1_rcv_saddr6, sk2_rcv_saddr6))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
/* match_sk*_wildcard == true: 0.0.0.0 equals to any IPv4 addresses
|
|
* match_sk*_wildcard == false: addresses must be exactly the same, i.e.
|
|
* 0.0.0.0 only equals to 0.0.0.0
|
|
*/
|
|
static bool ipv4_rcv_saddr_equal(__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr,
|
|
bool sk2_ipv6only, bool match_sk1_wildcard,
|
|
bool match_sk2_wildcard)
|
|
{
|
|
if (!sk2_ipv6only) {
|
|
if (sk1_rcv_saddr == sk2_rcv_saddr)
|
|
return true;
|
|
return (match_sk1_wildcard && !sk1_rcv_saddr) ||
|
|
(match_sk2_wildcard && !sk2_rcv_saddr);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
|
|
bool match_wildcard)
|
|
{
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
if (sk->sk_family == AF_INET6)
|
|
return ipv6_rcv_saddr_equal(&sk->sk_v6_rcv_saddr,
|
|
inet6_rcv_saddr(sk2),
|
|
sk->sk_rcv_saddr,
|
|
sk2->sk_rcv_saddr,
|
|
ipv6_only_sock(sk),
|
|
ipv6_only_sock(sk2),
|
|
match_wildcard,
|
|
match_wildcard);
|
|
#endif
|
|
return ipv4_rcv_saddr_equal(sk->sk_rcv_saddr, sk2->sk_rcv_saddr,
|
|
ipv6_only_sock(sk2), match_wildcard,
|
|
match_wildcard);
|
|
}
|
|
EXPORT_SYMBOL(inet_rcv_saddr_equal);
|
|
|
|
bool inet_rcv_saddr_any(const struct sock *sk)
|
|
{
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
if (sk->sk_family == AF_INET6)
|
|
return ipv6_addr_any(&sk->sk_v6_rcv_saddr);
|
|
#endif
|
|
return !sk->sk_rcv_saddr;
|
|
}
|
|
|
|
void inet_get_local_port_range(struct net *net, int *low, int *high)
|
|
{
|
|
unsigned int seq;
|
|
|
|
do {
|
|
seq = read_seqbegin(&net->ipv4.ip_local_ports.lock);
|
|
|
|
*low = net->ipv4.ip_local_ports.range[0];
|
|
*high = net->ipv4.ip_local_ports.range[1];
|
|
} while (read_seqretry(&net->ipv4.ip_local_ports.lock, seq));
|
|
}
|
|
EXPORT_SYMBOL(inet_get_local_port_range);
|
|
|
|
static int inet_csk_bind_conflict(const struct sock *sk,
|
|
const struct inet_bind_bucket *tb,
|
|
bool relax, bool reuseport_ok)
|
|
{
|
|
struct sock *sk2;
|
|
bool reuse = sk->sk_reuse;
|
|
bool reuseport = !!sk->sk_reuseport && reuseport_ok;
|
|
kuid_t uid = sock_i_uid((struct sock *)sk);
|
|
|
|
/*
|
|
* Unlike other sk lookup places we do not check
|
|
* for sk_net here, since _all_ the socks listed
|
|
* in tb->owners list belong to the same net - the
|
|
* one this bucket belongs to.
|
|
*/
|
|
|
|
sk_for_each_bound(sk2, &tb->owners) {
|
|
if (sk != sk2 &&
|
|
(!sk->sk_bound_dev_if ||
|
|
!sk2->sk_bound_dev_if ||
|
|
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
|
|
if ((!reuse || !sk2->sk_reuse ||
|
|
sk2->sk_state == TCP_LISTEN) &&
|
|
(!reuseport || !sk2->sk_reuseport ||
|
|
rcu_access_pointer(sk->sk_reuseport_cb) ||
|
|
(sk2->sk_state != TCP_TIME_WAIT &&
|
|
!uid_eq(uid, sock_i_uid(sk2))))) {
|
|
if (inet_rcv_saddr_equal(sk, sk2, true))
|
|
break;
|
|
}
|
|
if (!relax && reuse && sk2->sk_reuse &&
|
|
sk2->sk_state != TCP_LISTEN) {
|
|
if (inet_rcv_saddr_equal(sk, sk2, true))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return sk2 != NULL;
|
|
}
|
|
|
|
/*
|
|
* Find an open port number for the socket. Returns with the
|
|
* inet_bind_hashbucket lock held.
|
|
*/
|
|
static struct inet_bind_hashbucket *
|
|
inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *port_ret)
|
|
{
|
|
struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
|
|
int port = 0;
|
|
struct inet_bind_hashbucket *head;
|
|
struct net *net = sock_net(sk);
|
|
int i, low, high, attempt_half;
|
|
struct inet_bind_bucket *tb;
|
|
u32 remaining, offset;
|
|
|
|
attempt_half = (sk->sk_reuse == SK_CAN_REUSE) ? 1 : 0;
|
|
other_half_scan:
|
|
inet_get_local_port_range(net, &low, &high);
|
|
high++; /* [32768, 60999] -> [32768, 61000[ */
|
|
if (high - low < 4)
|
|
attempt_half = 0;
|
|
if (attempt_half) {
|
|
int half = low + (((high - low) >> 2) << 1);
|
|
|
|
if (attempt_half == 1)
|
|
high = half;
|
|
else
|
|
low = half;
|
|
}
|
|
remaining = high - low;
|
|
if (likely(remaining > 1))
|
|
remaining &= ~1U;
|
|
|
|
offset = prandom_u32() % remaining;
|
|
/* __inet_hash_connect() favors ports having @low parity
|
|
* We do the opposite to not pollute connect() users.
|
|
*/
|
|
offset |= 1U;
|
|
|
|
other_parity_scan:
|
|
port = low + offset;
|
|
for (i = 0; i < remaining; i += 2, port += 2) {
|
|
if (unlikely(port >= high))
|
|
port -= remaining;
|
|
if (inet_is_local_reserved_port(net, port))
|
|
continue;
|
|
head = &hinfo->bhash[inet_bhashfn(net, port,
|
|
hinfo->bhash_size)];
|
|
spin_lock_bh(&head->lock);
|
|
inet_bind_bucket_for_each(tb, &head->chain)
|
|
if (net_eq(ib_net(tb), net) && tb->port == port) {
|
|
if (!inet_csk_bind_conflict(sk, tb, false, false))
|
|
goto success;
|
|
goto next_port;
|
|
}
|
|
tb = NULL;
|
|
goto success;
|
|
next_port:
|
|
spin_unlock_bh(&head->lock);
|
|
cond_resched();
|
|
}
|
|
|
|
offset--;
|
|
if (!(offset & 1))
|
|
goto other_parity_scan;
|
|
|
|
if (attempt_half == 1) {
|
|
/* OK we now try the upper half of the range */
|
|
attempt_half = 2;
|
|
goto other_half_scan;
|
|
}
|
|
return NULL;
|
|
success:
|
|
*port_ret = port;
|
|
*tb_ret = tb;
|
|
return head;
|
|
}
|
|
|
|
static inline int sk_reuseport_match(struct inet_bind_bucket *tb,
|
|
struct sock *sk)
|
|
{
|
|
kuid_t uid = sock_i_uid(sk);
|
|
|
|
if (tb->fastreuseport <= 0)
|
|
return 0;
|
|
if (!sk->sk_reuseport)
|
|
return 0;
|
|
if (rcu_access_pointer(sk->sk_reuseport_cb))
|
|
return 0;
|
|
if (!uid_eq(tb->fastuid, uid))
|
|
return 0;
|
|
/* We only need to check the rcv_saddr if this tb was once marked
|
|
* without fastreuseport and then was reset, as we can only know that
|
|
* the fast_*rcv_saddr doesn't have any conflicts with the socks on the
|
|
* owners list.
|
|
*/
|
|
if (tb->fastreuseport == FASTREUSEPORT_ANY)
|
|
return 1;
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
if (tb->fast_sk_family == AF_INET6)
|
|
return ipv6_rcv_saddr_equal(&tb->fast_v6_rcv_saddr,
|
|
inet6_rcv_saddr(sk),
|
|
tb->fast_rcv_saddr,
|
|
sk->sk_rcv_saddr,
|
|
tb->fast_ipv6_only,
|
|
ipv6_only_sock(sk), true, false);
|
|
#endif
|
|
return ipv4_rcv_saddr_equal(tb->fast_rcv_saddr, sk->sk_rcv_saddr,
|
|
ipv6_only_sock(sk), true, false);
|
|
}
|
|
|
|
void inet_csk_update_fastreuse(struct inet_bind_bucket *tb,
|
|
struct sock *sk)
|
|
{
|
|
kuid_t uid = sock_i_uid(sk);
|
|
bool reuse = sk->sk_reuse && sk->sk_state != TCP_LISTEN;
|
|
|
|
if (hlist_empty(&tb->owners)) {
|
|
tb->fastreuse = reuse;
|
|
if (sk->sk_reuseport) {
|
|
tb->fastreuseport = FASTREUSEPORT_ANY;
|
|
tb->fastuid = uid;
|
|
tb->fast_rcv_saddr = sk->sk_rcv_saddr;
|
|
tb->fast_ipv6_only = ipv6_only_sock(sk);
|
|
tb->fast_sk_family = sk->sk_family;
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
|
|
#endif
|
|
} else {
|
|
tb->fastreuseport = 0;
|
|
}
|
|
} else {
|
|
if (!reuse)
|
|
tb->fastreuse = 0;
|
|
if (sk->sk_reuseport) {
|
|
/* We didn't match or we don't have fastreuseport set on
|
|
* the tb, but we have sk_reuseport set on this socket
|
|
* and we know that there are no bind conflicts with
|
|
* this socket in this tb, so reset our tb's reuseport
|
|
* settings so that any subsequent sockets that match
|
|
* our current socket will be put on the fast path.
|
|
*
|
|
* If we reset we need to set FASTREUSEPORT_STRICT so we
|
|
* do extra checking for all subsequent sk_reuseport
|
|
* socks.
|
|
*/
|
|
if (!sk_reuseport_match(tb, sk)) {
|
|
tb->fastreuseport = FASTREUSEPORT_STRICT;
|
|
tb->fastuid = uid;
|
|
tb->fast_rcv_saddr = sk->sk_rcv_saddr;
|
|
tb->fast_ipv6_only = ipv6_only_sock(sk);
|
|
tb->fast_sk_family = sk->sk_family;
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
|
|
#endif
|
|
}
|
|
} else {
|
|
tb->fastreuseport = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Obtain a reference to a local port for the given sock,
|
|
* if snum is zero it means select any available local port.
|
|
* We try to allocate an odd port (and leave even ports for connect())
|
|
*/
|
|
int inet_csk_get_port(struct sock *sk, unsigned short snum)
|
|
{
|
|
bool reuse = sk->sk_reuse && sk->sk_state != TCP_LISTEN;
|
|
struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
|
|
int ret = 1, port = snum;
|
|
struct inet_bind_hashbucket *head;
|
|
struct net *net = sock_net(sk);
|
|
struct inet_bind_bucket *tb = NULL;
|
|
|
|
if (!port) {
|
|
head = inet_csk_find_open_port(sk, &tb, &port);
|
|
if (!head)
|
|
return ret;
|
|
if (!tb)
|
|
goto tb_not_found;
|
|
goto success;
|
|
}
|
|
head = &hinfo->bhash[inet_bhashfn(net, port,
|
|
hinfo->bhash_size)];
|
|
spin_lock_bh(&head->lock);
|
|
|
|
if (inet_is_local_reserved_port(net, snum) &&
|
|
!sysctl_reserved_port_bind) {
|
|
ret = 1;
|
|
goto fail_unlock;
|
|
}
|
|
|
|
inet_bind_bucket_for_each(tb, &head->chain)
|
|
if (net_eq(ib_net(tb), net) && tb->port == port)
|
|
goto tb_found;
|
|
tb_not_found:
|
|
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
|
|
net, head, port);
|
|
if (!tb)
|
|
goto fail_unlock;
|
|
tb_found:
|
|
if (!hlist_empty(&tb->owners)) {
|
|
if (sk->sk_reuse == SK_FORCE_REUSE)
|
|
goto success;
|
|
|
|
if ((tb->fastreuse > 0 && reuse) ||
|
|
sk_reuseport_match(tb, sk))
|
|
goto success;
|
|
if (inet_csk_bind_conflict(sk, tb, true, true))
|
|
goto fail_unlock;
|
|
}
|
|
success:
|
|
inet_csk_update_fastreuse(tb, sk);
|
|
|
|
if (!inet_csk(sk)->icsk_bind_hash)
|
|
inet_bind_hash(sk, tb, port);
|
|
WARN_ON(inet_csk(sk)->icsk_bind_hash != tb);
|
|
ret = 0;
|
|
|
|
fail_unlock:
|
|
spin_unlock_bh(&head->lock);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_get_port);
|
|
|
|
/*
|
|
* Wait for an incoming connection, avoid race conditions. This must be called
|
|
* with the socket locked.
|
|
*/
|
|
static int inet_csk_wait_for_connect(struct sock *sk, long timeo)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
DEFINE_WAIT(wait);
|
|
int err;
|
|
|
|
/*
|
|
* True wake-one mechanism for incoming connections: only
|
|
* one process gets woken up, not the 'whole herd'.
|
|
* Since we do not 'race & poll' for established sockets
|
|
* anymore, the common case will execute the loop only once.
|
|
*
|
|
* Subtle issue: "add_wait_queue_exclusive()" will be added
|
|
* after any current non-exclusive waiters, and we know that
|
|
* it will always _stay_ after any new non-exclusive waiters
|
|
* because all non-exclusive waiters are added at the
|
|
* beginning of the wait-queue. As such, it's ok to "drop"
|
|
* our exclusiveness temporarily when we get woken up without
|
|
* having to remove and re-insert us on the wait queue.
|
|
*/
|
|
for (;;) {
|
|
prepare_to_wait_exclusive(sk_sleep(sk), &wait,
|
|
TASK_INTERRUPTIBLE);
|
|
release_sock(sk);
|
|
if (reqsk_queue_empty(&icsk->icsk_accept_queue))
|
|
timeo = schedule_timeout(timeo);
|
|
sched_annotate_sleep();
|
|
lock_sock(sk);
|
|
err = 0;
|
|
if (!reqsk_queue_empty(&icsk->icsk_accept_queue))
|
|
break;
|
|
err = -EINVAL;
|
|
if (sk->sk_state != TCP_LISTEN)
|
|
break;
|
|
err = sock_intr_errno(timeo);
|
|
if (signal_pending(current))
|
|
break;
|
|
err = -EAGAIN;
|
|
if (!timeo)
|
|
break;
|
|
}
|
|
finish_wait(sk_sleep(sk), &wait);
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
* This will accept the next outstanding connection.
|
|
*/
|
|
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
struct request_sock_queue *queue = &icsk->icsk_accept_queue;
|
|
struct request_sock *req;
|
|
struct sock *newsk;
|
|
int error;
|
|
|
|
lock_sock(sk);
|
|
|
|
/* We need to make sure that this socket is listening,
|
|
* and that it has something pending.
|
|
*/
|
|
error = -EINVAL;
|
|
if (sk->sk_state != TCP_LISTEN)
|
|
goto out_err;
|
|
|
|
/* Find already established connection */
|
|
if (reqsk_queue_empty(queue)) {
|
|
long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
|
|
|
|
/* If this is a non blocking socket don't sleep */
|
|
error = -EAGAIN;
|
|
if (!timeo)
|
|
goto out_err;
|
|
|
|
error = inet_csk_wait_for_connect(sk, timeo);
|
|
if (error)
|
|
goto out_err;
|
|
}
|
|
req = reqsk_queue_remove(queue, sk);
|
|
newsk = req->sk;
|
|
|
|
if (sk->sk_protocol == IPPROTO_TCP &&
|
|
tcp_rsk(req)->tfo_listener) {
|
|
spin_lock_bh(&queue->fastopenq.lock);
|
|
if (tcp_rsk(req)->tfo_listener) {
|
|
/* We are still waiting for the final ACK from 3WHS
|
|
* so can't free req now. Instead, we set req->sk to
|
|
* NULL to signify that the child socket is taken
|
|
* so reqsk_fastopen_remove() will free the req
|
|
* when 3WHS finishes (or is aborted).
|
|
*/
|
|
req->sk = NULL;
|
|
req = NULL;
|
|
}
|
|
spin_unlock_bh(&queue->fastopenq.lock);
|
|
}
|
|
|
|
out:
|
|
release_sock(sk);
|
|
if (newsk && mem_cgroup_sockets_enabled) {
|
|
int amt;
|
|
|
|
/* atomically get the memory usage, set and charge the
|
|
* newsk->sk_memcg.
|
|
*/
|
|
lock_sock(newsk);
|
|
|
|
/* The socket has not been accepted yet, no need to look at
|
|
* newsk->sk_wmem_queued.
|
|
*/
|
|
amt = sk_mem_pages(newsk->sk_forward_alloc +
|
|
atomic_read(&newsk->sk_rmem_alloc));
|
|
mem_cgroup_sk_alloc(newsk);
|
|
if (newsk->sk_memcg && amt)
|
|
mem_cgroup_charge_skmem(newsk->sk_memcg, amt);
|
|
|
|
release_sock(newsk);
|
|
}
|
|
if (req)
|
|
reqsk_put(req);
|
|
return newsk;
|
|
out_err:
|
|
newsk = NULL;
|
|
req = NULL;
|
|
*err = error;
|
|
goto out;
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_accept);
|
|
|
|
/*
|
|
* Using different timers for retransmit, delayed acks and probes
|
|
* We may wish use just one timer maintaining a list of expire jiffies
|
|
* to optimize.
|
|
*/
|
|
void inet_csk_init_xmit_timers(struct sock *sk,
|
|
void (*retransmit_handler)(struct timer_list *t),
|
|
void (*delack_handler)(struct timer_list *t),
|
|
void (*keepalive_handler)(struct timer_list *t))
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
|
timer_setup(&icsk->icsk_retransmit_timer, retransmit_handler, 0);
|
|
timer_setup(&icsk->icsk_delack_timer, delack_handler, 0);
|
|
timer_setup(&sk->sk_timer, keepalive_handler, 0);
|
|
icsk->icsk_pending = icsk->icsk_ack.pending = 0;
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_init_xmit_timers);
|
|
|
|
void inet_csk_clear_xmit_timers(struct sock *sk)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
|
icsk->icsk_pending = icsk->icsk_ack.pending = icsk->icsk_ack.blocked = 0;
|
|
|
|
sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
|
|
sk_stop_timer(sk, &icsk->icsk_delack_timer);
|
|
sk_stop_timer(sk, &sk->sk_timer);
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
|
|
|
|
void inet_csk_delete_keepalive_timer(struct sock *sk)
|
|
{
|
|
sk_stop_timer(sk, &sk->sk_timer);
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
|
|
|
|
void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
|
|
{
|
|
sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
|
|
|
|
struct dst_entry *inet_csk_route_req(const struct sock *sk,
|
|
struct flowi4 *fl4,
|
|
const struct request_sock *req)
|
|
{
|
|
const struct inet_request_sock *ireq = inet_rsk(req);
|
|
struct net *net = read_pnet(&ireq->ireq_net);
|
|
struct ip_options_rcu *opt;
|
|
struct rtable *rt;
|
|
|
|
rcu_read_lock();
|
|
opt = rcu_dereference(ireq->ireq_opt);
|
|
|
|
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
|
|
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
|
|
sk->sk_protocol, inet_sk_flowi_flags(sk),
|
|
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
|
|
ireq->ir_loc_addr, ireq->ir_rmt_port,
|
|
htons(ireq->ir_num), sk->sk_uid);
|
|
security_req_classify_flow(req, flowi4_to_flowi(fl4));
|
|
rt = ip_route_output_flow(net, fl4, sk);
|
|
if (IS_ERR(rt))
|
|
goto no_route;
|
|
if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
|
|
goto route_err;
|
|
rcu_read_unlock();
|
|
return &rt->dst;
|
|
|
|
route_err:
|
|
ip_rt_put(rt);
|
|
no_route:
|
|
rcu_read_unlock();
|
|
__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_route_req);
|
|
|
|
struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
|
|
struct sock *newsk,
|
|
const struct request_sock *req)
|
|
{
|
|
const struct inet_request_sock *ireq = inet_rsk(req);
|
|
struct net *net = read_pnet(&ireq->ireq_net);
|
|
struct inet_sock *newinet = inet_sk(newsk);
|
|
struct ip_options_rcu *opt;
|
|
struct flowi4 *fl4;
|
|
struct rtable *rt;
|
|
|
|
opt = rcu_dereference(ireq->ireq_opt);
|
|
fl4 = &newinet->cork.fl.u.ip4;
|
|
|
|
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
|
|
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
|
|
sk->sk_protocol, inet_sk_flowi_flags(sk),
|
|
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
|
|
ireq->ir_loc_addr, ireq->ir_rmt_port,
|
|
htons(ireq->ir_num), sk->sk_uid);
|
|
security_req_classify_flow(req, flowi4_to_flowi(fl4));
|
|
rt = ip_route_output_flow(net, fl4, sk);
|
|
if (IS_ERR(rt))
|
|
goto no_route;
|
|
if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
|
|
goto route_err;
|
|
return &rt->dst;
|
|
|
|
route_err:
|
|
ip_rt_put(rt);
|
|
no_route:
|
|
__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_route_child_sock);
|
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
#define AF_INET_FAMILY(fam) ((fam) == AF_INET)
|
|
#else
|
|
#define AF_INET_FAMILY(fam) true
|
|
#endif
|
|
|
|
/* Decide when to expire the request and when to resend SYN-ACK */
|
|
static inline void syn_ack_recalc(struct request_sock *req, const int thresh,
|
|
const int max_retries,
|
|
const u8 rskq_defer_accept,
|
|
int *expire, int *resend)
|
|
{
|
|
if (!rskq_defer_accept) {
|
|
*expire = req->num_timeout >= thresh;
|
|
*resend = 1;
|
|
return;
|
|
}
|
|
*expire = req->num_timeout >= thresh &&
|
|
(!inet_rsk(req)->acked || req->num_timeout >= max_retries);
|
|
/*
|
|
* Do not resend while waiting for data after ACK,
|
|
* start to resend on end of deferring period to give
|
|
* last chance for data or ACK to create established socket.
|
|
*/
|
|
*resend = !inet_rsk(req)->acked ||
|
|
req->num_timeout >= rskq_defer_accept - 1;
|
|
}
|
|
|
|
int inet_rtx_syn_ack(const struct sock *parent, struct request_sock *req)
|
|
{
|
|
int err = req->rsk_ops->rtx_syn_ack(parent, req);
|
|
|
|
if (!err)
|
|
req->num_retrans++;
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(inet_rtx_syn_ack);
|
|
|
|
/* return true if req was found in the ehash table */
|
|
static bool reqsk_queue_unlink(struct request_sock_queue *queue,
|
|
struct request_sock *req)
|
|
{
|
|
struct inet_hashinfo *hashinfo = req_to_sk(req)->sk_prot->h.hashinfo;
|
|
bool found = false;
|
|
|
|
if (sk_hashed(req_to_sk(req))) {
|
|
spinlock_t *lock = inet_ehash_lockp(hashinfo, req->rsk_hash);
|
|
|
|
spin_lock(lock);
|
|
found = __sk_nulls_del_node_init_rcu(req_to_sk(req));
|
|
spin_unlock(lock);
|
|
}
|
|
if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
|
|
reqsk_put(req);
|
|
return found;
|
|
}
|
|
|
|
void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req)
|
|
{
|
|
if (reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req)) {
|
|
reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
|
|
reqsk_put(req);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_reqsk_queue_drop);
|
|
|
|
void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req)
|
|
{
|
|
inet_csk_reqsk_queue_drop(sk, req);
|
|
reqsk_put(req);
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_reqsk_queue_drop_and_put);
|
|
|
|
static void reqsk_timer_handler(struct timer_list *t)
|
|
{
|
|
struct request_sock *req = from_timer(req, t, rsk_timer);
|
|
struct sock *sk_listener = req->rsk_listener;
|
|
struct net *net = sock_net(sk_listener);
|
|
struct inet_connection_sock *icsk = inet_csk(sk_listener);
|
|
struct request_sock_queue *queue = &icsk->icsk_accept_queue;
|
|
int qlen, expire = 0, resend = 0;
|
|
int max_retries, thresh;
|
|
u8 defer_accept;
|
|
|
|
if (inet_sk_state_load(sk_listener) != TCP_LISTEN)
|
|
goto drop;
|
|
|
|
max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries;
|
|
thresh = max_retries;
|
|
/* Normally all the openreqs are young and become mature
|
|
* (i.e. converted to established socket) for first timeout.
|
|
* If synack was not acknowledged for 1 second, it means
|
|
* one of the following things: synack was lost, ack was lost,
|
|
* rtt is high or nobody planned to ack (i.e. synflood).
|
|
* When server is a bit loaded, queue is populated with old
|
|
* open requests, reducing effective size of queue.
|
|
* When server is well loaded, queue size reduces to zero
|
|
* after several minutes of work. It is not synflood,
|
|
* it is normal operation. The solution is pruning
|
|
* too old entries overriding normal timeout, when
|
|
* situation becomes dangerous.
|
|
*
|
|
* Essentially, we reserve half of room for young
|
|
* embrions; and abort old ones without pity, if old
|
|
* ones are about to clog our table.
|
|
*/
|
|
qlen = reqsk_queue_len(queue);
|
|
if ((qlen << 1) > max(8U, sk_listener->sk_max_ack_backlog)) {
|
|
int young = reqsk_queue_len_young(queue) << 1;
|
|
|
|
while (thresh > 2) {
|
|
if (qlen < young)
|
|
break;
|
|
thresh--;
|
|
young <<= 1;
|
|
}
|
|
}
|
|
defer_accept = READ_ONCE(queue->rskq_defer_accept);
|
|
if (defer_accept)
|
|
max_retries = defer_accept;
|
|
syn_ack_recalc(req, thresh, max_retries, defer_accept,
|
|
&expire, &resend);
|
|
req->rsk_ops->syn_ack_timeout(req);
|
|
if (!expire &&
|
|
(!resend ||
|
|
!inet_rtx_syn_ack(sk_listener, req) ||
|
|
inet_rsk(req)->acked)) {
|
|
unsigned long timeo;
|
|
|
|
if (req->num_timeout++ == 0)
|
|
atomic_dec(&queue->young);
|
|
timeo = min(TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
|
|
mod_timer(&req->rsk_timer, jiffies + timeo);
|
|
return;
|
|
}
|
|
drop:
|
|
inet_csk_reqsk_queue_drop_and_put(sk_listener, req);
|
|
}
|
|
|
|
static void reqsk_queue_hash_req(struct request_sock *req,
|
|
unsigned long timeout)
|
|
{
|
|
req->num_retrans = 0;
|
|
req->num_timeout = 0;
|
|
req->sk = NULL;
|
|
|
|
timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED);
|
|
mod_timer(&req->rsk_timer, jiffies + timeout);
|
|
|
|
inet_ehash_insert(req_to_sk(req), NULL);
|
|
/* before letting lookups find us, make sure all req fields
|
|
* are committed to memory and refcnt initialized.
|
|
*/
|
|
smp_wmb();
|
|
refcount_set(&req->rsk_refcnt, 2 + 1);
|
|
}
|
|
|
|
void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
|
|
unsigned long timeout)
|
|
{
|
|
reqsk_queue_hash_req(req, timeout);
|
|
inet_csk_reqsk_queue_added(sk);
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add);
|
|
|
|
/**
|
|
* inet_csk_clone_lock - clone an inet socket, and lock its clone
|
|
* @sk: the socket to clone
|
|
* @req: request_sock
|
|
* @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
|
|
*
|
|
* Caller must unlock socket even in error path (bh_unlock_sock(newsk))
|
|
*/
|
|
struct sock *inet_csk_clone_lock(const struct sock *sk,
|
|
const struct request_sock *req,
|
|
const gfp_t priority)
|
|
{
|
|
struct sock *newsk = sk_clone_lock(sk, priority);
|
|
|
|
if (newsk) {
|
|
struct inet_connection_sock *newicsk = inet_csk(newsk);
|
|
|
|
inet_sk_set_state(newsk, TCP_SYN_RECV);
|
|
newicsk->icsk_bind_hash = NULL;
|
|
|
|
inet_sk(newsk)->inet_dport = inet_rsk(req)->ir_rmt_port;
|
|
inet_sk(newsk)->inet_num = inet_rsk(req)->ir_num;
|
|
inet_sk(newsk)->inet_sport = htons(inet_rsk(req)->ir_num);
|
|
|
|
/* listeners have SOCK_RCU_FREE, not the children */
|
|
sock_reset_flag(newsk, SOCK_RCU_FREE);
|
|
|
|
inet_sk(newsk)->mc_list = NULL;
|
|
|
|
newsk->sk_mark = inet_rsk(req)->ir_mark;
|
|
atomic64_set(&newsk->sk_cookie,
|
|
atomic64_read(&inet_rsk(req)->ir_cookie));
|
|
|
|
newicsk->icsk_retransmits = 0;
|
|
newicsk->icsk_backoff = 0;
|
|
newicsk->icsk_probes_out = 0;
|
|
|
|
/* Deinitialize accept_queue to trap illegal accesses. */
|
|
memset(&newicsk->icsk_accept_queue, 0, sizeof(newicsk->icsk_accept_queue));
|
|
|
|
security_inet_csk_clone(newsk, req);
|
|
}
|
|
return newsk;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_clone_lock);
|
|
|
|
/*
|
|
* At this point, there should be no process reference to this
|
|
* socket, and thus no user references at all. Therefore we
|
|
* can assume the socket waitqueue is inactive and nobody will
|
|
* try to jump onto it.
|
|
*/
|
|
void inet_csk_destroy_sock(struct sock *sk)
|
|
{
|
|
WARN_ON(sk->sk_state != TCP_CLOSE);
|
|
WARN_ON(!sock_flag(sk, SOCK_DEAD));
|
|
|
|
/* It cannot be in hash table! */
|
|
WARN_ON(!sk_unhashed(sk));
|
|
|
|
/* If it has not 0 inet_sk(sk)->inet_num, it must be bound */
|
|
WARN_ON(inet_sk(sk)->inet_num && !inet_csk(sk)->icsk_bind_hash);
|
|
|
|
sk->sk_prot->destroy(sk);
|
|
|
|
sk_stream_kill_queues(sk);
|
|
|
|
xfrm_sk_free_policy(sk);
|
|
|
|
sk_refcnt_debug_release(sk);
|
|
|
|
percpu_counter_dec(sk->sk_prot->orphan_count);
|
|
|
|
sock_put(sk);
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_destroy_sock);
|
|
|
|
/* This function allows to force a closure of a socket after the call to
|
|
* tcp/dccp_create_openreq_child().
|
|
*/
|
|
void inet_csk_prepare_forced_close(struct sock *sk)
|
|
__releases(&sk->sk_lock.slock)
|
|
{
|
|
/* sk_clone_lock locked the socket and set refcnt to 2 */
|
|
bh_unlock_sock(sk);
|
|
sock_put(sk);
|
|
|
|
/* The below has to be done to allow calling inet_csk_destroy_sock */
|
|
sock_set_flag(sk, SOCK_DEAD);
|
|
percpu_counter_inc(sk->sk_prot->orphan_count);
|
|
inet_sk(sk)->inet_num = 0;
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
|
|
|
|
int inet_csk_listen_start(struct sock *sk, int backlog)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
int err = -EADDRINUSE;
|
|
|
|
reqsk_queue_alloc(&icsk->icsk_accept_queue);
|
|
|
|
sk->sk_max_ack_backlog = backlog;
|
|
sk->sk_ack_backlog = 0;
|
|
inet_csk_delack_init(sk);
|
|
|
|
/* There is race window here: we announce ourselves listening,
|
|
* but this transition is still not validated by get_port().
|
|
* It is OK, because this socket enters to hash table only
|
|
* after validation is complete.
|
|
*/
|
|
inet_sk_state_store(sk, TCP_LISTEN);
|
|
if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
|
|
inet->inet_sport = htons(inet->inet_num);
|
|
|
|
sk_dst_reset(sk);
|
|
err = sk->sk_prot->hash(sk);
|
|
|
|
if (likely(!err))
|
|
return 0;
|
|
}
|
|
|
|
inet_sk_set_state(sk, TCP_CLOSE);
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_listen_start);
|
|
|
|
static void inet_child_forget(struct sock *sk, struct request_sock *req,
|
|
struct sock *child)
|
|
{
|
|
sk->sk_prot->disconnect(child, O_NONBLOCK);
|
|
|
|
sock_orphan(child);
|
|
|
|
percpu_counter_inc(sk->sk_prot->orphan_count);
|
|
|
|
if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(req)->tfo_listener) {
|
|
BUG_ON(tcp_sk(child)->fastopen_rsk != req);
|
|
BUG_ON(sk != req->rsk_listener);
|
|
|
|
/* Paranoid, to prevent race condition if
|
|
* an inbound pkt destined for child is
|
|
* blocked by sock lock in tcp_v4_rcv().
|
|
* Also to satisfy an assertion in
|
|
* tcp_v4_destroy_sock().
|
|
*/
|
|
tcp_sk(child)->fastopen_rsk = NULL;
|
|
}
|
|
inet_csk_destroy_sock(child);
|
|
}
|
|
|
|
struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
|
|
struct request_sock *req,
|
|
struct sock *child)
|
|
{
|
|
struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
|
|
|
|
spin_lock(&queue->rskq_lock);
|
|
if (unlikely(sk->sk_state != TCP_LISTEN)) {
|
|
inet_child_forget(sk, req, child);
|
|
child = NULL;
|
|
} else {
|
|
req->sk = child;
|
|
req->dl_next = NULL;
|
|
if (queue->rskq_accept_head == NULL)
|
|
WRITE_ONCE(queue->rskq_accept_head, req);
|
|
else
|
|
queue->rskq_accept_tail->dl_next = req;
|
|
queue->rskq_accept_tail = req;
|
|
sk_acceptq_added(sk);
|
|
}
|
|
spin_unlock(&queue->rskq_lock);
|
|
return child;
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_reqsk_queue_add);
|
|
|
|
struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
|
|
struct request_sock *req, bool own_req)
|
|
{
|
|
if (own_req) {
|
|
inet_csk_reqsk_queue_drop(sk, req);
|
|
reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
|
|
if (inet_csk_reqsk_queue_add(sk, req, child))
|
|
return child;
|
|
}
|
|
/* Too bad, another child took ownership of the request, undo. */
|
|
bh_unlock_sock(child);
|
|
sock_put(child);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(inet_csk_complete_hashdance);
|
|
|
|
/*
|
|
* This routine closes sockets which have been at least partially
|
|
* opened, but not yet accepted.
|
|
*/
|
|
void inet_csk_listen_stop(struct sock *sk)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
struct request_sock_queue *queue = &icsk->icsk_accept_queue;
|
|
struct request_sock *next, *req;
|
|
|
|
/* Following specs, it would be better either to send FIN
|
|
* (and enter FIN-WAIT-1, it is normal close)
|
|
* or to send active reset (abort).
|
|
* Certainly, it is pretty dangerous while synflood, but it is
|
|
* bad justification for our negligence 8)
|
|
* To be honest, we are not able to make either
|
|
* of the variants now. --ANK
|
|
*/
|
|
while ((req = reqsk_queue_remove(queue, sk)) != NULL) {
|
|
struct sock *child = req->sk;
|
|
|
|
local_bh_disable();
|
|
bh_lock_sock(child);
|
|
WARN_ON(sock_owned_by_user(child));
|
|
sock_hold(child);
|
|
|
|
inet_child_forget(sk, req, child);
|
|
reqsk_put(req);
|
|
bh_unlock_sock(child);
|
|
local_bh_enable();
|
|
sock_put(child);
|
|
|
|
cond_resched();
|
|
}
|
|
if (queue->fastopenq.rskq_rst_head) {
|
|
/* Free all the reqs queued in rskq_rst_head. */
|
|
spin_lock_bh(&queue->fastopenq.lock);
|
|
req = queue->fastopenq.rskq_rst_head;
|
|
queue->fastopenq.rskq_rst_head = NULL;
|
|
spin_unlock_bh(&queue->fastopenq.lock);
|
|
while (req != NULL) {
|
|
next = req->dl_next;
|
|
reqsk_put(req);
|
|
req = next;
|
|
}
|
|
}
|
|
WARN_ON_ONCE(sk->sk_ack_backlog);
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_listen_stop);
|
|
|
|
void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
|
|
const struct inet_sock *inet = inet_sk(sk);
|
|
|
|
sin->sin_family = AF_INET;
|
|
sin->sin_addr.s_addr = inet->inet_daddr;
|
|
sin->sin_port = inet->inet_dport;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr);
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
|
|
char __user *optval, int __user *optlen)
|
|
{
|
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
|
if (icsk->icsk_af_ops->compat_getsockopt)
|
|
return icsk->icsk_af_ops->compat_getsockopt(sk, level, optname,
|
|
optval, optlen);
|
|
return icsk->icsk_af_ops->getsockopt(sk, level, optname,
|
|
optval, optlen);
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt);
|
|
|
|
int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
|
|
char __user *optval, unsigned int optlen)
|
|
{
|
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
|
if (icsk->icsk_af_ops->compat_setsockopt)
|
|
return icsk->icsk_af_ops->compat_setsockopt(sk, level, optname,
|
|
optval, optlen);
|
|
return icsk->icsk_af_ops->setsockopt(sk, level, optname,
|
|
optval, optlen);
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt);
|
|
#endif
|
|
|
|
static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl)
|
|
{
|
|
const struct inet_sock *inet = inet_sk(sk);
|
|
const struct ip_options_rcu *inet_opt;
|
|
__be32 daddr = inet->inet_daddr;
|
|
struct flowi4 *fl4;
|
|
struct rtable *rt;
|
|
|
|
rcu_read_lock();
|
|
inet_opt = rcu_dereference(inet->inet_opt);
|
|
if (inet_opt && inet_opt->opt.srr)
|
|
daddr = inet_opt->opt.faddr;
|
|
fl4 = &fl->u.ip4;
|
|
rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr,
|
|
inet->inet_saddr, inet->inet_dport,
|
|
inet->inet_sport, sk->sk_protocol,
|
|
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
|
|
if (IS_ERR(rt))
|
|
rt = NULL;
|
|
if (rt)
|
|
sk_setup_caps(sk, &rt->dst);
|
|
rcu_read_unlock();
|
|
|
|
return &rt->dst;
|
|
}
|
|
|
|
struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu)
|
|
{
|
|
struct dst_entry *dst = __sk_dst_check(sk, 0);
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
|
|
if (!dst) {
|
|
dst = inet_csk_rebuild_route(sk, &inet->cork.fl);
|
|
if (!dst)
|
|
goto out;
|
|
}
|
|
dst->ops->update_pmtu(dst, sk, NULL, mtu, true);
|
|
|
|
dst = __sk_dst_check(sk, 0);
|
|
if (!dst)
|
|
dst = inet_csk_rebuild_route(sk, &inet->cork.fl);
|
|
out:
|
|
return dst;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet_csk_update_pmtu);
|