mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
* refs/heads/tmp-d2d05bc: Linux 4.14.190 ath9k: Fix regression with Atheros 9271 ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb parisc: Add atomic64_set_release() define to avoid CPU soft lockups io-mapping: indicate mapping failure mm/memcg: fix refcount error while moving and swapping Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation vt: Reject zero-sized screen buffer size. fbdev: Detect integer underflow at "struct fbcon_ops"->clear_margins. serial: 8250_mtk: Fix high-speed baud rates clamping serial: 8250: fix null-ptr-deref in serial8250_start_tx() staging: comedi: addi_apci_1564: check INSN_CONFIG_DIGITAL_TRIG shift staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift staging: comedi: ni_6527: fix INSN_CONFIG_DIGITAL_TRIG support staging: comedi: addi_apci_1032: check INSN_CONFIG_DIGITAL_TRIG shift staging: wlan-ng: properly check endpoint types Revert "cifs: Fix the target file was deleted when rename failed." usb: xhci: Fix ASM2142/ASM3142 DMA addressing usb: xhci-mtk: fix the failure of bandwidth allocation binder: Don't use mmput() from shrinker function. x86: math-emu: Fix up 'cmp' insn for clang ias arm64: Use test_tsk_thread_flag() for checking TIF_SINGLESTEP usb: gadget: udc: gr_udc: fix memleak on error handling path in gr_ep_init() Input: synaptics - enable InterTouch for ThinkPad X1E 1st gen dmaengine: ioat setting ioat timeout as module parameter hwmon: (aspeed-pwm-tacho) Avoid possible buffer overflow regmap: dev_get_regmap_match(): fix string comparison spi: mediatek: use correct SPI_CFG2_REG MACRO Input: add `SW_MACHINE_COVER` dmaengine: tegra210-adma: Fix runtime PM imbalance on error HID: apple: Disable Fn-key key-re-mapping on clone keyboards HID: i2c-hid: add Mediacom FlexBook edge13 to descriptor override scripts/decode_stacktrace: strip basepath from all paths serial: exar: Fix GPIO configuration for Sealevel cards based on XR17V35X bonding: check return value of register_netdevice() in bond_newlink() i2c: rcar: always clear ICSAR to avoid side effects ipvs: fix the connection sync failed in some cases mlxsw: destroy workqueue when trap_register in mlxsw_emad_init bonding: check error value of register_netdevice() immediately net: smc91x: Fix possible memory leak in smc_drv_probe() drm: sun4i: hdmi: Fix inverted HPD result net: dp83640: fix SIOCSHWTSTAMP to update the struct with actual configuration ax88172a: fix ax88172a_unbind() failures hippi: Fix a size used in a 'pci_free_consistent()' in an error handling path bnxt_en: Fix race when modifying pause settings. btrfs: fix page leaks after failure to lock page for delalloc btrfs: fix mount failure caused by race with umount btrfs: fix double free on ulist after backref resolution failure ASoC: rt5670: Correct RT5670_LDO_SEL_MASK ALSA: info: Drop WARN_ON() from buffer NULL sanity check uprobes: Change handle_swbp() to send SIGTRAP with si_code=SI_KERNEL, to fix GDB regression IB/umem: fix reference count leak in ib_umem_odp_get() spi: spi-fsl-dspi: Exit the ISR with IRQ_NONE when it's not ours SUNRPC reverting d03727b248d0 ("NFSv4 fix CLOSE not waiting for direct IO compeletion") irqdomain/treewide: Keep firmware node unconditionally allocated drm/nouveau/i2c/g94-: increase NV_PMGR_DP_AUXCTL_TRANSACTREQ timeout net: sky2: initialize return of gm_phy_read drivers/net/wan/lapbether: Fixed the value of hard_header_len xtensa: update *pos in cpuinfo_op.next xtensa: fix __sync_fetch_and_{and,or}_4 declarations scsi: scsi_transport_spi: Fix function pointer check mac80211: allow rx of mesh eapol frames with default rx key pinctrl: amd: fix npins for uart0 in kerncz_groups gpio: arizona: put pm_runtime in case of failure gpio: arizona: handle pm_runtime_get_sync failure case ANDROID: Incremental fs: magic number compatible 32-bit ANDROID: kbuild: don't merge .*..compoundliteral in modules Revert "arm64/alternatives: use subsections for replacement sequences" Linux 4.14.189 rxrpc: Fix trace string libceph: don't omit recovery_deletes in target_copy() x86/cpu: Move x86_cache_bits settings sched/fair: handle case of task_h_load() returning 0 arm64: ptrace: Override SPSR.SS when single-stepping is enabled thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power misc: atmel-ssc: lock with mutex instead of spinlock dmaengine: fsl-edma: Fix NULL pointer exception in fsl_edma_tx_handler intel_th: pci: Add Emmitsburg PCH support intel_th: pci: Add Tiger Lake PCH-H support intel_th: pci: Add Jasper Lake CPU support hwmon: (emc2103) fix unable to change fan pwm1_enable attribute MIPS: Fix build for LTS kernel caused by backporting lpj adjustment timer: Fix wheel index calculation on last level uio_pdrv_genirq: fix use without device tree and no interrupt Input: i8042 - add Lenovo XiaoXin Air 12 to i8042 nomux list mei: bus: don't clean driver pointer Revert "zram: convert remaining CLASS_ATTR() to CLASS_ATTR_RO()" fuse: Fix parameter for FS_IOC_{GET,SET}FLAGS virtio: virtio_console: add missing MODULE_DEVICE_TABLE() for rproc serial USB: serial: option: add Quectel EG95 LTE modem USB: serial: option: add GosunCn GM500 series USB: serial: ch341: add new Product ID for CH340 USB: serial: cypress_m8: enable Simply Automated UPB PIM USB: serial: iuu_phoenix: fix memory corruption usb: gadget: function: fix missing spinlock in f_uac1_legacy usb: chipidea: core: add wakeup support for extcon usb: dwc2: Fix shutdown callback in platform USB: c67x00: fix use after free in c67x00_giveback_urb ALSA: usb-audio: Fix race against the error recovery URB submission ALSA: line6: Perform sanity check for each URB creation HID: magicmouse: do not set up autorepeat mtd: rawnand: oxnas: Release all devices in the _remove() path mtd: rawnand: oxnas: Unregister all devices on error mtd: rawnand: oxnas: Keep track of registered devices mtd: rawnand: brcmnand: fix CS0 layout perf stat: Zero all the 'ena' and 'run' array slot stats for interval mode copy_xstate_to_kernel: Fix typo which caused GDB regression ARM: dts: socfpga: Align L2 cache-controller nodename with dtschema Revert "thermal: mediatek: fix register index error" staging: comedi: verify array index is correct before using it usb: gadget: udc: atmel: fix uninitialized read in debug printk spi: spi-sun6i: sun6i_spi_transfer_one(): fix setting of clock rate arm64: dts: meson: add missing gxl rng clock phy: sun4i-usb: fix dereference of pointer phy0 before it is null checked iio:health:afe4404 Fix timestamp alignment and prevent data leak. ACPI: video: Use native backlight on Acer TravelMate 5735Z ACPI: video: Use native backlight on Acer Aspire 5783z mmc: sdhci: do not enable card detect interrupt for gpio cd type doc: dt: bindings: usb: dwc3: Update entries for disabling SS instances in park mode Revert "usb/xhci-plat: Set PM runtime as active on resume" Revert "usb/ehci-platform: Set PM runtime as active on resume" Revert "usb/ohci-platform: Fix a warning when hibernating" of: of_mdio: Correct loop scanning logic net: dsa: bcm_sf2: Fix node reference count spi: fix initial SPI_SR value in spi-fsl-dspi spi: spi-fsl-dspi: Fix lockup if device is shutdown during SPI transfer iio:health:afe4403 Fix timestamp alignment and prevent data leak. iio:pressure:ms5611 Fix buffer element alignment iio: pressure: zpa2326: handle pm_runtime_get_sync failure iio: mma8452: Add missed iio_device_unregister() call in mma8452_probe() iio: magnetometer: ak8974: Fix runtime PM imbalance on error iio:humidity:hdc100x Fix alignment and data leak issues iio:magnetometer:ak8974: Fix alignment and data leak issues arm64/alternatives: don't patch up internal branches arm64: alternative: Use true and false for boolean values i2c: eg20t: Load module automatically if ID matches gfs2: read-only mounts should grab the sd_freeze_gl glock tpm_tis: extra chip->ops check on error path in tpm_tis_core_init arm64/alternatives: use subsections for replacement sequences drm/exynos: fix ref count leak in mic_pre_enable cgroup: Fix sock_cgroup_data on big-endian. cgroup: fix cgroup_sk_alloc() for sk_clone_lock() tcp: md5: do not send silly options in SYNCOOKIES tcp: make sure listeners don't initialize congestion-control state net_sched: fix a memory leak in atm_tc_init() tcp: md5: allow changing MD5 keys in all socket states tcp: md5: refine tcp_md5_do_add()/tcp_md5_hash_key() barriers tcp: md5: add missing memory barriers in tcp_md5_do_add()/tcp_md5_hash_key() net: usb: qmi_wwan: add support for Quectel EG95 LTE modem net: Added pointer check for dst->ops->neigh_lookup in dst_neigh_lookup_skb llc: make sure applications use ARPHRD_ETHER l2tp: remove skb_dst_set() from l2tp_xmit_skb() ipv4: fill fl4_icmp_{type,code} in ping_v4_sendmsg genetlink: remove genl_bind s390/mm: fix huge pte soft dirty copying ARC: elf: use right ELF_ARCH ARC: entry: fix potential EFA clobber when TIF_SYSCALL_TRACE dm: use noio when sending kobject event drm/radeon: fix double free btrfs: fix fatal extent_buffer readahead vs releasepage race Revert "ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb" KVM: x86: Mark CR4.TSD as being possibly owned by the guest KVM: x86: Inject #GP if guest attempts to toggle CR4.LA57 in 64-bit mode KVM: x86: bit 8 of non-leaf PDPEs is not reserved KVM: arm64: Stop clobbering x0 for HVC_SOFT_RESTART KVM: arm64: Fix definition of PAGE_HYP_DEVICE ALSA: usb-audio: add quirk for MacroSilicon MS2109 ALSA: hda - let hs_mic be picked ahead of hp_mic ALSA: opl3: fix infoleak in opl3 mlxsw: spectrum_router: Remove inappropriate usage of WARN_ON() net: macb: mark device wake capable when "magic-packet" property present bnxt_en: fix NULL dereference in case SR-IOV configuration fails nbd: Fix memory leak in nbd_add_socket arm64: kgdb: Fix single-step exception handling oops ALSA: compress: fix partial_drain completion state smsc95xx: avoid memory leak in smsc95xx_bind smsc95xx: check return value of smsc95xx_reset net: cxgb4: fix return error value in t4_prep_fw x86/entry: Increase entry_stack size to a full page nvme-rdma: assign completion vector correctly scsi: mptscsih: Fix read sense data size ARM: imx6: add missing put_device() call in imx6q_suspend_init() cifs: update ctime and mtime during truncate s390/kasan: fix early pgm check handler execution ixgbe: protect ring accesses with READ- and WRITE_ONCE spi: spidev: fix a potential use-after-free in spidev_release() spi: spidev: fix a race between spidev_release and spidev_remove gpu: host1x: Detach driver on unregister ARM: dts: omap4-droid4: Fix spi configuration and increase rate spi: spi-fsl-dspi: Fix external abort on interrupt in resume or exit paths spi: spi-fsl-dspi: use IRQF_SHARED mode to request IRQ spi: spi-fsl-dspi: Fix lockup if device is removed during SPI transfer spi: spi-fsl-dspi: Adding shutdown hook KVM: s390: reduce number of IO pins to 1 UPSTREAM: perf/core: Fix crash when using HW tracing kernel filters ANDROID: fscrypt: fix DUN contiguity with inline encryption + IV_INO_LBLK_32 policies ANDROID: f2fs: add back compress inode check Linux 4.14.188 efi: Make it possible to disable efivar_ssdt entirely dm zoned: assign max_io_len correctly irqchip/gic: Atomically update affinity MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen cifs: Fix the target file was deleted when rename failed. SMB3: Honor persistent/resilient handle flags for multiuser mounts SMB3: Honor 'seal' flag for multiuser mounts Revert "ALSA: usb-audio: Improve frames size computation" nfsd: apply umask on fs without ACL support i2c: algo-pca: Add 0x78 as SCL stuck low status for PCA9665 virtio-blk: free vblk-vqs in error path of virtblk_probe() drm: sun4i: hdmi: Remove extra HPD polling hwmon: (acpi_power_meter) Fix potential memory leak in acpi_power_meter_add() hwmon: (max6697) Make sure the OVERT mask is set correctly cxgb4: parse TC-U32 key values and masks natively cxgb4: use unaligned conversion for fetching timestamp crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock() kgdb: Avoid suspicious RCU usage warning usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect mm/slub: fix stack overruns with SLUB_STATS mm/slub.c: fix corrupted freechain in deactivate_slab() usbnet: smsc95xx: Fix use-after-free after removal EDAC/amd64: Read back the scrub rate PCI register on F15h mm: fix swap cache node allocation mask btrfs: fix data block group relocation failure due to concurrent scrub btrfs: cow_file_range() num_bytes and disk_num_bytes are same btrfs: fix a block group ref counter leak after failure to remove block group UPSTREAM: binder: fix null deref of proc->context ANDROID: GKI: scripts: Makefile: update the lz4 command (#2) Linux 4.14.187 Revert "tty: hvc: Fix data abort due to race in hvc_open" xfs: add agf freeblocks verify in xfs_agf_verify NFSv4 fix CLOSE not waiting for direct IO compeletion pNFS/flexfiles: Fix list corruption if the mirror count changes SUNRPC: Properly set the @subbuf parameter of xdr_buf_subsegment() sunrpc: fixed rollback in rpc_gssd_dummy_populate() Staging: rtl8723bs: prevent buffer overflow in update_sta_support_rate() drm/radeon: fix fb_div check in ni_init_smc_spll_table() tracing: Fix event trigger to accept redundant spaces arm64: perf: Report the PC value in REGS_ABI_32 mode ocfs2: fix panic on nfs server over ocfs2 ocfs2: fix value of OCFS2_INVALID_SLOT ocfs2: load global_inode_alloc mm/slab: use memzero_explicit() in kzfree() btrfs: fix failure of RWF_NOWAIT write into prealloc extent beyond eof KVM: nVMX: Plumb L2 GPA through to PML emulation KVM: X86: Fix MSR range of APIC registers in X2APIC mode ACPI: sysfs: Fix pm_profile_attr type ALSA: hda: Add NVIDIA codec IDs 9a & 9d through a0 to patch table blktrace: break out of blktrace setup on concurrent calls kbuild: improve cc-option to clean up all temporary files s390/ptrace: fix setting syscall number net: alx: fix race condition in alx_remove ata/libata: Fix usage of page address by page_address in ata_scsi_mode_select_xlat function sched/core: Fix PI boosting between RT and DEADLINE tasks net: bcmgenet: use hardware padding of runt frames netfilter: ipset: fix unaligned atomic access usb: gadget: udc: Potential Oops in error handling code ARM: imx5: add missing put_device() call in imx_suspend_alloc_ocram() net: qed: fix excessive QM ILT lines consumption net: qed: fix NVMe login fails over VFs net: qed: fix left elements count calculation RDMA/mad: Fix possible memory leak in ib_mad_post_receive_mads() ASoC: rockchip: Fix a reference count leak. RDMA/cma: Protect bind_list and listen_list while finding matching cm id rxrpc: Fix handling of rwind from an ACK packet ARM: dts: NSP: Correct FA2 mailbox node efi/esrt: Fix reference count leak in esre_create_sysfs_entry. cifs/smb3: Fix data inconsistent when zero file range cifs/smb3: Fix data inconsistent when punch hole xhci: Poll for U0 after disabling USB2 LPM ALSA: usb-audio: Fix OOB access of mixer element list ALSA: usb-audio: Clean up mixer element list traverse ALSA: usb-audio: uac1: Invalidate ctl on interrupt loop: replace kill_bdev with invalidate_bdev cdc-acm: Add DISABLE_ECHO quirk for Microchip/SMSC chip xhci: Fix enumeration issue when setting max packet size for FS devices. xhci: Fix incorrect EP_STATE_MASK ALSA: usb-audio: add quirk for Denon DCD-1500RE usb: host: ehci-exynos: Fix error check in exynos_ehci_probe() usb: host: xhci-mtk: avoid runtime suspend when removing hcd USB: ehci: reopen solution for Synopsys HC bug usb: add USB_QUIRK_DELAY_INIT for Logitech C922 usb: dwc2: Postponed gadget registration to the udc class driver USB: ohci-sm501: Add missed iounmap() in remove net: core: reduce recursion limit value net: Do not clear the sock TX queue in sk_set_socket() net: Fix the arp error in some cases ip6_gre: fix use-after-free in ip6gre_tunnel_lookup() tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT ip_tunnel: fix use-after-free in ip_tunnel_lookup() tg3: driver sleeps indefinitely when EEH errors exceed eeh_max_freezes tcp: grow window for OOO packets only for SACK flows sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket rxrpc: Fix notification call on completion of discarded calls rocker: fix incorrect error handling in dma_rings_init net: usb: ax88179_178a: fix packet alignment padding net: fix memleak in register_netdevice() net: bridge: enfore alignment for ethernet address mld: fix memory leak in ipv6_mc_destroy_dev() ibmveth: Fix max MTU limit apparmor: don't try to replace stale label in ptraceme check fix a braino in "sparc32: fix register window handling in genregs32_[gs]et()" net: sched: export __netdev_watchdog_up() block/bio-integrity: don't free 'buf' if bio_integrity_add_page() failed net: be more gentle about silly gso requests coming from user scsi: scsi_devinfo: handle non-terminated strings ANDROID: Makefile: append BUILD_NUMBER to version string when defined Linux 4.14.186 KVM: x86/mmu: Set mmio_value to '0' if reserved #PF can't be generated kvm: x86: Fix reserved bits related calculation errors caused by MKTME kvm: x86: Move kvm_set_mmio_spte_mask() from x86.c to mmu.c md: add feature flag MD_FEATURE_RAID0_LAYOUT net: core: device_rename: Use rwsem instead of a seqcount sched/rt, net: Use CONFIG_PREEMPTION.patch kretprobe: Prevent triggering kretprobe from within kprobe_flush_task e1000e: Do not wake up the system via WOL if device wakeup is disabled kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex crypto: algboss - don't wait during notifier callback crypto: algif_skcipher - Cap recv SG list at ctx->used mtd: rawnand: tmio: Fix the probe error path mtd: rawnand: mtk: Fix the probe error path mtd: rawnand: plat_nand: Fix the probe error path mtd: rawnand: socrates: Fix the probe error path mtd: rawnand: oxnas: Fix the probe error path mtd: rawnand: oxnas: Add of_node_put() mtd: rawnand: orion: Fix the probe error path mtd: rawnand: xway: Fix the probe error path mtd: rawnand: sharpsl: Fix the probe error path mtd: rawnand: diskonchip: Fix the probe error path mtd: rawnand: Pass a nand_chip object to nand_release() block: nr_sects_write(): Disable preemption on seqcount write x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld drm/dp_mst: Increase ACT retry timeout to 3s ext4: fix partial cluster initialization when splitting extent selinux: fix double free drm/qxl: Use correct notify port address when creating cursor ring drm/dp_mst: Reformat drm_dp_check_act_status() a bit drm: encoder_slave: fix refcouting error for modules libata: Use per port sync for detach arm64: hw_breakpoint: Don't invoke overflow handler on uaccess watchpoints block: Fix use-after-free in blkdev_get() bcache: fix potential deadlock problem in btree_gc_coalesce perf report: Fix NULL pointer dereference in hists__fprintf_nr_sample_events() usb/ehci-platform: Set PM runtime as active on resume usb/xhci-plat: Set PM runtime as active on resume scsi: acornscsi: Fix an error handling path in acornscsi_probe() drm/sun4i: hdmi ddc clk: Fix size of m divider selftests/net: in timestamping, strncpy needs to preserve null byte gfs2: fix use-after-free on transaction ail lists blktrace: fix endianness for blk_log_remap() blktrace: fix endianness in get_pdu_int() blktrace: use errno instead of bi_status selftests/vm/pkeys: fix alloc_random_pkey() to make it really random elfnote: mark all .note sections SHF_ALLOC include/linux/bitops.h: avoid clang shift-count-overflow warnings lib/zlib: remove outdated and incorrect pre-increment optimization geneve: change from tx_error to tx_dropped on missing metadata crypto: omap-sham - add proper load balancing support for multicore pinctrl: freescale: imx: Fix an error handling path in 'imx_pinctrl_probe()' pinctrl: imxl: Fix an error handling path in 'imx1_pinctrl_core_probe()' scsi: ufs: Don't update urgent bkops level when toggling auto bkops scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj gfs2: Allow lock_nolock mount to specify jid=X openrisc: Fix issue with argument clobbering for clone/fork vfio/mdev: Fix reference count leak in add_mdev_supported_type ASoC: fsl_asrc_dma: Fix dma_chan leak when config DMA channel failed extcon: adc-jack: Fix an error handling path in 'adc_jack_probe()' powerpc/4xx: Don't unmap NULL mbase NFSv4.1 fix rpc_call_done assignment for BIND_CONN_TO_SESSION net: sunrpc: Fix off-by-one issues in 'rpc_ntop6' scsi: ufs-qcom: Fix scheduling while atomic issue clk: bcm2835: Fix return type of bcm2835_register_gate x86/apic: Make TSC deadline timer detection message visible usb: gadget: Fix issue with config_ep_by_speed function usb: gadget: fix potential double-free in m66592_probe. usb: gadget: lpc32xx_udc: don't dereference ep pointer before null check USB: gadget: udc: s3c2410_udc: Remove pointless NULL check in s3c2410_udc_nuke usb: dwc2: gadget: move gadget resume after the core is in L0 state watchdog: da9062: No need to ping manually before setting timeout IB/cma: Fix ports memory leak in cma_configfs PCI/PTM: Inherit Switch Downstream Port PTM settings from Upstream Port dm zoned: return NULL if dmz_get_zone_for_reclaim() fails to find a zone powerpc/64s/pgtable: fix an undefined behaviour clk: samsung: exynos5433: Add IGNORE_UNUSED flag to sclk_i2s1 tty: n_gsm: Fix bogus i++ in gsm_data_kick USB: host: ehci-mxc: Add error handling in ehci_mxc_drv_probe() drm/msm/mdp5: Fix mdp5_init error path for failed mdp5_kms allocation usb/ohci-platform: Fix a warning when hibernating vfio-pci: Mask cap zero powerpc/ps3: Fix kexec shutdown hang powerpc/pseries/ras: Fix FWNMI_VALID off by one tty: n_gsm: Fix waking up upper tty layer when room available tty: n_gsm: Fix SOF skipping PCI: Fix pci_register_host_bridge() device_register() error handling clk: ti: composite: fix memory leak dlm: remove BUG() before panic() scsi: mpt3sas: Fix double free warnings power: supply: smb347-charger: IRQSTAT_D is volatile power: supply: lp8788: Fix an error handling path in 'lp8788_charger_probe()' scsi: qla2xxx: Fix warning after FC target reset PCI/ASPM: Allow ASPM on links to PCIe-to-PCI/PCI-X Bridges PCI: rcar: Fix incorrect programming of OB windows drivers: base: Fix NULL pointer exception in __platform_driver_probe() if a driver developer is foolish serial: amba-pl011: Make sure we initialize the port.lock spinlock i2c: pxa: fix i2c_pxa_scream_blue_murder() debug output staging: sm750fb: add missing case while setting FB_VISUAL thermal/drivers/ti-soc-thermal: Avoid dereferencing ERR_PTR tty: hvc: Fix data abort due to race in hvc_open s390/qdio: put thinint indicator after early error ALSA: usb-audio: Improve frames size computation scsi: qedi: Do not flush offload work if ARP not resolved staging: greybus: fix a missing-check bug in gb_lights_light_config() scsi: ibmvscsi: Don't send host info in adapter info MAD after LPM scsi: sr: Fix sr_probe() missing deallocate of device minor apparmor: fix introspection of of task mode for unconfined tasks mksysmap: Fix the mismatch of '.L' symbols in System.map NTB: Fix the default port and peer numbers for legacy drivers yam: fix possible memory leak in yam_init_driver powerpc/crashkernel: Take "mem=" option into account nfsd: Fix svc_xprt refcnt leak when setup callback client failed powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run clk: clk-flexgen: fix clock-critical handling scsi: lpfc: Fix lpfc_nodelist leak when processing unsolicited event mfd: wm8994: Fix driver operation if loaded as modules m68k/PCI: Fix a memory leak in an error handling path vfio/pci: fix memory leaks in alloc_perm_bits() ps3disk: use the default segment boundary PCI: aardvark: Don't blindly enable ASPM L0s and don't write to read-only register dm mpath: switch paths in dm_blk_ioctl() code path usblp: poison URBs upon disconnect i2c: pxa: clear all master action bits in i2c_pxa_stop_message() f2fs: report delalloc reserve as non-free in statfs for project quota iio: bmp280: fix compensation of humidity scsi: qla2xxx: Fix issue with adapter's stopping state ALSA: isa/wavefront: prevent out of bounds write in ioctl scsi: qedi: Check for buffer overflow in qedi_set_path() ARM: integrator: Add some Kconfig selections ASoC: davinci-mcasp: Fix dma_chan refcnt leak when getting dma type backlight: lp855x: Ensure regulators are disabled on probe failure clk: qcom: msm8916: Fix the address location of pll->config_reg remoteproc: Fix IDR initialisation in rproc_alloc() iio: pressure: bmp280: Tolerate IRQ before registering i2c: piix4: Detect secondary SMBus controller on AMD AM4 chipsets clk: sunxi: Fix incorrect usage of round_down() power: supply: bq24257_charger: Replace depends on REGMAP_I2C with select drm/i915: Whitelist context-local timestamp in the gen9 cmdparser s390: fix syscall_get_error for compat processes ANDROID: ext4: Optimize match for casefolded encrypted dirs ANDROID: ext4: Handle casefolding with encryption ANDROID: cuttlefish_defconfig: x86: Enable KERNEL_LZ4 ANDROID: GKI: scripts: Makefile: update the lz4 command FROMLIST: f2fs: fix use-after-free when accessing bio->bi_crypt_context Linux 4.14.185 perf symbols: Fix debuginfo search for Ubuntu perf probe: Fix to check blacklist address correctly perf probe: Do not show the skipped events w1: omap-hdq: cleanup to add missing newline for some dev_dbg mtd: rawnand: pasemi: Fix the probe error path mtd: rawnand: brcmnand: fix hamming oob layout sunrpc: clean up properly in gss_mech_unregister() sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate registrations. kbuild: force to build vmlinux if CONFIG_MODVERSION=y powerpc/64s: Save FSCR to init_task.thread.fscr after feature init powerpc/64s: Don't let DT CPU features set FSCR_DSCR drivers/macintosh: Fix memleak in windfarm_pm112 driver ARM: tegra: Correct PL310 Auxiliary Control Register initialization kernel/cpu_pm: Fix uninitted local in cpu_pm dm crypt: avoid truncating the logical block size sparc64: fix misuses of access_process_vm() in genregs32_[sg]et() sparc32: fix register window handling in genregs32_[gs]et() pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs power: vexpress: add suppress_bind_attrs to true igb: Report speed and duplex as unknown when device is runtime suspended media: ov5640: fix use of destroyed mutex b43_legacy: Fix connection problem with WPA3 b43: Fix connection problem with WPA3 b43legacy: Fix case where channel status is corrupted media: go7007: fix a miss of snd_card_free carl9170: remove P2P_GO support e1000e: Relax condition to trigger reset for ME workaround e1000e: Disable TSO for buffer overrun workaround PCI: Program MPS for RCiEP devices blk-mq: move _blk_mq_update_nr_hw_queues synchronize_rcu call btrfs: fix wrong file range cleanup after an error filling dealloc range btrfs: fix error handling when submitting direct I/O bio PCI: Unify ACS quirk desired vs provided checking PCI: Add ACS quirk for Intel Root Complex Integrated Endpoints PCI: Generalize multi-function power dependency device links vga_switcheroo: Use device link for HDA controller vga_switcheroo: Deduplicate power state tracking PCI: Make ACS quirk implementations more uniform PCI: Add ACS quirk for Ampere root ports PCI: Add ACS quirk for iProc PAXB PCI: Avoid FLR for AMD Starship USB 3.0 PCI: Avoid FLR for AMD Matisse HD Audio & USB 3.0 PCI: Disable MSI for Freescale Layerscape PCIe RC mode ext4: fix race between ext4_sync_parent() and rename() ext4: fix error pointer dereference ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max evm: Fix possible memory leak in evm_calc_hmac_or_hash() ima: Directly assign the ima_default_policy pointer to ima_rules ima: Fix ima digest hash table key calculation mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked() btrfs: send: emit file capabilities after chown string.h: fix incompatibility between FORTIFY_SOURCE and KASAN platform/x86: hp-wmi: Convert simple_strtoul() to kstrtou32() cpuidle: Fix three reference count leaks spi: dw: Return any value retrieved from the dma_transfer callback mmc: sdhci-esdhc-imx: fix the mask for tuning start point ixgbe: fix signed-integer-overflow warning mmc: via-sdmmc: Respect the cmd->busy_timeout from the mmc core staging: greybus: sdio: Respect the cmd->busy_timeout from the mmc core mmc: sdhci-msm: Set SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 quirk MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe() PCI: Don't disable decoding when mmio_always_on is set macvlan: Skip loopback packets in RX handler m68k: mac: Don't call via_flush_cache() on Mac IIfx x86/mm: Stop printing BRK addresses mips: Add udelay lpj numbers adjustment mips: MAAR: Use more precise address mask x86/boot: Correct relocation destination on old linkers mwifiex: Fix memory corruption in dump_station rtlwifi: Fix a double free in _rtl_usb_tx_urb_setup() md: don't flush workqueue unconditionally in md_open net: qed*: Reduce RX and TX default ring count when running inside kdump kernel wcn36xx: Fix error handling path in 'wcn36xx_probe()' nvme: refine the Qemu Identify CNS quirk kgdb: Fix spurious true from in_dbg_master() mips: cm: Fix an invalid error code of INTVN_*_ERR MIPS: Truncate link address into 32bit for 32bit kernel Crypto/chcr: fix for ccm(aes) failed test powerpc/spufs: fix copy_to_user while atomic net: allwinner: Fix use correct return type for ndo_start_xmit() media: cec: silence shift wrapping warning in __cec_s_log_addrs() net: lpc-enet: fix error return code in lpc_mii_init() exit: Move preemption fixup up, move blocking operations down lib/mpi: Fix 64-bit MIPS build with Clang net: bcmgenet: set Rx mode before starting netif netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported audit: fix a net reference leak in audit_list_rules_send() MIPS: Make sparse_init() using top-down allocation media: platform: fcp: Set appropriate DMA parameters media: dvb: return -EREMOTEIO on i2c transfer failure. audit: fix a net reference leak in audit_send_reply() dt-bindings: display: mediatek: control dpi pins mode to avoid leakage e1000: Distribute switch variables for initialization tools api fs: Make xxx__mountpoint() more scalable brcmfmac: fix wrong location to get firmware feature staging: android: ion: use vmap instead of vm_map_ram net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss() x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit spi: dw: Fix Rx-only DMA transfers ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums clocksource: dw_apb_timer_of: Fix missing clockevent timers clocksource: dw_apb_timer: Make CPU-affiliation being optional spi: dw: Enable interrupts in accordance with DMA xfer mode kgdb: Prevent infinite recursive entries to the debugger Bluetooth: Add SCO fallback for invalid LMP parameters error MIPS: Loongson: Build ATI Radeon GPU driver as module ixgbe: Fix XDP redirect on archs with PAGE_SIZE above 4K spi: dw: Zero DMA Tx and Rx configurations on stack net: ena: fix error returning in ena_com_get_hash_function() spi: pxa2xx: Apply CS clk quirk to BXT objtool: Ignore empty alternatives media: si2157: Better check for running tuner in init crypto: ccp -- don't "select" CONFIG_DMADEVICES drm: bridge: adv7511: Extend list of audio sample rates ACPI: GED: use correct trigger type field in _Exx / _Lxx handling xen/pvcalls-back: test for errors when calling backend_connect() can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices mmc: sdio: Fix potential NULL pointer error in mmc_sdio_init_card() mmc: sdhci-msm: Clear tuning done flag while hs400 tuning agp/intel: Reinforce the barrier after GTT updates perf: Add cond_resched() to task_function_call() fat: don't allow to mount if the FAT length == 0 mm/slub: fix a memory leak in sysfs_slab_add() Smack: slab-out-of-bounds in vsscanf ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb ath9k: Fix use-after-free Write in ath9k_htc_rx_msg ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data) KVM: nVMX: Consult only the "basic" exit reason when routing nested exit KVM: nSVM: leave ASID aside in copy_vmcb_control_area KVM: nSVM: fix condition for filtering async PF video: fbdev: w100fb: Fix a potential double free. proc: Use new_inode not new_inode_pseudo ovl: initialize error in ovl_copy_xattr selftests/net: in rxtimestamp getopt_long needs terminating null entry crypto: virtio: Fix dest length calculation in __virtio_crypto_skcipher_do_req() crypto: virtio: Fix src/dst scatterlist calculation in __virtio_crypto_skcipher_do_req() crypto: virtio: Fix use-after-free in virtio_crypto_skcipher_finalize_req() spi: bcm2835: Fix controller unregister order spi: pxa2xx: Fix controller unregister order spi: Fix controller unregister order spi: No need to assign dummy value in spi_unregister_controller() spi: dw: Fix controller unregister order spi: dw: fix possible race condition x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches. x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS. x86/speculation: Add support for STIBP always-on preferred mode x86/speculation: Change misspelled STIPB to STIBP KVM: x86: only do L1TF workaround on affected processors KVM: x86/mmu: Consolidate "is MMIO SPTE" code kvm: x86: Fix L1TF mitigation for shadow MMU ALSA: pcm: disallow linking stream to itself crypto: cavium/nitrox - Fix 'nitrox_get_first_device()' when ndevlist is fully iterated spi: bcm-qspi: when tx/rx buffer is NULL set to 0 spi: bcm2835aux: Fix controller unregister order nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() cgroup, blkcg: Prepare some symbols for module and !CONFIG_CGROUP usages ACPI: PM: Avoid using power resources if there are none for D0 ACPI: GED: add support for _Exx / _Lxx handler methods ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() ALSA: usb-audio: Fix inconsistent card PM state after resume ALSA: hda/realtek - add a pintbl quirk for several Lenovo machines ALSA: es1688: Add the missed snd_card_free() efi/efivars: Add missing kobject_put() in sysfs entry creation error path x86/reboot/quirks: Add MacBook6,1 reboot quirk x86/speculation: Prevent rogue cross-process SSBD shutdown x86/PCI: Mark Intel C620 MROMs as having non-compliant BARs x86_64: Fix jiffies ODR violation mm: add kvfree_sensitive() for freeing sensitive data objects perf probe: Accept the instance number of kretprobe event ath9k_htc: Silence undersized packet warnings powerpc/xive: Clear the page tables for the ESB IO mapping drivers/net/ibmvnic: Update VNIC protocol version reporting Input: synaptics - add a second working PNP_ID for Lenovo T470s sched/fair: Don't NUMA balance for kthreads ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook crypto: talitos - fix ECB and CBC algs ivsize serial: imx: Fix handling of TC irq in combination with DMA lib: Reduce user_access_begin() boundaries in strncpy_from_user() and strnlen_user() x86: uaccess: Inhibit speculation past access_ok() in user_access_begin() arch/openrisc: Fix issues with access_ok() Fix 'acccess_ok()' on alpha and SH make 'user_access_begin()' do 'access_ok()' vxlan: Avoid infinite loop when suppressing NS messages with invalid options ipv6: fix IPV6_ADDRFORM operation logic writeback: Drop I_DIRTY_TIME_EXPIRE 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 Revert "writeback: Avoid skipping inode writeback" ANDROID: Enable LZ4_RAMDISK fscrypt: remove stale definition fs-verity: remove unnecessary extern keywords fs-verity: fix all kerneldoc warnings fscrypt: add support for IV_INO_LBLK_32 policies fscrypt: make test_dummy_encryption use v2 by default fscrypt: support test_dummy_encryption=v2 fscrypt: add fscrypt_add_test_dummy_key() linux/parser.h: add include guards fscrypt: remove unnecessary extern keywords fscrypt: name all function parameters fscrypt: fix all kerneldoc warnings ANDROID: kbuild: merge more sections with LTO Linux 4.14.184 uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned iio: vcnl4000: Fix i2c swapped word reading. x86/speculation: Add Ivy Bridge to affected list x86/speculation: Add SRBDS vulnerability and mitigation documentation x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) mitigation x86/cpu: Add 'table' argument to cpu_matches() x86/cpu: Add a steppings field to struct x86_cpu_id nvmem: qfprom: remove incorrect write support CDC-ACM: heed quirk also in error handling staging: rtl8712: Fix IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK tty: hvc_console, fix crashes on parallel open/close vt: keyboard: avoid signed integer overflow in k_ascii usb: musb: Fix runtime PM imbalance on error usb: musb: start session in resume for host port USB: serial: option: add Telit LE910C1-EUX compositions USB: serial: usb_wwan: do not resubmit rx urb on fatal errors USB: serial: qcserial: add DW5816e QDL support l2tp: add sk_family checks to l2tp_validate_socket net: check untrusted gso_size at kernel entry vsock: fix timeout in vsock_accept() NFC: st21nfca: add missed kfree_skb() in an error path net: usb: qmi_wwan: add Telit LE910C1-EUX composition l2tp: do not use inet_hash()/inet_unhash() devinet: fix memleak in inetdev_init() airo: Fix read overflows sending packets scsi: ufs: Release clock if DMA map fails mmc: fix compilation of user API kernel/relay.c: handle alloc_percpu returning NULL in relay_open p54usb: add AirVasT USB stick device-id HID: i2c-hid: add Schneider SCL142ALM to descriptor override HID: sony: Fix for broken buttons on DS3 USB dongles mm: Fix mremap not considering huge pmd devmap net: smsc911x: Fix runtime PM imbalance on error net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x net/ethernet/freescale: rework quiesce/activate for ucc_geth net: bmac: Fix read of MAC address from ROM x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables i2c: altera: Fix race between xfer_msg and isr thread ARC: [plat-eznps]: Restrict to CONFIG_ISA_ARCOMPACT ARC: Fix ICCM & DCCM runtime size checks pppoe: only process PADT targeted at local interfaces s390/ftrace: save traced function caller spi: dw: use "smp_mb()" to avoid sending spi data error scsi: hisi_sas: Check sas_port before using it libnvdimm: Fix endian conversion issues scsi: scsi_devinfo: fixup string compare ANDROID: Incremental fs: Remove dependency on PKCS7_MESSAGE_PARSER f2fs: attach IO flags to the missing cases f2fs: add node_io_flag for bio flags likewise data_io_flag f2fs: remove unused parameter of f2fs_put_rpages_mapping() f2fs: handle readonly filesystem in f2fs_ioc_shutdown() f2fs: avoid utf8_strncasecmp() with unstable name f2fs: don't return vmalloc() memory from f2fs_kmalloc() ANDROID: dm-bow: Add block_size option ANDROID: Incremental fs: Cache successful hash calculations ANDROID: Incremental fs: Fix four error-path bugs ANDROID: cuttlefish_defconfig: Disable CMOS RTC driver f2fs: fix retry logic in f2fs_write_cache_pages() ANDROID: modules: fix lockprove warning BACKPORT: arm64: vdso: Explicitly add build-id option BACKPORT: arm64: vdso: use $(LD) instead of $(CC) to link VDSO Linux 4.14.183 scsi: zfcp: fix request object use-after-free in send path causing wrong traces genirq/generic_pending: Do not lose pending affinity update net: hns: Fixes the missing put_device in positive leg for roce reset net: hns: fix unsigned comparison to less than zero KVM: VMX: check for existence of secondary exec controls before accessing rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket sc16is7xx: move label 'err_spi' to correct section mm/vmalloc.c: don't dereference possible NULL pointer in __vunmap() netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build bonding: Fix reference count leak in bond_sysfs_slave_add. qlcnic: fix missing release in qlcnic_83xx_interrupt_test. esp6: get the right proto for transport mode in esp6_gso_encap netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code netfilter: nfnetlink_cthelper: unbreak userspace helper support netfilter: ipset: Fix subcounter update skip netfilter: nft_reject_bridge: enable reject with bridge vlan ip_vti: receive ipip packet by calling ip_tunnel_rcv vti4: eliminated some duplicate code. xfrm: fix error in comment xfrm: fix a NULL-ptr deref in xfrm_local_error xfrm: fix a warning in xfrm_policy_insert_list xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input copy_xstate_to_kernel(): don't leave parts of destination uninitialized x86/dma: Fix max PFN arithmetic overflow on 32 bit systems mac80211: mesh: fix discovery timer re-arming issue / crash parisc: Fix kernel panic in mem_init() iommu: Fix reference count leak in iommu_group_alloc. include/asm-generic/topology.h: guard cpumask_of_node() macro argument fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() mm: remove VM_BUG_ON(PageSlab()) from page_mapcount() libceph: ignore pool overlay and cache logic on redirects ALSA: hda/realtek - Add new codec supported for ALC287 exec: Always set cap_ambient in cap_bprm_set_creds ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC ALSA: hwdep: fix a left shifting 1 by 31 UB bug RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe() mmc: block: Fix use-after-free issue for rpmb ARM: dts: bcm2835-rpi-zero-w: Fix led polarity ARM: dts/imx6q-bx50v3: Set display interface clock parents ARM: dts: imx6q-bx50v3: Add internal switch IB/qib: Call kobject_put() when kobject_init_and_add() fails gpio: exar: Fix bad handling for ida_simple_get error path ARM: uaccess: fix DACR mismatch with nested exceptions ARM: uaccess: integrate uaccess_save and uaccess_restore ARM: uaccess: consolidate uaccess asm to asm/uaccess-asm.h ARM: 8843/1: use unified assembler in headers Input: synaptics-rmi4 - fix error return code in rmi_driver_probe() Input: synaptics-rmi4 - really fix attn_data use-after-free Input: i8042 - add ThinkPad S230u to i8042 reset list Input: dlink-dir685-touchkeys - fix a typo in driver name Input: xpad - add custom init packet for Xbox One S controllers Input: evdev - call input_flush_device() on release(), not flush() Input: usbtouchscreen - add support for BonXeon TP samples: bpf: Fix build error cifs: Fix null pointer check in cifs_read net: freescale: select CONFIG_FIXED_PHY where needed usb: gadget: legacy: fix redundant initialization warnings cachefiles: Fix race between read_waiter and read_copier involving op->to_do gfs2: move privileged user check to gfs2_quota_lock_check net: microchip: encx24j600: add missed kthread_stop gpio: tegra: mask GPIO IRQs during IRQ shutdown ARM: dts: rockchip: fix pinctrl sub nodename for spi in rk322x.dtsi arm64: dts: rockchip: swap interrupts interrupt-names rk3399 gpu node ARM: dts: rockchip: fix phy nodename for rk3228-evb net/mlx4_core: fix a memory leak bug. net: sun: fix missing release regions in cas_init_one(). net: qrtr: Fix passing invalid reference to qrtr_local_enqueue() net/mlx5e: Update netdev txq on completions during closure sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and socket is closed r8152: support additional Microsoft Surface Ethernet Adapter variant net sched: fix reporting the first-time use timestamp net: revert "net: get rid of an signed integer overflow in ip_idents_reserve()" net/mlx5: Add command entry handling completion net: ipip: fix wrong address family in init error path ax25: fix setsockopt(SO_BINDTODEVICE) ANDROID: scs: fix recursive spinlock in scs_check_usage ANDROID: timer: fix timer_setup with CFI FROMGIT: USB: dummy-hcd: use configurable endpoint naming scheme UPSTREAM: USB: dummy-hcd: remove unsupported isochronous endpoints UPSTREAM: usb: raw-gadget: fix null-ptr-deref when reenabling endpoints UPSTREAM: usb: raw-gadget: documentation updates UPSTREAM: usb: raw-gadget: support stalling/halting/wedging endpoints UPSTREAM: usb: raw-gadget: fix gadget endpoint selection UPSTREAM: usb: raw-gadget: improve uapi headers comments UPSTREAM: usb: raw-gadget: fix return value of ep read ioctls UPSTREAM: usb: raw-gadget: fix raw_event_queue_fetch locking UPSTREAM: usb: raw-gadget: Fix copy_to/from_user() checks f2fs: fix wrong discard space f2fs: compress: don't compress any datas after cp stop f2fs: remove unneeded return value of __insert_discard_tree() f2fs: fix wrong value of tracepoint parameter f2fs: protect new segment allocation in expand_inode_data f2fs: code cleanup by removing ifdef macro surrounding writeback: Avoid skipping inode writeback ANDROID: net: bpf: permit redirect from ingress L3 to egress L2 devices at near max mtu Revert "ANDROID: Incremental fs: Avoid continually recalculating hashes" Linux 4.14.182 iio: adc: stm32-adc: fix device used to request dma iio: adc: stm32-adc: Use dma_request_chan() instead dma_request_slave_channel() x86/unwind/orc: Fix unwind_get_return_address_ptr() for inactive tasks rxrpc: Fix a memory leak in rxkad_verify_response() rapidio: fix an error in get_user_pages_fast() error handling mei: release me_cl object reference iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()' iio: sca3000: Remove an erroneous 'get_device()' staging: greybus: Fix uninitialized scalar variable staging: iio: ad2s1210: Fix SPI reading Revert "gfs2: Don't demote a glock until its revokes are written" cxgb4/cxgb4vf: Fix mac_hlist initialization and free cxgb4: free mac_hlist properly media: fdp1: Fix R-Car M3-N naming in debug message libnvdimm/btt: Fix LBA masking during 'free list' population libnvdimm/btt: Remove unnecessary code in btt_freelist_init ubsan: build ubsan.c more conservatively x86/uaccess, ubsan: Fix UBSAN vs. SMAP powerpc/64s: Disable STRICT_KERNEL_RWX powerpc: Remove STRICT_KERNEL_RWX incompatibility with RELOCATABLE powerpc: restore alphabetic order in Kconfig dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()' apparmor: Fix aa_label refcnt leak in policy_update ALSA: pcm: fix incorrect hw_base increase ALSA: iec1712: Initialize STDSP24 properly when using the model=staudio option l2tp: initialise PPP sessions before registering them l2tp: protect sock pointer of struct pppol2tp_session with RCU l2tp: initialise l2tp_eth sessions before registering them l2tp: don't register sessions in l2tp_session_create() arm64: fix the flush_icache_range arguments in machine_kexec padata: purge get_cpu and reorder_via_wq from padata_do_serial padata: initialize pd->cpu with effective cpumask padata: Replace delayed timer with immediate workqueue in padata_reorder padata: set cpu_index of unused CPUs to -1 ARM: futex: Address build warning platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA USB: core: Fix misleading driver bug report ceph: fix double unlock in handle_cap_export() gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp() x86/apic: Move TSC deadline timer debug printk scsi: ibmvscsi: Fix WARN_ON during event pool release component: Silence bind error on -EPROBE_DEFER vhost/vsock: fix packet delivery order to monitoring devices configfs: fix config_item refcnt leak in configfs_rmdir() scsi: qla2xxx: Fix hang when issuing nvme disconnect-all in NPIV HID: multitouch: add eGalaxTouch P80H84 support gcc-common.h: Update for GCC 10 ubi: Fix seq_file usage in detailed_erase_block_info debugfs file i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()' iommu/amd: Fix over-read of ACPI UID from IVRS table fix multiplication overflow in copy_fdtable() ima: Fix return value of ima_write_policy() evm: Check also if *tfm is an error pointer in init_desc() ima: Set file->f_mode instead of file->f_flags in ima_calc_file_hash() padata: ensure padata_do_serial() runs on the correct CPU padata: ensure the reorder timer callback runs on the correct CPU i2c: dev: Fix the race between the release of i2c_dev and cdev watchdog: Fix the race between the release of watchdog_core_data and cdev ext4: add cond_resched() to ext4_protect_reserved_inode ANDROID: scsi: ufs: Handle clocks when lrbp fails ANDROID: fscrypt: handle direct I/O with IV_INO_LBLK_32 BACKPORT: FROMLIST: fscrypt: add support for IV_INO_LBLK_32 policies f2fs: avoid inifinite loop to wait for flushing node pages at cp_error ANDROID: namespace'ify tcp_default_init_rwnd implementation Linux 4.14.181 Makefile: disallow data races on gcc-10 as well KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce ARM: dts: r8a7740: Add missing extal2 to CPG node ARM: dts: r8a73a4: Add missing CMT1 interrupts arm64: dts: rockchip: Rename dwc3 device nodes on rk3399 to make dtc happy arm64: dts: rockchip: Replace RK805 PMIC node name with "pmic" on rk3328 boards Revert "ALSA: hda/realtek: Fix pop noise on ALC225" usb: gadget: legacy: fix error return code in cdc_bind() usb: gadget: legacy: fix error return code in gncm_bind() usb: gadget: audio: Fix a missing error return value in audio_bind() usb: gadget: net2272: Fix a memory leak in an error handling path in 'net2272_plat_probe()' clk: rockchip: fix incorrect configuration of rk3228 aclk_gpu* clocks exec: Move would_dump into flush_old_exec x86/unwind/orc: Fix error handling in __unwind_start() usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list USB: gadget: fix illegal array access in binding with UDC usb: host: xhci-plat: keep runtime active when removing host usb: core: hub: limit HUB_QUIRK_DISABLE_AUTOSUSPEND to USB5534B ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset x86: Fix early boot crash on gcc-10, third try ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries ARM: dts: dra7: Fix bus_dma_limit for PCIe ALSA: rawmidi: Fix racy buffer resize under concurrent accesses ALSA: rawmidi: Initialize allocated buffers ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 net: tcp: fix rx timestamp behavior for tcp_recvmsg netprio_cgroup: Fix unlimited memory leak of v2 cgroups net: ipv4: really enforce backoff for redirects net: dsa: loop: Add module soft dependency hinic: fix a bug of ndo_stop Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu" net: phy: fix aneg restart in phy_ethtool_set_eee netlabel: cope with NULL catmap net: fix a potential recursive NETDEV_FEAT_CHANGE net: phy: micrel: Use strlcpy() for ethtool::get_strings x86/asm: Add instruction suffixes to bitops gcc-10: avoid shadowing standard library 'free()' in crypto gcc-10: disable 'restrict' warning for now gcc-10: disable 'stringop-overflow' warning for now gcc-10: disable 'array-bounds' warning for now gcc-10: disable 'zero-length-bounds' warning for now Stop the ad-hoc games with -Wno-maybe-initialized kbuild: compute false-positive -Wmaybe-uninitialized cases in Kconfig gcc-10 warnings: fix low-hanging fruit pnp: Use list_for_each_entry() instead of open coding hwmon: (da9052) Synchronize access with mfd IB/mlx4: Test return value of calls to ib_get_cached_pkey netfilter: conntrack: avoid gcc-10 zero-length-bounds warning i40iw: Fix error handling in i40iw_manage_arp_cache() pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler pinctrl: baytrail: Enable pin configuration setting for GPIO chip ipmi: Fix NULL pointer dereference in ssif_probe x86/entry/64: Fix unwind hints in register clearing code ALSA: hda/realtek - Fix S3 pop noise on Dell Wyse ipc/util.c: sysvipc_find_ipc() incorrectly updates position index drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper() ALSA: hda/hdmi: fix race in monitor detection during probe cpufreq: intel_pstate: Only mention the BIOS disabling turbo mode once dmaengine: mmp_tdma: Reset channel error on release dmaengine: pch_dma.c: Avoid data race between probe and irq handler scsi: sg: add sg_remove_request in sg_write virtio-blk: handle block_device_operations callbacks after hot unplug drop_monitor: work around gcc-10 stringop-overflow warning net: moxa: Fix a potential double 'free_irq()' net/sonic: Fix a resource leak in an error handling path in 'jazz_sonic_probe()' shmem: fix possible deadlocks on shmlock_user_lock net: stmmac: Use mutex instead of spinlock f2fs: fix to avoid memory leakage in f2fs_listxattr f2fs: fix to avoid accessing xattr across the boundary f2fs: sanity check of xattr entry size f2fs: introduce read_xattr_block f2fs: introduce read_inline_xattr blktrace: fix dereference after null check blktrace: Protect q->blk_trace with RCU blktrace: fix trace mutex deadlock blktrace: fix unlocked access to init/start-stop/teardown net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup net: ipv6: add net argument to ip6_dst_lookup_flow scripts/decodecode: fix trapping instruction formatting objtool: Fix stack offset tracking for indirect CFAs netfilter: nat: never update the UDP checksum when it's 0 x86/unwind/orc: Fix error path for bad ORC entry type x86/unwind/orc: Prevent unwinding before ORC initialization x86/unwind/orc: Don't skip the first frame for inactive tasks x86/entry/64: Fix unwind hints in rewind_stack_do_exit() x86/entry/64: Fix unwind hints in kernel exit path batman-adv: Fix refcnt leak in batadv_v_ogm_process batman-adv: Fix refcnt leak in batadv_store_throughput_override batman-adv: Fix refcnt leak in batadv_show_throughput_override batman-adv: fix batadv_nc_random_weight_tq coredump: fix crash when umh is disabled mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous() KVM: arm: vgic: Fix limit condition when writing to GICD_I[CS]ACTIVER tracing: Add a vmalloc_sync_mappings() for safe measure USB: serial: garmin_gps: add sanity checking for data length USB: uas: add quirk for LaCie 2Big Quadra HID: usbhid: Fix race between usbhid_close() and usbhid_stop() geneve: only configure or fill UDP_ZERO_CSUM6_RX/TX info when CONFIG_IPV6 HID: wacom: Read HID_DG_CONTACTMAX directly for non-generic devices ipv6: fix cleanup ordering for ip6_mr failure net: stricter validation of untrusted gso packets bnxt_en: Fix VF anti-spoof filter setup. bnxt_en: Improve AER slot reset. net/mlx5: Fix command entry leak in Internal Error State net/mlx5: Fix forced completion access non initialized command entry bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features(). sch_sfq: validate silly quantum values sch_choke: avoid potential panic in choke_reset() net: usb: qmi_wwan: add support for DW5816e net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() net: macsec: preserve ingress frame ordering fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks dp83640: reverse arguments to list_add_tail USB: serial: qcserial: Add DW5816e support f2fs: compress: fix zstd data corruption f2fs: add compressed/gc data read IO stat f2fs: fix potential use-after-free issue f2fs: compress: don't handle non-compressed data in workqueue f2fs: remove redundant assignment to variable err f2fs: refactor resize_fs to avoid meta updates in progress f2fs: use round_up to enhance calculation f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS f2fs: Avoid double lock for cp_rwsem during checkpoint f2fs: report delalloc reserve as non-free in statfs for project quota f2fs: Fix wrong stub helper update_sit_info f2fs: compress: let lz4 compressor handle output buffer budget properly f2fs: remove blk_plugging in block_operations f2fs: introduce F2FS_IOC_RELEASE_COMPRESS_BLOCKS f2fs: shrink spinlock coverage f2fs: correctly fix the parent inode number during fsync() f2fs: introduce mempool for {,de}compress intermediate page allocation f2fs: introduce f2fs_bmap_compress() f2fs: support fiemap on compressed inode f2fs: support partial truncation on compressed inode f2fs: remove redundant compress inode check f2fs: flush dirty meta pages when flushing them f2fs: use strcmp() in parse_options() f2fs: fix checkpoint=disable:%u%% f2fs: Use the correct style for SPDX License Identifier f2fs: rework filename handling f2fs: split f2fs_d_compare() from f2fs_match_name() f2fs: don't leak filename in f2fs_try_convert_inline_dir() ANDROID: clang: update to 11.0.1 FROMLIST: x86_64: fix jiffies ODR violation ANDROID: cuttlefish_defconfig: Enable net testing options ANDROID: Incremental fs: wake up log pollers less often ANDROID: Incremental fs: Fix scheduling while atomic error ANDROID: Incremental fs: Avoid continually recalculating hashes Revert "f2fs: refactor resize_fs to avoid meta updates in progress" UPSTREAM: HID: steam: Fix input device disappearing ANDROID: fscrypt: set dun_bytes more precisely ANDROID: dm-default-key: set dun_bytes more precisely ANDROID: block: backport the ability to specify max_dun_bytes ANDROID: hid: steam: remove BT controller matching ANDROID: dm-default-key: Update key size for wrapped keys ANDROID: cuttlefish_defconfig: Enable CONFIG_STATIC_USERMODEHELPER ANDROID: cuttlefish_defconfig: enable CONFIG_MMC_CRYPTO ANDROID: Add padding for crypto related structs in UFS and MMC ANDROID: mmc: MMC crypto API f2fs: fix missing check for f2fs_unlock_op f2fs: refactor resize_fs to avoid meta updates in progress Conflicts: Documentation/devicetree/bindings/usb/dwc3.txt drivers/block/virtio_blk.c drivers/mmc/core/Kconfig drivers/mmc/core/block.c drivers/mmc/host/sdhci-msm.c drivers/net/ethernet/stmicro/stmmac/stmmac.h drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c drivers/net/ethernet/stmicro/stmmac/stmmac_main.c drivers/scsi/ufs/ufs-qcom.c drivers/usb/gadget/composite.c drivers/usb/gadget/function/f_uac1_legacy.c fs/crypto/crypto.c fs/crypto/inline_crypt.c fs/crypto/keyring.c fs/f2fs/checkpoint.c include/linux/fs.h include/linux/mmc/host.h include/linux/mod_devicetable.h include/uapi/linux/input-event-codes.h net/qrtr/qrtr.c sound/core/compress_offload.c sound/core/rawmidi.c Fixed build errors: drivers/scsi/ufs/ufshcd.c Change-Id: I2add911b58d3c87b666ffa0fe46cbceb6cc56430 Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
1791 lines
45 KiB
C
1791 lines
45 KiB
C
/*
|
|
* IPv6 output functions
|
|
* Linux INET6 implementation
|
|
*
|
|
* Authors:
|
|
* Pedro Roque <roque@di.fc.ul.pt>
|
|
*
|
|
* Based on linux/net/ipv4/ip_output.c
|
|
*
|
|
* 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.
|
|
*
|
|
* Changes:
|
|
* A.N.Kuznetsov : airthmetics in fragmentation.
|
|
* extension headers are implemented.
|
|
* route changes now work.
|
|
* ip6_forward does not confuse sniffers.
|
|
* etc.
|
|
*
|
|
* H. von Brand : Added missing #include <linux/string.h>
|
|
* Imran Patel : frag id should be in NBO
|
|
* Kazunori MIYAZAWA @USAGI
|
|
* : add ip6_append_data and related functions
|
|
* for datagram xmit
|
|
*/
|
|
|
|
#include <linux/errno.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/string.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/net.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/if_arp.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/tcp.h>
|
|
#include <linux/route.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/bpf-cgroup.h>
|
|
#include <linux/netfilter.h>
|
|
#include <linux/netfilter_ipv6.h>
|
|
|
|
#include <net/sock.h>
|
|
#include <net/snmp.h>
|
|
|
|
#include <net/ipv6.h>
|
|
#include <net/ndisc.h>
|
|
#include <net/protocol.h>
|
|
#include <net/ip6_route.h>
|
|
#include <net/addrconf.h>
|
|
#include <net/rawv6.h>
|
|
#include <net/icmp.h>
|
|
#include <net/xfrm.h>
|
|
#include <net/checksum.h>
|
|
#include <linux/mroute6.h>
|
|
#include <net/l3mdev.h>
|
|
#include <net/lwtunnel.h>
|
|
|
|
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
{
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
struct net_device *dev = dst->dev;
|
|
struct neighbour *neigh;
|
|
struct in6_addr *nexthop;
|
|
int ret;
|
|
|
|
if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
|
|
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
|
|
|
if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(sk) &&
|
|
((mroute6_socket(net, skb) &&
|
|
!(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
|
|
ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
|
|
&ipv6_hdr(skb)->saddr))) {
|
|
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
|
|
|
|
/* Do not check for IFF_ALLMULTI; multicast routing
|
|
is not supported in any case.
|
|
*/
|
|
if (newskb)
|
|
NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
|
|
net, sk, newskb, NULL, newskb->dev,
|
|
dev_loopback_xmit);
|
|
|
|
if (ipv6_hdr(skb)->hop_limit == 0) {
|
|
IP6_INC_STATS(net, idev,
|
|
IPSTATS_MIB_OUTDISCARDS);
|
|
kfree_skb(skb);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, skb->len);
|
|
|
|
if (IPV6_ADDR_MC_SCOPE(&ipv6_hdr(skb)->daddr) <=
|
|
IPV6_ADDR_SCOPE_NODELOCAL &&
|
|
!(dev->flags & IFF_LOOPBACK)) {
|
|
kfree_skb(skb);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (lwtunnel_xmit_redirect(dst->lwtstate)) {
|
|
int res = lwtunnel_xmit(skb);
|
|
|
|
if (res < 0 || res == LWTUNNEL_XMIT_DONE)
|
|
return res;
|
|
}
|
|
|
|
rcu_read_lock_bh();
|
|
nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr);
|
|
neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop);
|
|
if (unlikely(!neigh))
|
|
neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false);
|
|
if (!IS_ERR(neigh)) {
|
|
sock_confirm_neigh(skb, neigh);
|
|
ret = neigh_output(neigh, skb);
|
|
rcu_read_unlock_bh();
|
|
return ret;
|
|
}
|
|
rcu_read_unlock_bh();
|
|
|
|
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
|
|
kfree_skb(skb);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
{
|
|
int ret;
|
|
|
|
ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
|
|
if (ret) {
|
|
kfree_skb(skb);
|
|
return ret;
|
|
}
|
|
|
|
#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
|
|
/* Policy lookup after SNAT yielded a new policy */
|
|
if (skb_dst(skb)->xfrm) {
|
|
IPCB(skb)->flags |= IPSKB_REROUTED;
|
|
return dst_output(net, sk, skb);
|
|
}
|
|
#endif
|
|
|
|
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
|
|
dst_allfrag(skb_dst(skb)) ||
|
|
(IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
|
|
return ip6_fragment(net, sk, skb, ip6_finish_output2);
|
|
else
|
|
return ip6_finish_output2(net, sk, skb);
|
|
}
|
|
|
|
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
{
|
|
struct net_device *dev = skb_dst(skb)->dev;
|
|
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
|
|
|
skb->protocol = htons(ETH_P_IPV6);
|
|
skb->dev = dev;
|
|
|
|
if (unlikely(idev->cnf.disable_ipv6)) {
|
|
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
|
kfree_skb(skb);
|
|
return 0;
|
|
}
|
|
|
|
return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
|
|
net, sk, skb, NULL, dev,
|
|
ip6_finish_output,
|
|
!(IP6CB(skb)->flags & IP6SKB_REROUTED));
|
|
}
|
|
|
|
bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np)
|
|
{
|
|
if (!np->autoflowlabel_set)
|
|
return ip6_default_np_autolabel(net);
|
|
else
|
|
return np->autoflowlabel;
|
|
}
|
|
|
|
/*
|
|
* xmit an sk_buff (used by TCP, SCTP and DCCP)
|
|
* Note : socket lock is not held for SYNACK packets, but might be modified
|
|
* by calls to skb_set_owner_w() and ipv6_local_error(),
|
|
* which are using proper atomic operations or spinlocks.
|
|
*/
|
|
int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
|
|
__u32 mark, struct ipv6_txoptions *opt, int tclass)
|
|
{
|
|
struct net *net = sock_net(sk);
|
|
const struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct in6_addr *first_hop = &fl6->daddr;
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
unsigned int head_room;
|
|
struct ipv6hdr *hdr;
|
|
u8 proto = fl6->flowi6_proto;
|
|
int seg_len = skb->len;
|
|
int hlimit = -1;
|
|
u32 mtu;
|
|
|
|
head_room = sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
|
|
if (opt)
|
|
head_room += opt->opt_nflen + opt->opt_flen;
|
|
|
|
if (unlikely(skb_headroom(skb) < head_room)) {
|
|
struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
|
|
if (!skb2) {
|
|
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_OUTDISCARDS);
|
|
kfree_skb(skb);
|
|
return -ENOBUFS;
|
|
}
|
|
if (skb->sk)
|
|
skb_set_owner_w(skb2, skb->sk);
|
|
consume_skb(skb);
|
|
skb = skb2;
|
|
}
|
|
|
|
if (opt) {
|
|
seg_len += opt->opt_nflen + opt->opt_flen;
|
|
|
|
if (opt->opt_flen)
|
|
ipv6_push_frag_opts(skb, opt, &proto);
|
|
|
|
if (opt->opt_nflen)
|
|
ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop,
|
|
&fl6->saddr);
|
|
}
|
|
|
|
skb_push(skb, sizeof(struct ipv6hdr));
|
|
skb_reset_network_header(skb);
|
|
hdr = ipv6_hdr(skb);
|
|
|
|
/*
|
|
* Fill in the IPv6 header
|
|
*/
|
|
if (np)
|
|
hlimit = np->hop_limit;
|
|
if (hlimit < 0)
|
|
hlimit = ip6_dst_hoplimit(dst);
|
|
|
|
ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel,
|
|
ip6_autoflowlabel(net, np), fl6));
|
|
|
|
hdr->payload_len = htons(seg_len);
|
|
hdr->nexthdr = proto;
|
|
hdr->hop_limit = hlimit;
|
|
|
|
hdr->saddr = fl6->saddr;
|
|
hdr->daddr = *first_hop;
|
|
|
|
skb->protocol = htons(ETH_P_IPV6);
|
|
skb->priority = sk->sk_priority;
|
|
skb->mark = mark;
|
|
|
|
mtu = dst_mtu(dst);
|
|
if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) {
|
|
IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_OUT, skb->len);
|
|
|
|
/* if egress device is enslaved to an L3 master device pass the
|
|
* skb to its handler for processing
|
|
*/
|
|
skb = l3mdev_ip6_out((struct sock *)sk, skb);
|
|
if (unlikely(!skb))
|
|
return 0;
|
|
|
|
/* hooks should never assume socket lock is held.
|
|
* we promote our socket to non const
|
|
*/
|
|
return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
|
net, (struct sock *)sk, skb, NULL, dst->dev,
|
|
dst_output);
|
|
}
|
|
|
|
skb->dev = dst->dev;
|
|
/* ipv6_local_error() does not require socket lock,
|
|
* we promote our socket to non const
|
|
*/
|
|
ipv6_local_error((struct sock *)sk, EMSGSIZE, fl6, mtu);
|
|
|
|
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);
|
|
kfree_skb(skb);
|
|
return -EMSGSIZE;
|
|
}
|
|
EXPORT_SYMBOL(ip6_xmit);
|
|
|
|
static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
|
|
{
|
|
struct ip6_ra_chain *ra;
|
|
struct sock *last = NULL;
|
|
|
|
read_lock(&ip6_ra_lock);
|
|
for (ra = ip6_ra_chain; ra; ra = ra->next) {
|
|
struct sock *sk = ra->sk;
|
|
if (sk && ra->sel == sel &&
|
|
(!sk->sk_bound_dev_if ||
|
|
sk->sk_bound_dev_if == skb->dev->ifindex)) {
|
|
if (last) {
|
|
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
|
|
if (skb2)
|
|
rawv6_rcv(last, skb2);
|
|
}
|
|
last = sk;
|
|
}
|
|
}
|
|
|
|
if (last) {
|
|
rawv6_rcv(last, skb);
|
|
read_unlock(&ip6_ra_lock);
|
|
return 1;
|
|
}
|
|
read_unlock(&ip6_ra_lock);
|
|
return 0;
|
|
}
|
|
|
|
static int ip6_forward_proxy_check(struct sk_buff *skb)
|
|
{
|
|
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
|
u8 nexthdr = hdr->nexthdr;
|
|
__be16 frag_off;
|
|
int offset;
|
|
|
|
if (ipv6_ext_hdr(nexthdr)) {
|
|
offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr, &frag_off);
|
|
if (offset < 0)
|
|
return 0;
|
|
} else
|
|
offset = sizeof(struct ipv6hdr);
|
|
|
|
if (nexthdr == IPPROTO_ICMPV6) {
|
|
struct icmp6hdr *icmp6;
|
|
|
|
if (!pskb_may_pull(skb, (skb_network_header(skb) +
|
|
offset + 1 - skb->data)))
|
|
return 0;
|
|
|
|
icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
|
|
|
|
switch (icmp6->icmp6_type) {
|
|
case NDISC_ROUTER_SOLICITATION:
|
|
case NDISC_ROUTER_ADVERTISEMENT:
|
|
case NDISC_NEIGHBOUR_SOLICITATION:
|
|
case NDISC_NEIGHBOUR_ADVERTISEMENT:
|
|
case NDISC_REDIRECT:
|
|
/* For reaction involving unicast neighbor discovery
|
|
* message destined to the proxied address, pass it to
|
|
* input function.
|
|
*/
|
|
return 1;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The proxying router can't forward traffic sent to a link-local
|
|
* address, so signal the sender and discard the packet. This
|
|
* behavior is clarified by the MIPv6 specification.
|
|
*/
|
|
if (ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) {
|
|
dst_link_failure(skb);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int ip6_forward_finish(struct net *net, struct sock *sk,
|
|
struct sk_buff *skb)
|
|
{
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
|
|
__IP6_ADD_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len);
|
|
|
|
return dst_output(net, sk, skb);
|
|
}
|
|
|
|
static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
|
|
{
|
|
unsigned int mtu;
|
|
struct inet6_dev *idev;
|
|
|
|
if (dst_metric_locked(dst, RTAX_MTU)) {
|
|
mtu = dst_metric_raw(dst, RTAX_MTU);
|
|
if (mtu)
|
|
return mtu;
|
|
}
|
|
|
|
mtu = IPV6_MIN_MTU;
|
|
rcu_read_lock();
|
|
idev = __in6_dev_get(dst->dev);
|
|
if (idev)
|
|
mtu = idev->cnf.mtu6;
|
|
rcu_read_unlock();
|
|
|
|
return mtu;
|
|
}
|
|
|
|
static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
|
|
{
|
|
if (skb->len <= mtu)
|
|
return false;
|
|
|
|
/* ipv6 conntrack defrag sets max_frag_size + ignore_df */
|
|
if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
|
|
return true;
|
|
|
|
if (skb->ignore_df)
|
|
return false;
|
|
|
|
if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
int ip6_forward(struct sk_buff *skb)
|
|
{
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
|
struct inet6_skb_parm *opt = IP6CB(skb);
|
|
struct net *net = dev_net(dst->dev);
|
|
u32 mtu;
|
|
|
|
if (net->ipv6.devconf_all->forwarding == 0)
|
|
goto error;
|
|
|
|
if (skb->pkt_type != PACKET_HOST)
|
|
goto drop;
|
|
|
|
if (unlikely(skb->sk))
|
|
goto drop;
|
|
|
|
if (skb_warn_if_lro(skb))
|
|
goto drop;
|
|
|
|
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_INDISCARDS);
|
|
goto drop;
|
|
}
|
|
|
|
skb_forward_csum(skb);
|
|
|
|
/*
|
|
* We DO NOT make any processing on
|
|
* RA packets, pushing them to user level AS IS
|
|
* without ane WARRANTY that application will be able
|
|
* to interpret them. The reason is that we
|
|
* cannot make anything clever here.
|
|
*
|
|
* We are not end-node, so that if packet contains
|
|
* AH/ESP, we cannot make anything.
|
|
* Defragmentation also would be mistake, RA packets
|
|
* cannot be fragmented, because there is no warranty
|
|
* that different fragments will go along one path. --ANK
|
|
*/
|
|
if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
|
|
if (ip6_call_ra_chain(skb, ntohs(opt->ra)))
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* check and decrement ttl
|
|
*/
|
|
if (hdr->hop_limit <= 1) {
|
|
/* Force OUTPUT device used as source address */
|
|
skb->dev = dst->dev;
|
|
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_INHDRERRORS);
|
|
|
|
kfree_skb(skb);
|
|
return -ETIMEDOUT;
|
|
}
|
|
|
|
/* XXX: idev->cnf.proxy_ndp? */
|
|
if (net->ipv6.devconf_all->proxy_ndp &&
|
|
pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
|
|
int proxied = ip6_forward_proxy_check(skb);
|
|
if (proxied > 0)
|
|
return ip6_input(skb);
|
|
else if (proxied < 0) {
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_INDISCARDS);
|
|
goto drop;
|
|
}
|
|
}
|
|
|
|
if (!xfrm6_route_forward(skb)) {
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_INDISCARDS);
|
|
goto drop;
|
|
}
|
|
dst = skb_dst(skb);
|
|
|
|
/* IPv6 specs say nothing about it, but it is clear that we cannot
|
|
send redirects to source routed frames.
|
|
We don't send redirects to frames decapsulated from IPsec.
|
|
*/
|
|
if (IP6CB(skb)->iif == dst->dev->ifindex &&
|
|
opt->srcrt == 0 && !skb_sec_path(skb)) {
|
|
struct in6_addr *target = NULL;
|
|
struct inet_peer *peer;
|
|
struct rt6_info *rt;
|
|
|
|
/*
|
|
* incoming and outgoing devices are the same
|
|
* send a redirect.
|
|
*/
|
|
|
|
rt = (struct rt6_info *) dst;
|
|
if (rt->rt6i_flags & RTF_GATEWAY)
|
|
target = &rt->rt6i_gateway;
|
|
else
|
|
target = &hdr->daddr;
|
|
|
|
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1);
|
|
|
|
/* Limit redirects both by destination (here)
|
|
and by source (inside ndisc_send_redirect)
|
|
*/
|
|
if (inet_peer_xrlim_allow(peer, 1*HZ))
|
|
ndisc_send_redirect(skb, target);
|
|
if (peer)
|
|
inet_putpeer(peer);
|
|
} else {
|
|
int addrtype = ipv6_addr_type(&hdr->saddr);
|
|
|
|
/* This check is security critical. */
|
|
if (addrtype == IPV6_ADDR_ANY ||
|
|
addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK))
|
|
goto error;
|
|
if (addrtype & IPV6_ADDR_LINKLOCAL) {
|
|
icmpv6_send(skb, ICMPV6_DEST_UNREACH,
|
|
ICMPV6_NOT_NEIGHBOUR, 0);
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
mtu = ip6_dst_mtu_forward(dst);
|
|
if (mtu < IPV6_MIN_MTU)
|
|
mtu = IPV6_MIN_MTU;
|
|
|
|
if (ip6_pkt_too_big(skb, mtu)) {
|
|
/* Again, force OUTPUT device used as source address */
|
|
skb->dev = dst->dev;
|
|
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_INTOOBIGERRORS);
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_FRAGFAILS);
|
|
kfree_skb(skb);
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
if (skb_cow(skb, dst->dev->hard_header_len)) {
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst),
|
|
IPSTATS_MIB_OUTDISCARDS);
|
|
goto drop;
|
|
}
|
|
|
|
hdr = ipv6_hdr(skb);
|
|
|
|
/* Mangling hops number delayed to point after skb COW */
|
|
|
|
hdr->hop_limit--;
|
|
|
|
return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD,
|
|
net, NULL, skb, skb->dev, dst->dev,
|
|
ip6_forward_finish);
|
|
|
|
error:
|
|
__IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
|
|
drop:
|
|
kfree_skb(skb);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
|
|
{
|
|
to->pkt_type = from->pkt_type;
|
|
to->priority = from->priority;
|
|
to->protocol = from->protocol;
|
|
skb_dst_drop(to);
|
|
skb_dst_set(to, dst_clone(skb_dst(from)));
|
|
to->dev = from->dev;
|
|
to->mark = from->mark;
|
|
|
|
skb_copy_hash(to, from);
|
|
|
|
#ifdef CONFIG_NET_SCHED
|
|
to->tc_index = from->tc_index;
|
|
#endif
|
|
nf_copy(to, from);
|
|
skb_copy_secmark(to, from);
|
|
}
|
|
|
|
int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|
int (*output)(struct net *, struct sock *, struct sk_buff *))
|
|
{
|
|
struct sk_buff *frag;
|
|
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
|
|
struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
|
|
inet6_sk(skb->sk) : NULL;
|
|
struct ipv6hdr *tmp_hdr;
|
|
struct frag_hdr *fh;
|
|
unsigned int mtu, hlen, left, len, nexthdr_offset;
|
|
int hroom, troom;
|
|
__be32 frag_id;
|
|
int ptr, offset = 0, err = 0;
|
|
u8 *prevhdr, nexthdr = 0;
|
|
|
|
err = ip6_find_1stfragopt(skb, &prevhdr);
|
|
if (err < 0)
|
|
goto fail;
|
|
hlen = err;
|
|
nexthdr = *prevhdr;
|
|
nexthdr_offset = prevhdr - skb_network_header(skb);
|
|
|
|
mtu = ip6_skb_dst_mtu(skb);
|
|
|
|
/* We must not fragment if the socket is set to force MTU discovery
|
|
* or if the skb it not generated by a local socket.
|
|
*/
|
|
if (unlikely(!skb->ignore_df && skb->len > mtu))
|
|
goto fail_toobig;
|
|
|
|
if (IP6CB(skb)->frag_max_size) {
|
|
if (IP6CB(skb)->frag_max_size > mtu)
|
|
goto fail_toobig;
|
|
|
|
/* don't send fragments larger than what we received */
|
|
mtu = IP6CB(skb)->frag_max_size;
|
|
if (mtu < IPV6_MIN_MTU)
|
|
mtu = IPV6_MIN_MTU;
|
|
}
|
|
|
|
if (np && np->frag_size < mtu) {
|
|
if (np->frag_size)
|
|
mtu = np->frag_size;
|
|
}
|
|
if (mtu < hlen + sizeof(struct frag_hdr) + 8)
|
|
goto fail_toobig;
|
|
mtu -= hlen + sizeof(struct frag_hdr);
|
|
|
|
frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
|
|
&ipv6_hdr(skb)->saddr);
|
|
|
|
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
|
(err = skb_checksum_help(skb)))
|
|
goto fail;
|
|
|
|
prevhdr = skb_network_header(skb) + nexthdr_offset;
|
|
hroom = LL_RESERVED_SPACE(rt->dst.dev);
|
|
if (skb_has_frag_list(skb)) {
|
|
unsigned int first_len = skb_pagelen(skb);
|
|
struct sk_buff *frag2;
|
|
|
|
if (first_len - hlen > mtu ||
|
|
((first_len - hlen) & 7) ||
|
|
skb_cloned(skb) ||
|
|
skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
|
|
goto slow_path;
|
|
|
|
skb_walk_frags(skb, frag) {
|
|
/* Correct geometry. */
|
|
if (frag->len > mtu ||
|
|
((frag->len & 7) && frag->next) ||
|
|
skb_headroom(frag) < (hlen + hroom + sizeof(struct frag_hdr)))
|
|
goto slow_path_clean;
|
|
|
|
/* Partially cloned skb? */
|
|
if (skb_shared(frag))
|
|
goto slow_path_clean;
|
|
|
|
BUG_ON(frag->sk);
|
|
if (skb->sk) {
|
|
frag->sk = skb->sk;
|
|
frag->destructor = sock_wfree;
|
|
}
|
|
skb->truesize -= frag->truesize;
|
|
}
|
|
|
|
err = 0;
|
|
offset = 0;
|
|
/* BUILD HEADER */
|
|
|
|
*prevhdr = NEXTHDR_FRAGMENT;
|
|
tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
|
|
if (!tmp_hdr) {
|
|
err = -ENOMEM;
|
|
goto fail;
|
|
}
|
|
frag = skb_shinfo(skb)->frag_list;
|
|
skb_frag_list_init(skb);
|
|
|
|
__skb_pull(skb, hlen);
|
|
fh = __skb_push(skb, sizeof(struct frag_hdr));
|
|
__skb_push(skb, hlen);
|
|
skb_reset_network_header(skb);
|
|
memcpy(skb_network_header(skb), tmp_hdr, hlen);
|
|
|
|
fh->nexthdr = nexthdr;
|
|
fh->reserved = 0;
|
|
fh->frag_off = htons(IP6_MF);
|
|
fh->identification = frag_id;
|
|
|
|
first_len = skb_pagelen(skb);
|
|
skb->data_len = first_len - skb_headlen(skb);
|
|
skb->len = first_len;
|
|
ipv6_hdr(skb)->payload_len = htons(first_len -
|
|
sizeof(struct ipv6hdr));
|
|
|
|
for (;;) {
|
|
/* Prepare header of the next frame,
|
|
* before previous one went down. */
|
|
if (frag) {
|
|
frag->ip_summed = CHECKSUM_NONE;
|
|
skb_reset_transport_header(frag);
|
|
fh = __skb_push(frag, sizeof(struct frag_hdr));
|
|
__skb_push(frag, hlen);
|
|
skb_reset_network_header(frag);
|
|
memcpy(skb_network_header(frag), tmp_hdr,
|
|
hlen);
|
|
offset += skb->len - hlen - sizeof(struct frag_hdr);
|
|
fh->nexthdr = nexthdr;
|
|
fh->reserved = 0;
|
|
fh->frag_off = htons(offset);
|
|
if (frag->next)
|
|
fh->frag_off |= htons(IP6_MF);
|
|
fh->identification = frag_id;
|
|
ipv6_hdr(frag)->payload_len =
|
|
htons(frag->len -
|
|
sizeof(struct ipv6hdr));
|
|
ip6_copy_metadata(frag, skb);
|
|
}
|
|
|
|
err = output(net, sk, skb);
|
|
if (!err)
|
|
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
|
IPSTATS_MIB_FRAGCREATES);
|
|
|
|
if (err || !frag)
|
|
break;
|
|
|
|
skb = frag;
|
|
frag = skb->next;
|
|
skb->next = NULL;
|
|
}
|
|
|
|
kfree(tmp_hdr);
|
|
|
|
if (err == 0) {
|
|
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
|
IPSTATS_MIB_FRAGOKS);
|
|
return 0;
|
|
}
|
|
|
|
kfree_skb_list(frag);
|
|
|
|
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
|
IPSTATS_MIB_FRAGFAILS);
|
|
return err;
|
|
|
|
slow_path_clean:
|
|
skb_walk_frags(skb, frag2) {
|
|
if (frag2 == frag)
|
|
break;
|
|
frag2->sk = NULL;
|
|
frag2->destructor = NULL;
|
|
skb->truesize += frag2->truesize;
|
|
}
|
|
}
|
|
|
|
slow_path:
|
|
left = skb->len - hlen; /* Space per frame */
|
|
ptr = hlen; /* Where to start from */
|
|
|
|
/*
|
|
* Fragment the datagram.
|
|
*/
|
|
|
|
troom = rt->dst.dev->needed_tailroom;
|
|
|
|
/*
|
|
* Keep copying data until we run out.
|
|
*/
|
|
while (left > 0) {
|
|
u8 *fragnexthdr_offset;
|
|
|
|
len = left;
|
|
/* IF: it doesn't fit, use 'mtu' - the data space left */
|
|
if (len > mtu)
|
|
len = mtu;
|
|
/* IF: we are not sending up to and including the packet end
|
|
then align the next start on an eight byte boundary */
|
|
if (len < left) {
|
|
len &= ~7;
|
|
}
|
|
|
|
/* Allocate buffer */
|
|
frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) +
|
|
hroom + troom, GFP_ATOMIC);
|
|
if (!frag) {
|
|
err = -ENOMEM;
|
|
goto fail;
|
|
}
|
|
|
|
/*
|
|
* Set up data on packet
|
|
*/
|
|
|
|
ip6_copy_metadata(frag, skb);
|
|
skb_reserve(frag, hroom);
|
|
skb_put(frag, len + hlen + sizeof(struct frag_hdr));
|
|
skb_reset_network_header(frag);
|
|
fh = (struct frag_hdr *)(skb_network_header(frag) + hlen);
|
|
frag->transport_header = (frag->network_header + hlen +
|
|
sizeof(struct frag_hdr));
|
|
|
|
/*
|
|
* Charge the memory for the fragment to any owner
|
|
* it might possess
|
|
*/
|
|
if (skb->sk)
|
|
skb_set_owner_w(frag, skb->sk);
|
|
|
|
/*
|
|
* Copy the packet header into the new buffer.
|
|
*/
|
|
skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
|
|
|
|
fragnexthdr_offset = skb_network_header(frag);
|
|
fragnexthdr_offset += prevhdr - skb_network_header(skb);
|
|
*fragnexthdr_offset = NEXTHDR_FRAGMENT;
|
|
|
|
/*
|
|
* Build fragment header.
|
|
*/
|
|
fh->nexthdr = nexthdr;
|
|
fh->reserved = 0;
|
|
fh->identification = frag_id;
|
|
|
|
/*
|
|
* Copy a block of the IP datagram.
|
|
*/
|
|
BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag),
|
|
len));
|
|
left -= len;
|
|
|
|
fh->frag_off = htons(offset);
|
|
if (left > 0)
|
|
fh->frag_off |= htons(IP6_MF);
|
|
ipv6_hdr(frag)->payload_len = htons(frag->len -
|
|
sizeof(struct ipv6hdr));
|
|
|
|
ptr += len;
|
|
offset += len;
|
|
|
|
/*
|
|
* Put this fragment into the sending queue.
|
|
*/
|
|
err = output(net, sk, frag);
|
|
if (err)
|
|
goto fail;
|
|
|
|
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_FRAGCREATES);
|
|
}
|
|
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_FRAGOKS);
|
|
consume_skb(skb);
|
|
return err;
|
|
|
|
fail_toobig:
|
|
if (skb->sk && dst_allfrag(skb_dst(skb)))
|
|
sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
|
|
|
|
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
|
|
err = -EMSGSIZE;
|
|
|
|
fail:
|
|
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_FRAGFAILS);
|
|
kfree_skb(skb);
|
|
return err;
|
|
}
|
|
|
|
static inline int ip6_rt_check(const struct rt6key *rt_key,
|
|
const struct in6_addr *fl_addr,
|
|
const struct in6_addr *addr_cache)
|
|
{
|
|
return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
|
|
(!addr_cache || !ipv6_addr_equal(fl_addr, addr_cache));
|
|
}
|
|
|
|
static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
|
|
struct dst_entry *dst,
|
|
const struct flowi6 *fl6)
|
|
{
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct rt6_info *rt;
|
|
|
|
if (!dst)
|
|
goto out;
|
|
|
|
if (dst->ops->family != AF_INET6) {
|
|
dst_release(dst);
|
|
return NULL;
|
|
}
|
|
|
|
rt = (struct rt6_info *)dst;
|
|
/* Yes, checking route validity in not connected
|
|
* case is not very simple. Take into account,
|
|
* that we do not support routing by source, TOS,
|
|
* and MSG_DONTROUTE --ANK (980726)
|
|
*
|
|
* 1. ip6_rt_check(): If route was host route,
|
|
* check that cached destination is current.
|
|
* If it is network route, we still may
|
|
* check its validity using saved pointer
|
|
* to the last used address: daddr_cache.
|
|
* We do not want to save whole address now,
|
|
* (because main consumer of this service
|
|
* is tcp, which has not this problem),
|
|
* so that the last trick works only on connected
|
|
* sockets.
|
|
* 2. oif also should be the same.
|
|
*/
|
|
if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
|
|
#ifdef CONFIG_IPV6_SUBTREES
|
|
ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
|
|
#endif
|
|
(!(fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) &&
|
|
(fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex))) {
|
|
dst_release(dst);
|
|
dst = NULL;
|
|
}
|
|
|
|
out:
|
|
return dst;
|
|
}
|
|
|
|
static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
|
|
struct dst_entry **dst, struct flowi6 *fl6)
|
|
{
|
|
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
|
|
struct neighbour *n;
|
|
struct rt6_info *rt;
|
|
#endif
|
|
int err;
|
|
int flags = 0;
|
|
|
|
/* The correct way to handle this would be to do
|
|
* ip6_route_get_saddr, and then ip6_route_output; however,
|
|
* the route-specific preferred source forces the
|
|
* ip6_route_output call _before_ ip6_route_get_saddr.
|
|
*
|
|
* In source specific routing (no src=any default route),
|
|
* ip6_route_output will fail given src=any saddr, though, so
|
|
* that's why we try it again later.
|
|
*/
|
|
if (ipv6_addr_any(&fl6->saddr) && (!*dst || !(*dst)->error)) {
|
|
struct rt6_info *rt;
|
|
bool had_dst = *dst != NULL;
|
|
|
|
if (!had_dst)
|
|
*dst = ip6_route_output(net, sk, fl6);
|
|
rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
|
|
err = ip6_route_get_saddr(net, rt, &fl6->daddr,
|
|
sk ? inet6_sk(sk)->srcprefs : 0,
|
|
&fl6->saddr);
|
|
if (err)
|
|
goto out_err_release;
|
|
|
|
/* If we had an erroneous initial result, pretend it
|
|
* never existed and let the SA-enabled version take
|
|
* over.
|
|
*/
|
|
if (!had_dst && (*dst)->error) {
|
|
dst_release(*dst);
|
|
*dst = NULL;
|
|
}
|
|
|
|
if (fl6->flowi6_oif)
|
|
flags |= RT6_LOOKUP_F_IFACE;
|
|
}
|
|
|
|
if (!*dst)
|
|
*dst = ip6_route_output_flags(net, sk, fl6, flags);
|
|
|
|
err = (*dst)->error;
|
|
if (err)
|
|
goto out_err_release;
|
|
|
|
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
|
|
/*
|
|
* Here if the dst entry we've looked up
|
|
* has a neighbour entry that is in the INCOMPLETE
|
|
* state and the src address from the flow is
|
|
* marked as OPTIMISTIC, we release the found
|
|
* dst entry and replace it instead with the
|
|
* dst entry of the nexthop router
|
|
*/
|
|
rt = (struct rt6_info *) *dst;
|
|
rcu_read_lock_bh();
|
|
n = __ipv6_neigh_lookup_noref(rt->dst.dev,
|
|
rt6_nexthop(rt, &fl6->daddr));
|
|
err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0;
|
|
rcu_read_unlock_bh();
|
|
|
|
if (err) {
|
|
struct inet6_ifaddr *ifp;
|
|
struct flowi6 fl_gw6;
|
|
int redirect;
|
|
|
|
ifp = ipv6_get_ifaddr(net, &fl6->saddr,
|
|
(*dst)->dev, 1);
|
|
|
|
redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
|
|
if (ifp)
|
|
in6_ifa_put(ifp);
|
|
|
|
if (redirect) {
|
|
/*
|
|
* We need to get the dst entry for the
|
|
* default router instead
|
|
*/
|
|
dst_release(*dst);
|
|
memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
|
|
memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
|
|
*dst = ip6_route_output(net, sk, &fl_gw6);
|
|
err = (*dst)->error;
|
|
if (err)
|
|
goto out_err_release;
|
|
}
|
|
}
|
|
#endif
|
|
if (ipv6_addr_v4mapped(&fl6->saddr) &&
|
|
!(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr))) {
|
|
err = -EAFNOSUPPORT;
|
|
goto out_err_release;
|
|
}
|
|
|
|
return 0;
|
|
|
|
out_err_release:
|
|
dst_release(*dst);
|
|
*dst = NULL;
|
|
|
|
if (err == -ENETUNREACH)
|
|
IP6_INC_STATS(net, NULL, IPSTATS_MIB_OUTNOROUTES);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* ip6_dst_lookup - perform route lookup on flow
|
|
* @sk: socket which provides route info
|
|
* @dst: pointer to dst_entry * for result
|
|
* @fl6: flow to lookup
|
|
*
|
|
* This function performs a route lookup on the given flow.
|
|
*
|
|
* It returns zero on success, or a standard errno code on error.
|
|
*/
|
|
int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
|
|
struct flowi6 *fl6)
|
|
{
|
|
*dst = NULL;
|
|
return ip6_dst_lookup_tail(net, sk, dst, fl6);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_dst_lookup);
|
|
|
|
/**
|
|
* ip6_dst_lookup_flow - perform route lookup on flow with ipsec
|
|
* @sk: socket which provides route info
|
|
* @fl6: flow to lookup
|
|
* @final_dst: final destination address for ipsec lookup
|
|
*
|
|
* This function performs a route lookup on the given flow.
|
|
*
|
|
* It returns a valid dst pointer on success, or a pointer encoded
|
|
* error code.
|
|
*/
|
|
struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
|
|
const struct in6_addr *final_dst)
|
|
{
|
|
struct dst_entry *dst = NULL;
|
|
int err;
|
|
|
|
err = ip6_dst_lookup_tail(net, sk, &dst, fl6);
|
|
if (err)
|
|
return ERR_PTR(err);
|
|
if (final_dst)
|
|
fl6->daddr = *final_dst;
|
|
|
|
return xfrm_lookup_route(net, dst, flowi6_to_flowi(fl6), sk, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
|
|
|
|
/**
|
|
* ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
|
|
* @sk: socket which provides the dst cache and route info
|
|
* @fl6: flow to lookup
|
|
* @final_dst: final destination address for ipsec lookup
|
|
*
|
|
* This function performs a route lookup on the given flow with the
|
|
* possibility of using the cached route in the socket if it is valid.
|
|
* It will take the socket dst lock when operating on the dst cache.
|
|
* As a result, this function can only be used in process context.
|
|
*
|
|
* It returns a valid dst pointer on success, or a pointer encoded
|
|
* error code.
|
|
*/
|
|
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
|
|
const struct in6_addr *final_dst)
|
|
{
|
|
struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
|
|
|
|
dst = ip6_sk_dst_check(sk, dst, fl6);
|
|
if (!dst)
|
|
dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_dst);
|
|
|
|
return dst;
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
|
|
|
|
static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
|
|
gfp_t gfp)
|
|
{
|
|
return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
|
|
}
|
|
|
|
static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
|
|
gfp_t gfp)
|
|
{
|
|
return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
|
|
}
|
|
|
|
static void ip6_append_data_mtu(unsigned int *mtu,
|
|
int *maxfraglen,
|
|
unsigned int fragheaderlen,
|
|
struct sk_buff *skb,
|
|
struct rt6_info *rt,
|
|
unsigned int orig_mtu)
|
|
{
|
|
if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
|
|
if (!skb) {
|
|
/* first fragment, reserve header_len */
|
|
*mtu = orig_mtu - rt->dst.header_len;
|
|
|
|
} else {
|
|
/*
|
|
* this fragment is not first, the headers
|
|
* space is regarded as data space.
|
|
*/
|
|
*mtu = orig_mtu;
|
|
}
|
|
*maxfraglen = ((*mtu - fragheaderlen) & ~7)
|
|
+ fragheaderlen - sizeof(struct frag_hdr);
|
|
}
|
|
}
|
|
|
|
static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
|
|
struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
|
|
struct rt6_info *rt, struct flowi6 *fl6)
|
|
{
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
unsigned int mtu;
|
|
struct ipv6_txoptions *opt = ipc6->opt;
|
|
|
|
/*
|
|
* setup for corking
|
|
*/
|
|
if (opt) {
|
|
if (WARN_ON(v6_cork->opt))
|
|
return -EINVAL;
|
|
|
|
v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation);
|
|
if (unlikely(!v6_cork->opt))
|
|
return -ENOBUFS;
|
|
|
|
v6_cork->opt->tot_len = sizeof(*opt);
|
|
v6_cork->opt->opt_flen = opt->opt_flen;
|
|
v6_cork->opt->opt_nflen = opt->opt_nflen;
|
|
|
|
v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
|
|
sk->sk_allocation);
|
|
if (opt->dst0opt && !v6_cork->opt->dst0opt)
|
|
return -ENOBUFS;
|
|
|
|
v6_cork->opt->dst1opt = ip6_opt_dup(opt->dst1opt,
|
|
sk->sk_allocation);
|
|
if (opt->dst1opt && !v6_cork->opt->dst1opt)
|
|
return -ENOBUFS;
|
|
|
|
v6_cork->opt->hopopt = ip6_opt_dup(opt->hopopt,
|
|
sk->sk_allocation);
|
|
if (opt->hopopt && !v6_cork->opt->hopopt)
|
|
return -ENOBUFS;
|
|
|
|
v6_cork->opt->srcrt = ip6_rthdr_dup(opt->srcrt,
|
|
sk->sk_allocation);
|
|
if (opt->srcrt && !v6_cork->opt->srcrt)
|
|
return -ENOBUFS;
|
|
|
|
/* need source address above miyazawa*/
|
|
}
|
|
dst_hold(&rt->dst);
|
|
cork->base.dst = &rt->dst;
|
|
cork->fl.u.ip6 = *fl6;
|
|
v6_cork->hop_limit = ipc6->hlimit;
|
|
v6_cork->tclass = ipc6->tclass;
|
|
if (rt->dst.flags & DST_XFRM_TUNNEL)
|
|
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
|
|
READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst);
|
|
else
|
|
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
|
|
READ_ONCE(rt->dst.dev->mtu) : dst_mtu(rt->dst.path);
|
|
if (np->frag_size < mtu) {
|
|
if (np->frag_size)
|
|
mtu = np->frag_size;
|
|
}
|
|
if (!(rt->dst.flags & DST_XFRM_TUNNEL) && mtu < IPV6_MIN_MTU)
|
|
return -EINVAL;
|
|
cork->base.fragsize = mtu;
|
|
cork->base.gso_size = sk->sk_type == SOCK_DGRAM &&
|
|
sk->sk_protocol == IPPROTO_UDP ? ipc6->gso_size : 0;
|
|
|
|
if (dst_allfrag(rt->dst.path))
|
|
cork->base.flags |= IPCORK_ALLFRAG;
|
|
cork->base.length = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __ip6_append_data(struct sock *sk,
|
|
struct flowi6 *fl6,
|
|
struct sk_buff_head *queue,
|
|
struct inet_cork *cork,
|
|
struct inet6_cork *v6_cork,
|
|
struct page_frag *pfrag,
|
|
int getfrag(void *from, char *to, int offset,
|
|
int len, int odd, struct sk_buff *skb),
|
|
void *from, int length, int transhdrlen,
|
|
unsigned int flags, struct ipcm6_cookie *ipc6,
|
|
const struct sockcm_cookie *sockc)
|
|
{
|
|
struct sk_buff *skb, *skb_prev = NULL;
|
|
unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
|
|
int exthdrlen = 0;
|
|
int dst_exthdrlen = 0;
|
|
int hh_len;
|
|
int copy;
|
|
int err;
|
|
int offset = 0;
|
|
__u8 tx_flags = 0;
|
|
u32 tskey = 0;
|
|
struct rt6_info *rt = (struct rt6_info *)cork->dst;
|
|
struct ipv6_txoptions *opt = v6_cork->opt;
|
|
int csummode = CHECKSUM_NONE;
|
|
unsigned int maxnonfragsize, headersize;
|
|
bool paged;
|
|
|
|
skb = skb_peek_tail(queue);
|
|
if (!skb) {
|
|
exthdrlen = opt ? opt->opt_flen : 0;
|
|
dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len;
|
|
}
|
|
|
|
paged = !!cork->gso_size;
|
|
mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize;
|
|
orig_mtu = mtu;
|
|
|
|
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
|
|
|
|
fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
|
|
(opt ? opt->opt_nflen : 0);
|
|
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
|
|
sizeof(struct frag_hdr);
|
|
|
|
headersize = sizeof(struct ipv6hdr) +
|
|
(opt ? opt->opt_flen + opt->opt_nflen : 0) +
|
|
(dst_allfrag(&rt->dst) ?
|
|
sizeof(struct frag_hdr) : 0) +
|
|
rt->rt6i_nfheader_len;
|
|
|
|
/* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
|
|
* the first fragment
|
|
*/
|
|
if (headersize + transhdrlen > mtu)
|
|
goto emsgsize;
|
|
|
|
if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
|
|
(sk->sk_protocol == IPPROTO_UDP ||
|
|
sk->sk_protocol == IPPROTO_RAW)) {
|
|
ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
|
|
sizeof(struct ipv6hdr));
|
|
goto emsgsize;
|
|
}
|
|
|
|
if (ip6_sk_ignore_df(sk))
|
|
maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
|
|
else
|
|
maxnonfragsize = mtu;
|
|
|
|
if (cork->length + length > maxnonfragsize - headersize) {
|
|
emsgsize:
|
|
pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
|
|
ipv6_local_error(sk, EMSGSIZE, fl6, pmtu);
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
/* CHECKSUM_PARTIAL only with no extension headers and when
|
|
* we are not going to fragment
|
|
*/
|
|
if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
|
|
headersize == sizeof(struct ipv6hdr) &&
|
|
length <= mtu - headersize &&
|
|
(!(flags & MSG_MORE) || cork->gso_size) &&
|
|
rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
|
|
csummode = CHECKSUM_PARTIAL;
|
|
|
|
if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) {
|
|
sock_tx_timestamp(sk, sockc->tsflags, &tx_flags);
|
|
if (tx_flags & SKBTX_ANY_SW_TSTAMP &&
|
|
sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
|
|
tskey = sk->sk_tskey++;
|
|
}
|
|
|
|
/*
|
|
* Let's try using as much space as possible.
|
|
* Use MTU if total length of the message fits into the MTU.
|
|
* Otherwise, we need to reserve fragment header and
|
|
* fragment alignment (= 8-15 octects, in total).
|
|
*
|
|
* Note that we may need to "move" the data from the tail of
|
|
* of the buffer to the new fragment when we split
|
|
* the message.
|
|
*
|
|
* FIXME: It may be fragmented into multiple chunks
|
|
* at once if non-fragmentable extension headers
|
|
* are too large.
|
|
* --yoshfuji
|
|
*/
|
|
|
|
cork->length += length;
|
|
if (!skb)
|
|
goto alloc_new_skb;
|
|
|
|
while (length > 0) {
|
|
/* Check if the remaining data fits into current packet. */
|
|
copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
|
|
if (copy < length)
|
|
copy = maxfraglen - skb->len;
|
|
|
|
if (copy <= 0) {
|
|
char *data;
|
|
unsigned int datalen;
|
|
unsigned int fraglen;
|
|
unsigned int fraggap;
|
|
unsigned int alloclen;
|
|
unsigned int pagedlen = 0;
|
|
alloc_new_skb:
|
|
/* There's no room in the current skb */
|
|
if (skb)
|
|
fraggap = skb->len - maxfraglen;
|
|
else
|
|
fraggap = 0;
|
|
/* update mtu and maxfraglen if necessary */
|
|
if (!skb || !skb_prev)
|
|
ip6_append_data_mtu(&mtu, &maxfraglen,
|
|
fragheaderlen, skb, rt,
|
|
orig_mtu);
|
|
|
|
skb_prev = skb;
|
|
|
|
/*
|
|
* If remaining data exceeds the mtu,
|
|
* we know we need more fragment(s).
|
|
*/
|
|
datalen = length + fraggap;
|
|
|
|
if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
|
|
datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len;
|
|
fraglen = datalen + fragheaderlen;
|
|
|
|
if ((flags & MSG_MORE) &&
|
|
!(rt->dst.dev->features&NETIF_F_SG))
|
|
alloclen = mtu;
|
|
else if (!paged)
|
|
alloclen = fraglen;
|
|
else {
|
|
alloclen = min_t(int, fraglen, MAX_HEADER);
|
|
pagedlen = fraglen - alloclen;
|
|
}
|
|
|
|
alloclen += dst_exthdrlen;
|
|
|
|
if (datalen != length + fraggap) {
|
|
/*
|
|
* this is not the last fragment, the trailer
|
|
* space is regarded as data space.
|
|
*/
|
|
datalen += rt->dst.trailer_len;
|
|
}
|
|
|
|
alloclen += rt->dst.trailer_len;
|
|
fraglen = datalen + fragheaderlen;
|
|
|
|
/*
|
|
* We just reserve space for fragment header.
|
|
* Note: this may be overallocation if the message
|
|
* (without MSG_MORE) fits into the MTU.
|
|
*/
|
|
alloclen += sizeof(struct frag_hdr);
|
|
|
|
copy = datalen - transhdrlen - fraggap - pagedlen;
|
|
if (copy < 0) {
|
|
err = -EINVAL;
|
|
goto error;
|
|
}
|
|
if (transhdrlen) {
|
|
skb = sock_alloc_send_skb(sk,
|
|
alloclen + hh_len,
|
|
(flags & MSG_DONTWAIT), &err);
|
|
} else {
|
|
skb = NULL;
|
|
if (refcount_read(&sk->sk_wmem_alloc) <=
|
|
2 * sk->sk_sndbuf)
|
|
skb = sock_wmalloc(sk,
|
|
alloclen + hh_len, 1,
|
|
sk->sk_allocation);
|
|
if (unlikely(!skb))
|
|
err = -ENOBUFS;
|
|
}
|
|
if (!skb)
|
|
goto error;
|
|
/*
|
|
* Fill in the control structures
|
|
*/
|
|
skb->protocol = htons(ETH_P_IPV6);
|
|
skb->ip_summed = csummode;
|
|
skb->csum = 0;
|
|
/* reserve for fragmentation and ipsec header */
|
|
skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
|
|
dst_exthdrlen);
|
|
|
|
/* Only the initial fragment is time stamped */
|
|
skb_shinfo(skb)->tx_flags = tx_flags;
|
|
tx_flags = 0;
|
|
skb_shinfo(skb)->tskey = tskey;
|
|
tskey = 0;
|
|
|
|
/*
|
|
* Find where to start putting bytes
|
|
*/
|
|
data = skb_put(skb, fraglen - pagedlen);
|
|
skb_set_network_header(skb, exthdrlen);
|
|
data += fragheaderlen;
|
|
skb->transport_header = (skb->network_header +
|
|
fragheaderlen);
|
|
if (fraggap) {
|
|
skb->csum = skb_copy_and_csum_bits(
|
|
skb_prev, maxfraglen,
|
|
data + transhdrlen, fraggap, 0);
|
|
skb_prev->csum = csum_sub(skb_prev->csum,
|
|
skb->csum);
|
|
data += fraggap;
|
|
pskb_trim_unique(skb_prev, maxfraglen);
|
|
}
|
|
if (copy > 0 &&
|
|
getfrag(from, data + transhdrlen, offset,
|
|
copy, fraggap, skb) < 0) {
|
|
err = -EFAULT;
|
|
kfree_skb(skb);
|
|
goto error;
|
|
}
|
|
|
|
offset += copy;
|
|
length -= copy + transhdrlen;
|
|
transhdrlen = 0;
|
|
exthdrlen = 0;
|
|
dst_exthdrlen = 0;
|
|
|
|
if ((flags & MSG_CONFIRM) && !skb_prev)
|
|
skb_set_dst_pending_confirm(skb, 1);
|
|
|
|
/*
|
|
* Put the packet on the pending queue
|
|
*/
|
|
__skb_queue_tail(queue, skb);
|
|
continue;
|
|
}
|
|
|
|
if (copy > length)
|
|
copy = length;
|
|
|
|
if (!(rt->dst.dev->features&NETIF_F_SG) &&
|
|
skb_tailroom(skb) >= copy) {
|
|
unsigned int off;
|
|
|
|
off = skb->len;
|
|
if (getfrag(from, skb_put(skb, copy),
|
|
offset, copy, off, skb) < 0) {
|
|
__skb_trim(skb, off);
|
|
err = -EFAULT;
|
|
goto error;
|
|
}
|
|
} else {
|
|
int i = skb_shinfo(skb)->nr_frags;
|
|
|
|
err = -ENOMEM;
|
|
if (!sk_page_frag_refill(sk, pfrag))
|
|
goto error;
|
|
|
|
if (!skb_can_coalesce(skb, i, pfrag->page,
|
|
pfrag->offset)) {
|
|
err = -EMSGSIZE;
|
|
if (i == MAX_SKB_FRAGS)
|
|
goto error;
|
|
|
|
__skb_fill_page_desc(skb, i, pfrag->page,
|
|
pfrag->offset, 0);
|
|
skb_shinfo(skb)->nr_frags = ++i;
|
|
get_page(pfrag->page);
|
|
}
|
|
copy = min_t(int, copy, pfrag->size - pfrag->offset);
|
|
if (getfrag(from,
|
|
page_address(pfrag->page) + pfrag->offset,
|
|
offset, copy, skb->len, skb) < 0)
|
|
goto error_efault;
|
|
|
|
pfrag->offset += copy;
|
|
skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
|
|
skb->len += copy;
|
|
skb->data_len += copy;
|
|
skb->truesize += copy;
|
|
refcount_add(copy, &sk->sk_wmem_alloc);
|
|
}
|
|
offset += copy;
|
|
length -= copy;
|
|
}
|
|
|
|
return 0;
|
|
|
|
error_efault:
|
|
err = -EFAULT;
|
|
error:
|
|
cork->length -= length;
|
|
IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
|
|
return err;
|
|
}
|
|
|
|
int ip6_append_data(struct sock *sk,
|
|
int getfrag(void *from, char *to, int offset, int len,
|
|
int odd, struct sk_buff *skb),
|
|
void *from, int length, int transhdrlen,
|
|
struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
|
|
struct rt6_info *rt, unsigned int flags,
|
|
const struct sockcm_cookie *sockc)
|
|
{
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
int exthdrlen;
|
|
int err;
|
|
|
|
if (flags&MSG_PROBE)
|
|
return 0;
|
|
if (skb_queue_empty(&sk->sk_write_queue)) {
|
|
/*
|
|
* setup for corking
|
|
*/
|
|
err = ip6_setup_cork(sk, &inet->cork, &np->cork,
|
|
ipc6, rt, fl6);
|
|
if (err)
|
|
return err;
|
|
|
|
exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
|
|
length += exthdrlen;
|
|
transhdrlen += exthdrlen;
|
|
} else {
|
|
fl6 = &inet->cork.fl.u.ip6;
|
|
transhdrlen = 0;
|
|
}
|
|
|
|
return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base,
|
|
&np->cork, sk_page_frag(sk), getfrag,
|
|
from, length, transhdrlen, flags, ipc6, sockc);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_append_data);
|
|
|
|
static void ip6_cork_release(struct inet_cork_full *cork,
|
|
struct inet6_cork *v6_cork)
|
|
{
|
|
if (v6_cork->opt) {
|
|
kfree(v6_cork->opt->dst0opt);
|
|
kfree(v6_cork->opt->dst1opt);
|
|
kfree(v6_cork->opt->hopopt);
|
|
kfree(v6_cork->opt->srcrt);
|
|
kfree(v6_cork->opt);
|
|
v6_cork->opt = NULL;
|
|
}
|
|
|
|
if (cork->base.dst) {
|
|
dst_release(cork->base.dst);
|
|
cork->base.dst = NULL;
|
|
cork->base.flags &= ~IPCORK_ALLFRAG;
|
|
}
|
|
memset(&cork->fl, 0, sizeof(cork->fl));
|
|
}
|
|
|
|
struct sk_buff *__ip6_make_skb(struct sock *sk,
|
|
struct sk_buff_head *queue,
|
|
struct inet_cork_full *cork,
|
|
struct inet6_cork *v6_cork)
|
|
{
|
|
struct sk_buff *skb, *tmp_skb;
|
|
struct sk_buff **tail_skb;
|
|
struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct net *net = sock_net(sk);
|
|
struct ipv6hdr *hdr;
|
|
struct ipv6_txoptions *opt = v6_cork->opt;
|
|
struct rt6_info *rt = (struct rt6_info *)cork->base.dst;
|
|
struct flowi6 *fl6 = &cork->fl.u.ip6;
|
|
unsigned char proto = fl6->flowi6_proto;
|
|
|
|
skb = __skb_dequeue(queue);
|
|
if (!skb)
|
|
goto out;
|
|
tail_skb = &(skb_shinfo(skb)->frag_list);
|
|
|
|
/* move skb->data to ip header from ext header */
|
|
if (skb->data < skb_network_header(skb))
|
|
__skb_pull(skb, skb_network_offset(skb));
|
|
while ((tmp_skb = __skb_dequeue(queue)) != NULL) {
|
|
__skb_pull(tmp_skb, skb_network_header_len(skb));
|
|
*tail_skb = tmp_skb;
|
|
tail_skb = &(tmp_skb->next);
|
|
skb->len += tmp_skb->len;
|
|
skb->data_len += tmp_skb->len;
|
|
skb->truesize += tmp_skb->truesize;
|
|
tmp_skb->destructor = NULL;
|
|
tmp_skb->sk = NULL;
|
|
}
|
|
|
|
/* Allow local fragmentation. */
|
|
skb->ignore_df = ip6_sk_ignore_df(sk);
|
|
|
|
*final_dst = fl6->daddr;
|
|
__skb_pull(skb, skb_network_header_len(skb));
|
|
if (opt && opt->opt_flen)
|
|
ipv6_push_frag_opts(skb, opt, &proto);
|
|
if (opt && opt->opt_nflen)
|
|
ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
|
|
|
|
skb_push(skb, sizeof(struct ipv6hdr));
|
|
skb_reset_network_header(skb);
|
|
hdr = ipv6_hdr(skb);
|
|
|
|
ip6_flow_hdr(hdr, v6_cork->tclass,
|
|
ip6_make_flowlabel(net, skb, fl6->flowlabel,
|
|
ip6_autoflowlabel(net, np), fl6));
|
|
hdr->hop_limit = v6_cork->hop_limit;
|
|
hdr->nexthdr = proto;
|
|
hdr->saddr = fl6->saddr;
|
|
hdr->daddr = *final_dst;
|
|
|
|
skb->priority = sk->sk_priority;
|
|
skb->mark = sk->sk_mark;
|
|
|
|
skb_dst_set(skb, dst_clone(&rt->dst));
|
|
IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
|
|
if (proto == IPPROTO_ICMPV6) {
|
|
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
|
|
|
ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
|
|
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
|
}
|
|
|
|
ip6_cork_release(cork, v6_cork);
|
|
out:
|
|
return skb;
|
|
}
|
|
|
|
int ip6_send_skb(struct sk_buff *skb)
|
|
{
|
|
struct net *net = sock_net(skb->sk);
|
|
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
|
|
int err;
|
|
|
|
err = ip6_local_out(net, skb->sk, skb);
|
|
if (err) {
|
|
if (err > 0)
|
|
err = net_xmit_errno(err);
|
|
if (err)
|
|
IP6_INC_STATS(net, rt->rt6i_idev,
|
|
IPSTATS_MIB_OUTDISCARDS);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int ip6_push_pending_frames(struct sock *sk)
|
|
{
|
|
struct sk_buff *skb;
|
|
|
|
skb = ip6_finish_skb(sk);
|
|
if (!skb)
|
|
return 0;
|
|
|
|
return ip6_send_skb(skb);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_push_pending_frames);
|
|
|
|
static void __ip6_flush_pending_frames(struct sock *sk,
|
|
struct sk_buff_head *queue,
|
|
struct inet_cork_full *cork,
|
|
struct inet6_cork *v6_cork)
|
|
{
|
|
struct sk_buff *skb;
|
|
|
|
while ((skb = __skb_dequeue_tail(queue)) != NULL) {
|
|
if (skb_dst(skb))
|
|
IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)),
|
|
IPSTATS_MIB_OUTDISCARDS);
|
|
kfree_skb(skb);
|
|
}
|
|
|
|
ip6_cork_release(cork, v6_cork);
|
|
}
|
|
|
|
void ip6_flush_pending_frames(struct sock *sk)
|
|
{
|
|
__ip6_flush_pending_frames(sk, &sk->sk_write_queue,
|
|
&inet_sk(sk)->cork, &inet6_sk(sk)->cork);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
|
|
|
|
struct sk_buff *ip6_make_skb(struct sock *sk,
|
|
int getfrag(void *from, char *to, int offset,
|
|
int len, int odd, struct sk_buff *skb),
|
|
void *from, int length, int transhdrlen,
|
|
struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
|
|
struct rt6_info *rt, unsigned int flags,
|
|
struct inet_cork_full *cork,
|
|
const struct sockcm_cookie *sockc)
|
|
{
|
|
struct inet6_cork v6_cork;
|
|
struct sk_buff_head queue;
|
|
int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
|
|
int err;
|
|
|
|
if (flags & MSG_PROBE)
|
|
return NULL;
|
|
|
|
__skb_queue_head_init(&queue);
|
|
|
|
cork->base.flags = 0;
|
|
cork->base.addr = 0;
|
|
cork->base.opt = NULL;
|
|
cork->base.dst = NULL;
|
|
v6_cork.opt = NULL;
|
|
err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6);
|
|
if (err) {
|
|
ip6_cork_release(cork, &v6_cork);
|
|
return ERR_PTR(err);
|
|
}
|
|
if (ipc6->dontfrag < 0)
|
|
ipc6->dontfrag = inet6_sk(sk)->dontfrag;
|
|
|
|
err = __ip6_append_data(sk, fl6, &queue, &cork->base, &v6_cork,
|
|
¤t->task_frag, getfrag, from,
|
|
length + exthdrlen, transhdrlen + exthdrlen,
|
|
flags, ipc6, sockc);
|
|
if (err) {
|
|
__ip6_flush_pending_frames(sk, &queue, cork, &v6_cork);
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
return __ip6_make_skb(sk, &queue, cork, &v6_cork);
|
|
}
|