mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge android11-5.4.259+ (81334f2) into msm-5.4
* remotes/origin/tmp-81334f2: UPSTREAM: netfilter: nf_tables: remove busy mark and gc batch API UPSTREAM: netfilter: nft_set_hash: mark set element as dead when deleting from packet path UPSTREAM: netfilter: nf_tables: adapt set backend to use GC transaction API UPSTREAM: netfilter: nf_tables: GC transaction API to avoid race with control plane UPSTREAM: netfilter: nft_set_rbtree: fix overlap expiration walk UPSTREAM: netfilter: nft_set_rbtree: fix null deref on element insertion UPSTREAM: netfilter: nft_set_rbtree: Switch to node list walk for overlap detection UPSTREAM: netfilter: nf_tables: drop map element references from preparation phase UPSTREAM: netfilter: nftables: rename set element data activation/deactivation functions ANDROID: ABI: Update allowed list for QCOM BACKPORT: ALSA: compress: Allow pause and resume during draining UPSTREAM: netfilter: nf_tables: pass context to nft_set_destroy() UPSTREAM: netfilter: nf_tables: don't skip expired elements during walk ANDROID: GKI: db845c: Update symbols list and ABI on rpmsg_register_device_override ANDROID: Use GKI Dr. No OWNERS file ANDROID: Remove android/OWNERs file FROMGIT: Input: uinput - allow injecting event times ANDROID: fix up rpmsg_device ABI break ANDROID: fix up platform_device ABI break UPSTREAM: rpmsg: Fix possible refcount leak in rpmsg_register_device_override() UPSTREAM: rpmsg: glink: Release driver_override BACKPORT: rpmsg: Fix calling device_lock() on non-initialized device BACKPORT: rpmsg: Fix kfree() of static memory on setting driver_override UPSTREAM: rpmsg: Constify local variable in field store macro UPSTREAM: driver: platform: Add helper for safer setting of driver_override Revert "perf: Disallow mis-matched inherited group reads" Revert "xfrm: fix a data-race in xfrm_gen_index()" Revert "Bluetooth: hci_core: Fix build warnings" Revert "xfrm: interface: use DEV_STATS_INC()" Revert "netfilter: conntrack: allow sctp hearbeat after connection re-use" Revert "netfilter: conntrack: don't refresh sctp entries in closed state" Revert "netfilter: handle the connecting collision properly in nf_conntrack_proto_sctp" Reapply "netfilter: conntrack: don't refresh sctp entries in closed state" Reapply "netfilter: conntrack: allow sctp hearbeat after connection re-use" Linux 5.4.259 xfrm6: fix inet6_dev refcount underflow problem Bluetooth: hci_sock: Correctly bounds check and pad HCI_MON_NEW_INDEX name Bluetooth: hci_sock: fix slab oob read in create_monitor_event phy: mapphone-mdm6600: Fix pinctrl_pm handling for sleep pins phy: mapphone-mdm6600: Fix runtime PM for remove phy: mapphone-mdm6600: Fix runtime disable on probe ASoC: pxa: fix a memory leak in probe() gpio: vf610: set value before the direction to avoid a glitch s390/pci: fix iommu bitmap allocation perf: Disallow mis-matched inherited group reads USB: serial: option: add Fibocom to DELL custom modem FM101R-GL USB: serial: option: add entry for Sierra EM9191 with new firmware USB: serial: option: add Telit LE910C4-WWX 0x1035 composition ACPI: irq: Fix incorrect return value in acpi_register_gsi() Revert "pinctrl: avoid unsafe code pattern in find_pinctrl()" mmc: core: Capture correct oemid-bits for eMMC cards mmc: core: sdio: hold retuning if sdio in 1-bit mode mtd: physmap-core: Restore map_rom fallback mtd: spinand: micron: correct bitmask for ecc status mtd: rawnand: qcom: Unmap the right resource upon probe failure Bluetooth: hci_event: Fix using memcmp when comparing keys HID: multitouch: Add required quirk for Synaptics 0xcd7e device btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c drm: panel-orientation-quirks: Add quirk for One Mix 2S sky2: Make sure there is at least one frag_addr available regulator/core: Revert "fix kobject release warning and memory leak in regulator_register()" wifi: cfg80211: avoid leaking stack data into trace wifi: mac80211: allow transmitting EAPOL frames with tainted key Bluetooth: hci_core: Fix build warnings Bluetooth: Avoid redundant authentication HID: holtek: fix slab-out-of-bounds Write in holtek_kbd_input_event tracing: relax trace_event_eval_update() execution with cond_resched() ata: libata-eh: Fix compilation warning in ata_eh_link_report() gpio: timberdale: Fix potential deadlock on &tgpio->lock overlayfs: set ctime when setting mtime and atime i2c: mux: Avoid potential false error message in i2c_mux_add_adapter btrfs: initialize start_slot in btrfs_log_prealloc_extents btrfs: return -EUCLEAN for delayed tree ref with a ref count not equals to 1 ARM: dts: ti: omap: Fix noisy serial with overrun-throttle-ms for mapphone ACPI: resource: Skip IRQ override on ASUS ExpertBook B1402CBA ACPI: resource: Skip IRQ override on ASUS ExpertBook B1502CBA ACPI: resource: Skip IRQ override on Asus Expertbook B2402CBA ACPI: resource: Add Asus ExpertBook B2502 to Asus quirks ACPI: resource: Skip IRQ override on Asus Vivobook S5602ZA ACPI: resource: Add ASUS model S5402ZA to quirks ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA ACPI: resources: Add DMI-based legacy IRQ override quirk ACPI: Drop acpi_dev_irqresource_disabled() resource: Add irqresource_disabled() net: pktgen: Fix interface flags printing netfilter: nft_set_rbtree: .deactivate fails if element has expired neighbor: tracing: Move pin6 inside CONFIG_IPV6=y section net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve i40e: prevent crash on probe if hw registers have invalid values net: usb: smsc95xx: Fix an error code in smsc95xx_reset() ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr tun: prevent negative ifindex tcp: tsq: relax tcp_small_queue_check() when rtx queue contains a single skb tcp: fix excessive TLP and RACK timeouts from HZ rounding net: rfkill: gpio: prevent value glitch during probe net: ipv6: fix return value check in esp_remove_trailer net: ipv4: fix return value check in esp_remove_trailer xfrm: interface: use DEV_STATS_INC() xfrm: fix a data-race in xfrm_gen_index() qed: fix LL2 RX buffer allocation netfilter: nft_payload: fix wrong mac header matching KVM: x86: Mask LVTPC when handling a PMI regmap: fix NULL deref on lookup nfc: nci: fix possible NULL pointer dereference in send_acknowledge() ice: fix over-shifted variable Bluetooth: avoid memcmp() out of bounds warning Bluetooth: hci_event: Fix coding style Bluetooth: vhci: Fix race when opening vhci device Bluetooth: Fix a refcnt underflow problem for hci_conn Bluetooth: Reject connection with the device which has same BD_ADDR Bluetooth: hci_event: Ignore NULL link key usb: hub: Guard against accesses to uninitialized BOS descriptors Documentation: sysctl: align cells in second content column dev_forward_skb: do not scrub skb mark within the same name space ravb: Fix use-after-free issue in ravb_tx_timeout_work() powerpc/64e: Fix wrong test in __ptep_test_and_clear_young() powerpc/8xx: Fix pte_access_permitted() for PAGE_NONE dmaengine: mediatek: Fix deadlock caused by synchronize_irq() x86/cpu: Fix AMD erratum #1485 on Zen4-based CPUs usb: gadget: ncm: Handle decoding of multiple NTB's in unwrap call usb: gadget: udc-xilinx: replace memcpy with memcpy_toio pinctrl: avoid unsafe code pattern in find_pinctrl() cgroup: Remove duplicates in cgroup v1 tasks file Input: xpad - add PXN V900 support Input: psmouse - fix fast_reconnect function for PS/2 mode Input: powermate - fix use-after-free in powermate_config_complete ceph: fix incorrect revoked caps assert in ceph_fill_file_size() libceph: use kernel_connect() mcb: remove is_added flag from mcb_device struct iio: pressure: ms5611: ms5611_prom_is_valid false negative bug iio: pressure: dps310: Adjust Timeout Settings iio: pressure: bmp280: Fix NULL pointer exception usb: musb: Modify the "HWVers" register address usb: musb: Get the musb_qh poniter after musb_giveback usb: dwc3: Soft reset phy on probe for host net: usb: dm9601: fix uninitialized variable use in dm9601_mdio_read usb: xhci: xhci-ring: Use sysdev for mapping bounce buffer dmaengine: stm32-mdma: abort resume if no ongoing transfer workqueue: Override implicit ordered attribute in workqueue_apply_unbound_cpumask() nfc: nci: assert requested protocol is valid net: nfc: fix races in nfc_llcp_sock_get() and nfc_llcp_sock_get_sn() ixgbe: fix crash with empty VF macvlan list drm/vmwgfx: fix typo of sizeof argument xen-netback: use default TX queue size for vifs mlxsw: fix mlxsw_sp2_nve_vxlan_learning_set() return type ieee802154: ca8210: Fix a potential UAF in ca8210_probe ravb: Fix up dma_free_coherent() call in ravb_remove() drm/msm/dsi: skip the wait for video mode done if not applicable drm: etvnaviv: fix bad backport leading to warning net: prevent address rewrite in kernel_bind() quota: Fix slow quotaoff HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect pwm: hibvt: Explicitly set .polarity in .get_state() lib/test_meminit: fix off-by-one error in test_pages() RDMA/cxgb4: Check skb value for failure to allocate Reapply "ANDROID: Revert "tracing/ring-buffer: Have polling block on watermark"" Revert "ring-buffer: Update "shortest_full" in polling" Revert "ANDROID: Revert "tracing/ring-buffer: Have polling block on watermark"" Revert "net: bridge: use DEV_STATS_INC()" FROMLIST: lib/test_meminit: fix off-by-one error in test_pages() Linux 5.4.258 xen/events: replace evtchn_rwlock with RCU ima: rework CONFIG_IMA dependency block NFS: Fix a race in __nfs_list_for_each_server() parisc: Restore __ldcw_align for PA-RISC 2.0 processors RDMA/mlx5: Fix NULL string error RDMA/siw: Fix connection failure handling RDMA/uverbs: Fix typo of sizeof argument RDMA/cma: Fix truncation compilation warning in make_cma_ports gpio: pxa: disable pinctrl calls for MMP_GPIO gpio: aspeed: fix the GPIO number passed to pinctrl_gpio_set_config() IB/mlx4: Fix the size of a buffer in add_port_entries() RDMA/core: Require admin capabilities to set system parameters cpupower: add Makefile dependencies for install targets sctp: update hb timer immediately after users change hb_interval sctp: update transport state when processing a dupcook packet tcp: fix delayed ACKs for MSS boundary condition tcp: fix quick-ack counting to count actual ACKs of new data net: stmmac: dwmac-stm32: fix resume on STM32 MCU netfilter: handle the connecting collision properly in nf_conntrack_proto_sctp net: nfc: llcp: Add lock when modifying device list net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data() net: fix possible store tearing in neigh_periodic_work() modpost: add missing else to the "of" check NFSv4: Fix a nfs4_state_manager() race NFS: Add a helper nfs_client_for_each_server() NFS4: Trace state recovery operation wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling wifi: mwifiex: Fix tlv_buf_left calculation scsi: target: core: Fix deadlock due to recursive locking drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close() qed/red_ll2: Fix undefined behavior bug in struct qed_ll2_info ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet regmap: rbtree: Fix wrong register marked as in-cache when creating new node wifi: iwlwifi: dbg_ini: fix structure packing ubi: Refuse attaching if mtd's erasesize is 0 net: prevent rewrite of msg_name in sock_sendmsg() net: replace calls to sock->ops->connect() with kernel_connect() fs: binfmt_elf_efpic: fix personality for ELF-FDPIC scsi: zfcp: Fix a double put in zfcp_port_enqueue() ata: libata-sata: increase PMP SRST timeout to 10s Revert "PCI: qcom: Disable write access to read only registers for IP v2.3.3" ata: libata-core: Do not register PM operations for SAS ports rbd: take header_rwsem in rbd_dev_refresh() only when updating ata: libata-core: Fix port and device removal rbd: decouple parent info read-in from updating rbd_dev ata: libata-core: Fix ata_port_request_pm() locking rbd: decouple header read-in from updating rbd_dev->header rbd: move rbd_dev_refresh() definition ring-buffer: Update "shortest_full" in polling i2c: i801: unregister tco_pdev in i801_probe() error path net: thunderbolt: Fix TCPv6 GSO checksum calculation ata: libata-scsi: ignore reserved bits for REPORT SUPPORTED OPERATION CODES btrfs: properly report 0 avail for very full file systems ALSA: hda: Disable power save for solving pop issue on Lenovo ThinkCentre M70q nilfs2: fix potential use after free in nilfs_gccache_submit_read_data() serial: 8250_port: Check IRQ data before use Smack:- Use overlay inode label in smack_inode_copy_up() smack: Retrieve transmuting information in smack_inode_getsecurity() smack: Record transmuting in smk_transmuted i40e: fix return of uninitialized aq_ret in i40e_set_vsi_promisc i40e: always propagate error value in i40e_set_vsi_promisc() ring-buffer: Avoid softlockup in ring_buffer_resize() selftests/ftrace: Correctly enable event in instance-event.tc i40e: improve locking of mac_filter_hash watchdog: iTCO_wdt: Set NO_REBOOT if the watchdog is not already running watchdog: iTCO_wdt: No need to stop the timer in probe nvme-pci: do not set the NUMA node of device if it has none fbdev/sh7760fb: Depend on FB=y ncsi: Propagate carrier gain/loss events to the NCSI controller powerpc/watchpoints: Annotate atomic context in more places bpf: Clarify error expectations from bpf_clone_redirect spi: nxp-fspi: reset the FLSHxCR1 registers ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() parisc: irq: Make irq_stack_union static to avoid sparse warning parisc: drivers: Fix sparse warning parisc: iosapic.c: Fix sparse warnings parisc: sba: Fix compile warning wrt list of SBA devices gpio: pmic-eic-sprd: Add can_sleep flag for PMIC EIC chip xtensa: boot/lib: fix function prototypes xtensa: boot: don't add include-dirs xtensa: iss/network: make functions static xtensa: add default definition for XCHAL_HAVE_DIV32 bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up ARM: dts: ti: omap: motorola-mapphone: Fix abe_clkctrl warning on boot clk: tegra: fix error return case for recalc_rate scsi: qla2xxx: Fix deletion race condition MIPS: Alchemy: only build mmc support helpers if au1xmmc is enabled scsi: qla2xxx: Fix update_fcport for current_topology ata: libata: disallow dev-initiated LPM transitions to unsupported states Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN drm/amd/display: prevent potential division by zero errors i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() drm/amd/display: Fix LFC multiplier changing erratically gpio: tb10x: Fix an error handling path in tb10x_gpio_probe() drm/amd/display: Reinstate LFC optimization netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP net: rds: Fix possible NULL-pointer dereference team: fix null-ptr-deref when team device type is changed net: bridge: use DEV_STATS_INC() net: hns3: add 5ms delay before clear firmware reset irq source dccp: fix dccp_v4_err()/dccp_v6_err() again powerpc/perf/hv-24x7: Update domain value check ipv4: fix null-deref in ipv4_link_failure i40e: Fix VF VLAN offloading when port VLAN is configured i40e: Fix warning message and call stack during rmmod i40e driver i40e: Remove scheduling while atomic possibility i40e: Fix for persistent lldp support ASoC: imx-audmix: Fix return error with devm_clk_get() selftests: tls: swap the TX and RX sockets in some tests ASoC: meson: spdifin: start hw on dai probe selftests/tls: Add {} to avoid static checker warning ext4: do not let fstrim block system suspend bpf: Avoid deadlock when using queue and stack maps from NMI ext4: move setting of trimmed bit into ext4_try_to_trim_range() netfilter: nf_tables: disallow element removal on anonymous sets ext4: replace the traditional ternary conditional operator with with max()/min() ext4: mark group as trimmed only if it was fully scanned ext4: change s_last_trim_minblks type to unsigned long ext4: scope ret locally in ext4_try_to_trim_range() ext4: add new helper interface ext4_try_to_trim_range() ext4: remove the 'group' parameter of ext4_trim_extent ata: libahci: clear pending interrupt status tracing: Increase trace array ref count on enable and filter files SUNRPC: Mark the cred for revalidation if the server rejects it NFS/pNFS: Report EINVAL errors from connect() to the server Revert "drm/panel: simple: Add missing connector type and pixel format for AUO T215HVN01" Revert "usb: typec: bus: verify partner exists in typec_altmode_attention" Revert "fs/nls: make load_nls() take a const parameter" Revert "ip_tunnels: use DEV_STATS_INC()" Linux 5.4.257 net/sched: Retire rsvp classifier drm/amdgpu: fix amdgpu_cs_p1_user_fence mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller ext4: fix rec_len verify error scsi: megaraid_sas: Fix deadlock on firmware crashdump i2c: aspeed: Reset the i2c controller when timeout occurs tracefs: Add missing lockdown check to tracefs_create_dir() nfsd: fix change_info in NFSv4 RENAME replies tracing: Have option files inc the trace array ref count tracing: Have current_trace inc the trace array ref count btrfs: fix lockdep splat and potential deadlock after failure running delayed items attr: block mode changes of symlinks md/raid1: fix error: ISO C90 forbids mixed declarations selftests: tracing: Fix to unmount tracefs for recovering environment btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super btrfs: add a helper to read the superblock metadata_uuid btrfs: move btrfs_pinned_by_swapfile prototype into volumes.h perf tools: Add an option to build without libbfd perf jevents: Make build dependency on test JSONs tools features: Add feature test to check if libbfd has buildid support kobject: Add sanity check for kset->kobj.ktype in kset_register() media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler warning serial: cpm_uart: Avoid suspicious locking scsi: target: iscsi: Fix buffer overflow in lio_target_nacl_info_show() usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc media: pci: cx23885: replace BUG with error return media: tuners: qt1010: replace BUG_ON with a regular error media: az6007: Fix null-ptr-deref in az6007_i2c_xfer() media: anysee: fix null-ptr-deref in anysee_master_xfer media: af9005: Fix null-ptr-deref in af9005_i2c_xfer media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer() media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer powerpc/pseries: fix possible memory leak in ibmebus_bus_init() jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount() ext2: fix datatype of block number in ext2_xattr_set2() md: raid1: fix potential OOB in raid1_remove_disk() bus: ti-sysc: Configure uart quirks for k3 SoC drm/exynos: fix a possible null-pointer dereference due to data race in exynos_drm_crtc_atomic_disable() wifi: mac80211_hwsim: drop short frames alx: fix OOB-read compiler warning mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450 tpm_tis: Resend command to recover from data transfer errors crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui() wifi: mwifiex: fix fortify warning wifi: ath9k: fix printk specifier devlink: remove reload failed checks in params get/set callbacks hw_breakpoint: fix single-stepping when using bpf_overflow_handler perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09 ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470 kernel/fork: beware of __put_task_struct() calling context ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer locks: fix KASAN: use-after-free in trace_event_raw_event_filelock_lock btrfs: output extra debug info if we failed to find an inline backref autofs: fix memory leak of waitqueues in autofs_catatonic_mode parisc: Drop loops_per_jiffy from per_cpu struct drm/amd/display: Fix a bug when searching for insert_above_mpcc kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). ixgbe: fix timestamp configuration code net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() platform/mellanox: mlxbf-tmfifo: Drop jumbo frames mlxbf-tmfifo: sparse tags for config access platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors kcm: Fix memory leak in error path of kcm_sendmsg() r8152: check budget for r8152_poll() net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in mtk_hwlro_get_fdir_all() net: ethernet: mvpp2_main: fix possible OOB write in mvpp2_ethtool_get_rxnfc() net: ipv4: fix one memleak in __inet_del_ifa() clk: imx8mm: Move 1443X/1416X PLL clock structure to common place ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2 usb: typec: bus: verify partner exists in typec_altmode_attention usb: typec: tcpm: Refactor tcpm_handle_vdm_request usb: typec: tcpm: Refactor tcpm_handle_vdm_request payload handling perf tools: Handle old data in PERF_RECORD_ATTR perf hists browser: Fix hierarchy mode header mtd: rawnand: brcmnand: Fix potential false time out warning mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write mtd: rawnand: brcmnand: Fix crash during the panic_write btrfs: use the correct superblock to compare fsid in btrfs_validate_super btrfs: don't start transaction when joining with TRANS_JOIN_NOSTART fuse: nlookup missing decrement in fuse_direntplus_link ata: pata_ftide010: Add missing MODULE_DESCRIPTION ata: sata_gemini: Add missing MODULE_DESCRIPTION sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory() net: hns3: fix the port information display when sfp is absent netfilter: nfnetlink_osf: avoid OOB read ip_tunnels: use DEV_STATS_INC() idr: fix param name in idr_alloc_cyclic() doc s390/zcrypt: don't leak memory if dev_set_name() fails igb: Change IGB_MIN to allow set rx/tx value between 64 and 80 igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80 igc: Change IGC_MIN to allow set rx/tx value between 64 and 80 kcm: Destroy mutex in kcm_exit_net() net: sched: sch_qfq: Fix UAF in qfq_dequeue() af_unix: Fix data race around sk->sk_err. af_unix: Fix data-races around sk->sk_shutdown. af_unix: Fix data-race around unix_tot_inflight. af_unix: Fix data-races around user->unix_inflight. net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr veth: Fixing transmit return status for dropped packets igb: disable virtualization features on 82580 net: read sk->sk_family once in sk_mc_loop() ipv4: annotate data-races around fi->fib_dead sctp: annotate data-races around sk->sk_wmem_queued pwm: lpc32xx: Remove handling of PWM channels watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load perf top: Don't pass an ERR_PTR() directly to perf_session__delete() x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() perf annotate bpf: Don't enclose non-debug code with an assert() kconfig: fix possible buffer overflow NFSv4/pnfs: minor fix for cleanup path in nfs4_get_device_info soc: qcom: qmi_encdec: Restrict string length in decode clk: qcom: gcc-mdm9615: use proper parent for pll0_vote clock parisc: led: Reduce CPU overhead for disk & lan LED computation parisc: led: Fix LAN receive and transmit LEDs lib/test_meminit: allocate pages up to order MAX_ORDER drm/ast: Fix DRAM init on AST2200 fbdev/ep93xx-fb: Do not assign to struct fb_info.dev scsi: qla2xxx: Remove unsupported ql2xenabledif option scsi: qla2xxx: Turn off noisy message log scsi: qla2xxx: Fix erroneous link up failure scsi: qla2xxx: fix inconsistent TMF timeout net/ipv6: SKB symmetric hash should incorporate transport ports drm: fix double free for gbo in drm_gem_vram_init and drm_gem_vram_create udf: initialize newblock to 0 usb: typec: tcpci: clear the fault status bit serial: sc16is7xx: fix broken port 0 uart init sc16is7xx: Set iobase to device index cpufreq: brcmstb-avs-cpufreq: Fix -Warray-bounds bug crypto: stm32 - fix loop iterating through scatterlist for DMA s390/ipl: add missing secure/has_secure file to ipl type 'unknown' pstore/ram: Check start of empty przs during init fsverity: skip PKCS#7 parser when keyring is empty net: handle ARPHRD_PPP in dev_is_mac_header_xmit() X.509: if signature is unsupported skip validation dccp: Fix out of bounds access in DCCP error handler dlm: fix plock lookup when using multiple lockspaces parisc: Fix /proc/cpuinfo output for lscpu procfs: block chmod on /proc/thread-self/comm Revert "PCI: Mark NVIDIA T4 GPUs to avoid bus reset" ntb: Fix calculation ntb_transport_tx_free_entry() ntb: Clean up tx tail index on link down ntb: Drop packets when qp link is down media: dvb: symbol fixup for dvb_attach() xtensa: PMU: fix base address for the newer hardware backlight/lv5207lp: Compare against struct fb_info.device backlight/bd6107: Compare against struct fb_info.device backlight/gpio_backlight: Compare against struct fb_info.device ARM: OMAP2+: Fix -Warray-bounds warning in _pwrdm_state_switch() ipmi_si: fix a memleak in try_smi_init() ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl PM / devfreq: Fix leak in devfreq_dev_release() igb: set max size RX buffer when store bad packet is enabled skbuff: skb_segment, Call zero copy functions before using skbuff frags netfilter: xt_sctp: validate the flag_info count netfilter: xt_u32: validate user space input netfilter: ipset: add the missing IP_SET_HASH_WITH_NET0 macro for ip_set_hash_netportnet.c igmp: limit igmpv3_newpack() packet size to IP_MAX_MTU virtio_ring: fix avail_wrap_counter in virtqueue_add_packed cpufreq: Fix the race condition while updating the transition_task of policy dmaengine: ste_dma40: Add missing IRQ check in d40_probe um: Fix hostaudio build errors mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume() rpmsg: glink: Add check for kstrdup phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 tracing: Fix race issue between cpu buffer write and swap x86/speculation: Mark all Skylake CPUs as vulnerable to GDS HID: multitouch: Correct devm device reference for hidinput input_dev name HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode() RDMA/siw: Correct wrong debug message RDMA/siw: Balance the reference of cep->kref in the error path Revert "IB/isert: Fix incorrect release of isert connection" amba: bus: fix refcount leak serial: tegra: handle clk prepare error in tegra_uart_hw_init() scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock scsi: core: Use 32-bit hostnum in scsi_host_lookup() media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors media: ov2680: Fix vflip / hflip set functions media: ov2680: Fix ov2680_bayer_order() media: ov2680: Remove auto-gain and auto-exposure controls media: i2c: ov2680: Set V4L2_CTRL_FLAG_MODIFY_LAYOUT on flips media: ov5640: Enable MIPI interface in ov5640_set_power_mipi() media: i2c: ov5640: Configure HVP lines in s_power callback USB: gadget: f_mass_storage: Fix unused variable warning media: go7007: Remove redundant if statement iommu/vt-d: Fix to flush cache of PASID directory table IB/uverbs: Fix an potential error pointer dereference driver core: test_async: fix an error code dma-buf/sync_file: Fix docs syntax coresight: tmc: Explicit type conversions to prevent integer overflow scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read() directly scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read() directly scsi: qedf: Do not touch __user pointer in qedf_dbg_stop_io_on_error_cmd_read() directly x86/APM: drop the duplicate APM_MINOR_DEV macro serial: sprd: Fix DMA buffer leak issue serial: sprd: Assign sprd_port after initialized to avoid wrong access serial: sprd: remove redundant sprd_port cleanup serial: sprd: getting port index via serial aliases only scsi: qla4xxx: Add length check when parsing nlattrs scsi: be2iscsi: Add length check when parsing nlattrs scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param() usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host() media: mediatek: vcodec: Return NULL if no vdec_fb is found media: cx24120: Add retval check for cx24120_message_send() media: dvb-usb: m920x: Fix a potential memory leak in m920x_i2c_xfer() media: dib7000p: Fix potential division by zero drivers: usb: smsusb: fix error handling code in smsusb_init_device media: v4l2-core: Fix a potential resource leak in v4l2_fwnode_parse_link() media: v4l2-fwnode: simplify v4l2_fwnode_parse_link media: v4l2-fwnode: fix v4l2_fwnode_parse_link handling NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN NFSD: da_addr_body field missing in some GETDEVICEINFO replies fs: lockd: avoid possible wrong NULL parameter jfs: validate max amount of blocks before allocation. powerpc/iommu: Fix notifiers being shared by PCI and VIO buses nfs/blocklayout: Use the passed in gfp flags wifi: ath10k: Use RMW accessors for changing LNKCTL drm/radeon: Use RMW accessors for changing LNKCTL drm/radeon: Prefer pcie_capability_read_word() drm/radeon: Replace numbers with PCI_EXP_LNKCTL2 definitions drm/radeon: Correct Transmit Margin masks drm/amdgpu: Use RMW accessors for changing LNKCTL drm/amdgpu: Prefer pcie_capability_read_word() drm/amdgpu: Replace numbers with PCI_EXP_LNKCTL2 definitions drm/amdgpu: Correct Transmit Margin masks PCI: Add #defines for Enter Compliance, Transmit Margin powerpc/fadump: reset dump area size if fadump memory reserve fails clk: imx: composite-8m: fix clock pauses when set_rate would be a no-op PCI/ASPM: Use RMW accessors for changing LNKCTL PCI: pciehp: Use RMW accessors for changing LNKCTL PCI: Mark NVIDIA T4 GPUs to avoid bus reset clk: sunxi-ng: Modify mismatched function name drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init() ipmi:ssif: Fix a memory leak when scanning for an adapter ipmi:ssif: Add check for kstrdup ALSA: ac97: Fix possible error value of *rac97 of: unittest: Fix overlay type in apply/revert check drm/mediatek: Fix potential memory leak if vmap() fail audit: fix possible soft lockup in __audit_inode_child() smackfs: Prevent underflow in smk_set_cipso() drm/msm/mdp5: Don't leak some plane state ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig drm/panel: simple: Add missing connector type and pixel format for AUO T215HVN01 drm/armada: Fix off-by-one error in armada_overlay_get_property() of: unittest: fix null pointer dereferencing in of_unittest_find_node_by_name() drm/tegra: dpaux: Fix incorrect return value of platform_get_irq drm/tegra: Remove superfluous error messages around platform_get_irq() md/md-bitmap: hold 'reconfig_mutex' in backlog_store() md/bitmap: don't set max_write_behind if there is no write mostly device drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl' arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC ARM: dts: BCM53573: Fix Ethernet info for Luxul devices drm: adv7511: Fix low refresh rate register for ADV7533/5 ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split) ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210 ARM: dts: s5pv210: correct ethernet unit address in SMDKV210 ARM: dts: s5pv210: use defines for IRQ flags in SMDKV210 ARM: dts: s5pv210: add RTC 32 KHz clock in SMDKV210 ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses (split) ARM: dts: s3c64xx: align pinctrl with dtschema ARM: dts: s3c6410: align node SROM bus node name with dtschema in Mini6410 ARM: dts: s3c6410: move fixed clocks under root node in Mini6410 drm/etnaviv: fix dumping of active MMU context ARM: dts: BCM53573: Use updated "spi-gpio" binding properties ARM: dts: BCM53573: Add cells sizes to PCIe node ARM: dts: BCM53573: Drop nonexistent "default-off" LED trigger drm/amdgpu: avoid integer overflow warning in amdgpu_device_resize_fb_bar() quota: fix dqput() to follow the guarantees dquot_srcu should provide quota: add new helper dquot_active() quota: rename dquot_active() to inode_quota_active() quota: factor out dquot_write_dquot() quota: avoid increasing DQST_LOOKUPS when iterating over dirty/inuse list drm/bridge: tc358764: Fix debug print parameter order netrom: Deny concurrent connect(). net/sched: sch_hfsc: Ensure inner classes have fsc curve mlxsw: i2c: Limit single transaction buffer size mlxsw: i2c: Fix chunk size setting in output mailbox buffer net: arcnet: Do not call kfree_skb() under local_irq_disable() wifi: ath9k: use IS_ERR() with debugfs_create_dir() wifi: mwifiex: avoid possible NULL skb pointer dereference wifi: ath9k: protect WMI command response buffer replacement with a lock wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx wifi: mwifiex: Fix missed return in oob checks failed path wifi: mwifiex: fix memory leak in mwifiex_histogram_read() fs: ocfs2: namei: check return value of ocfs2_add_entry() lwt: Check LWTUNNEL_XMIT_CONTINUE strictly lwt: Fix return values of BPF xmit ops hwrng: iproc-rng200 - Implement suspend and resume calls hwrng: iproc-rng200 - use semicolons rather than commas to separate statements crypto: caam - fix unchecked return value error Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe() crypto: stm32 - Properly handle pm_runtime_get failing wifi: mwifiex: fix error recovery in PCIE buffer descriptor management mwifiex: switch from 'pci_' to 'dma_' API wifi: mwifiex: Fix OOB and integer underflow when rx packets can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors also in case of OOM spi: tegra20-sflash: fix to check return value of platform_get_irq() in tegra_sflash_probe() regmap: rbtree: Use alloc_flags for memory allocations tcp: tcp_enter_quickack_mode() should be static bpf: Clear the probe_addr for uprobe cpufreq: powernow-k8: Use related_cpus instead of cpus in driver.exit() perf/imx_ddr: don't enable counter0 if none of 4 counters are used x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved x86/boot: Annotate local functions x86/asm: Make more symbols local OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() tmpfs: verify {g,u}id mount options correctly fs: Fix error checking for d_hash_and_lookup() new helper: lookup_positive_unlocked() eventfd: prevent underflow for eventfd semaphores eventfd: Export eventfd_ctx_do_read() reiserfs: Check the return value from __getblk() Revert "net: macsec: preserve ingress frame ordering" udf: Handle error when adding extent to a file udf: Check consistency of Space Bitmap Descriptor powerpc/32s: Fix assembler warning about r0 net: Avoid address overwrite in kernel_connect platform/mellanox: Fix mlxbf-tmfifo not handling all virtio CONSOLE notifications ALSA: seq: oss: Fix racy open/close of MIDI devices scsi: storvsc: Always set no_report_opcodes cifs: add a warning when the in-flight count goes negative sctp: handle invalid error codes without calling BUG() bnx2x: fix page fault following EEH recovery netlabel: fix shift wrapping bug in netlbl_catmap_setlong() scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock idmaengine: make FSL_EDMA and INTEL_IDMA64 depends on HAS_IOMEM net: usb: qmi_wwan: add Quectel EM05GV2 clk: fixed-mmio: make COMMON_CLK_FIXED_MMIO depend on HAS_IOMEM security: keys: perform capable check only on privileged operations platform/x86: huawei-wmi: Silence ambient light sensor platform/x86: intel: hid: Always call BTNL ACPI method ASoC: atmel: Fix the 8K sample parameter in I2SC master ASoc: codecs: ES8316: Fix DMIC config fs/nls: make load_nls() take a const parameter s390/dasd: fix hanging device after request requeue s390/dasd: use correct number of retries for ERP requests m68k: Fix invalid .section syntax vxlan: generalize vxlan_parse_gpe_hdr and remove unused args ethernet: atheros: fix return value check in atl1c_tso_csum() ASoC: da7219: Check for failure reading AAD IRQ events ASoC: da7219: Flush pending AAD IRQ when suspending 9p: virtio: make sure 'offs' is initialized in zc_request pinctrl: amd: Don't show `Invalid config param` errors nilfs2: fix WARNING in mark_buffer_dirty due to discarded buffer reuse nilfs2: fix general protection fault in nilfs_lookup_dirty_data_buffers() fsi: master-ast-cf: Add MODULE_FIRMWARE macro firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe serial: sc16is7xx: fix bug when first setting GPIO direction Bluetooth: btsdio: fix use after free bug in btsdio_remove due to race condition staging: rtl8712: fix race condition HID: wacom: remove the battery when the EKR is off USB: serial: option: add FOXCONN T99W368/T99W373 product USB: serial: option: add Quectel EM05G variant (0x030e) modules: only allow symbol_get of EXPORT_SYMBOL_GPL modules rtc: ds1685: use EXPORT_SYMBOL_GPL for ds1685_rtc_poweroff net: enetc: use EXPORT_SYMBOL_GPL for enetc_phc_index mmc: au1xmmc: force non-modular build and remove symbol_get usage ARM: pxa: remove use of symbol_get() erofs: ensure that the post-EOF tails are all zeroed Linux 5.4.256 Revert "MIPS: Alchemy: fix dbdma2" powerpc/pmac/smp: Drop unnecessary volatile qualifier powerpc/pmac/smp: Avoid unused-variable warnings Revert "drm/display/dp: Fix the DP DSC Receiver cap size" Revert "macsec: Fix traffic counters/statistics" Revert "macsec: use DEV_STATS_INC()" ANDROID: GKI: add back pm_runtime_get_if_in_use() Revert "interconnect: Add helpers for enabling/disabling a path" Revert "interconnect: Do not skip aggregation for disabled paths" Revert "ALSA: pcm: Set per-card upper limit of PCM buffer allocations" Revert "ALSA: pcm: Use SG-buffer only when direct DMA is available" Revert "ALSA: pcm: Fix potential data race at PCM memory allocation helpers" Revert "ALSA: pcm: Fix build error on m68k and others" Revert "Revert "ALSA: pcm: Use SG-buffer only when direct DMA is available"" Revert "ALSA: pcm: Check for null pointer of pointer substream before dereferencing it" Linux 5.4.255 dma-buf/sw_sync: Avoid recursive lock during fence signal pinctrl: renesas: rza2: Add lock around pinctrl_generic{{add,remove}_group,{add,remove}_function} clk: Fix undefined reference to `clk_rate_exclusive_{get,put}' scsi: core: raid_class: Remove raid_component_add() scsi: snic: Fix double free in snic_tgt_create() irqchip/mips-gic: Don't touch vl_map if a local interrupt is not routable Documentation/sysctl: document page_lock_unfairness ALSA: pcm: Check for null pointer of pointer substream before dereferencing it interconnect: Do not skip aggregation for disabled paths Revert "ALSA: pcm: Use SG-buffer only when direct DMA is available" ALSA: pcm: Fix build error on m68k and others rtnetlink: Reject negative ifindexes in RTM_NEWLINK mm: allow a controlled amount of unfairness in the page lock x86/fpu: Set X86_FEATURE_OSXSAVE feature after enabling OSXSAVE in CR4 drm/display/dp: Fix the DP DSC Receiver cap size PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus media: vcodec: Fix potential array out-of-bounds in encoder queue_setup radix tree: remove unused variable lib/clz_ctz.c: Fix __clzdi2() and __ctzdi2() for 32-bit kernels batman-adv: Hold rtnl lock during MTU update via netlink batman-adv: Fix batadv_v_ogm_aggr_send memory leak batman-adv: Fix TT global entry leak when client roamed back batman-adv: Do not get eth header before batadv_check_management_packet batman-adv: Don't increase MTU when set by user batman-adv: Trigger events for auto adjusted MTU nfsd: Fix race to FREE_STATEID and cl_revoked clk: Fix slab-out-of-bounds error in devm_clk_release() NFSv4: Fix dropped lock for racing OPEN and delegation return ibmveth: Use dcbf rather than dcbfl bonding: fix macvlan over alb bond support net: remove bond_slave_has_mac_rcu() net/sched: fix a qdisc modification with ambiguous command request igb: Avoid starting unnecessary workqueues net: validate veth and vxcan peer ifindexes net: bcmgenet: Fix return value check for fixed_phy_register() net: bgmac: Fix return value check for fixed_phy_register() ipvlan: Fix a reference count leak warning in ipvlan_ns_exit() dccp: annotate data-races in dccp_poll() sock: annotate data-races around prot->memory_pressure octeontx2-af: SDP: fix receive link config tracing: Fix memleak due to race between current_tracer and trace drm/amd/display: check TG is non-null before checking if enabled drm/amd/display: do not wait for mpc idle if tg is disabled ASoC: fsl_sai: Disable bit clock with transmitter ASoC: fsl_sai: Add new added registers and new bit definition ASoC: fsl_sai: Refine enable/disable TE/RE sequence in trigger() regmap: Account for register length in SMBus I/O limits ALSA: pcm: Fix potential data race at PCM memory allocation helpers ALSA: pcm: Use SG-buffer only when direct DMA is available ALSA: pcm: Set per-card upper limit of PCM buffer allocations dm integrity: reduce vmalloc space footprint on 32-bit architectures dm integrity: increase RECALC_SECTORS to improve recalculate speed fbdev: fix potential OOB read in fast_imageblit() fbdev: Fix sys_imageblit() for arbitrary image widths fbdev: Improve performance of sys_imageblit() MIPS: cpu-features: Use boot_cpu_type for CPU type based features MIPS: cpu-features: Enable octeon_cache by cpu_type fs: dlm: fix mismatch of plock results from userspace fs: dlm: use dlm_plock_info for do_unlock_close fs: dlm: change plock interrupted message to debug again fs: dlm: add pid to debug log dlm: replace usage of found with dedicated list iterator variable dlm: improve plock logging if interrupted PCI: acpiphp: Reassign resources on bridge if necessary net: phy: broadcom: stub c45 read/write for 54810 mmc: f-sdh30: fix order of function calls in sdhci_f_sdh30_remove net: xfrm: Amend XFRMA_SEC_CTX nla_policy structure net: fix the RTO timer retransmitting skb every 1ms if linear option is enabled virtio-net: set queues after driver_ok af_unix: Fix null-ptr-deref in unix_stream_sendpage(). netfilter: set default timeout to 3 secs for sctp shutdown send and recv state mmc: block: Fix in_flight[issue_type] value error mmc: wbsd: fix double mmc_free_host() in wbsd_init() cifs: Release folio lock on fscache read hit. ALSA: usb-audio: Add support for Mythware XA001AU capture and playback interfaces. serial: 8250: Fix oops for port->pm on uart_change_pm() ASoC: meson: axg-tdm-formatter: fix channel slot allocation ASoC: rt5665: add missed regulator_bulk_disable ARM: dts: imx: Set default tuning step for imx6sx usdhc ARM: dts: imx: Set default tuning step for imx7d usdhc ARM: dts: imx: Adjust dma-apbh node name ARM: dts: imx7s: Drop dma-apb interrupt-names bus: ti-sysc: Flush posted write on enable before reset bus: ti-sysc: Improve reset to work with modules with no sysconfig net: do not allow gso_size to be set to GSO_BY_FRAGS sock: Fix misuse of sk_under_memory_pressure() net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset i40e: fix misleading debug logs team: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves netfilter: nft_dynset: disallow object maps ipvs: fix racy memcpy in proc_do_sync_threshold selftests: mirror_gre_changes: Tighten up the TTL test match xfrm: add NULL check in xfrm_update_ae_params ip_vti: fix potential slab-use-after-free in decode_session6 ip6_vti: fix slab-use-after-free in decode_session6 xfrm: fix slab-use-after-free in decode_session6 xfrm: interface: rename xfrm_interface.c to xfrm_interface_core.c net: af_key: fix sadb_x_filter validation net: xfrm: Fix xfrm_address_filter OOB read btrfs: fix BUG_ON condition in btrfs_cancel_balance tty: serial: fsl_lpuart: Clear the error flags by writing 1 for lpuart32 platforms powerpc/rtas_flash: allow user copy to flash block cache objects fbdev: mmp: fix value check in mmphw_probe() i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue virtio-mmio: don't break lifecycle of vm_dev virtio-mmio: Use to_virtio_mmio_device() to simply code virtio-mmio: convert to devm_platform_ioremap_resource nfsd: Remove incorrect check in nfsd4_validate_stateid nfsd4: kill warnings on testing stateids with mismatched clientids net/ncsi: Fix gma flag setting after response tracing/probes: Fix to update dynamic data counter if fetcharg uses it tracing/probes: Have process_fetch_insn() take a void * instead of pt_regs leds: trigger: netdev: Recheck NETDEV_LED_MODE_LINKUP on dev rename mmc: sunxi: fix deferred probing mmc: bcm2835: fix deferred probing USB: dwc3: qcom: fix NULL-deref on suspend usb: dwc3: qcom: Add helper functions to enable,disable wake irqs interconnect: Add helpers for enabling/disabling a path interconnect: Move internal structs into a separate file irqchip/mips-gic: Use raw spinlock for gic_lock irqchip/mips-gic: Get rid of the reliance on irq_cpu_online() ALSA: hda: Fix unhandled register update during auto-suspend period PM: runtime: Add pm_runtime_get_if_active() PM-runtime: add tracepoints for usage_count changes iommu/amd: Fix "Guest Virtual APIC Table Root Pointer" configuration in IRTE iio: addac: stx104: Fix race condition when converting analog-to-digital iio: addac: stx104: Fix race condition for stx104_write_raw() iio: stx104: Move to addac subdirectory iio: adc: stx104: Implement and utilize register structures iio: adc: stx104: Utilize iomap interface iio: add addac subdirectory IMA: allow/fix UML builds powerpc/kasan: Disable KCOV in KASAN code ALSA: hda: fix a possible null-pointer dereference due to data race in snd_hdac_regmap_sync() ALSA: hda/realtek: Add quirks for Unis H3C Desktop B760 & Q760 drm/amdgpu: Fix potential fence use-after-free v2 Bluetooth: L2CAP: Fix use-after-free pcmcia: rsrc_nonstatic: Fix memory leak in nonstatic_release_resource_db() gfs2: Fix possible data races in gfs2_show_options() usb: chipidea: imx: don't request QoS for imx8ulp media: platform: mediatek: vpu: fix NULL ptr dereference media: v4l2-mem2mem: add lock to protect parameter num_rdy FS: JFS: Check for read-only mounted filesystem in txBegin FS: JFS: Fix null-ptr-deref Read in txBegin MIPS: dec: prom: Address -Warray-bounds warning fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev udf: Fix uninitialized array access for some pathnames ovl: check type and offset of struct vfsmount in ovl_entry HID: add quirk for 03f0:464a HP Elite Presenter Mouse quota: fix warning in dqgrab() quota: Properly disable quotas when add_dquot_ref() fails ALSA: emu10k1: roll up loops in DSP setup code for Audigy drm/radeon: Fix integer overflow in radeon_cs_parser_init macsec: use DEV_STATS_INC() macsec: Fix traffic counters/statistics selftests: forwarding: tc_flower: Relax success criterion mmc: sdhci-f-sdh30: Replace with sdhci_pltfm mmc: sdhci_f_sdh30: convert to devm_platform_ioremap_resource Conflict: drivers/devfreq/devfreq.c drivers/mmc/core/block.c drivers/rpmsg/qcom_glink_native.c include/net/tcp.h net/ipv4/tcp_input.c Change-Id: I9381be24d8fd353e56226698d20732fee74a03c3 Signed-off-by: kamasali Satyanarayan <[email protected]>
This commit is contained in:
commit
9110d2473d
793 changed files with 15256 additions and 13211 deletions
|
|
@ -394,7 +394,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
|
|||
struct page **in_pages = NULL, **out_pages = NULL;
|
||||
struct virtio_chan *chan = client->trans;
|
||||
struct scatterlist *sgs[4];
|
||||
size_t offs;
|
||||
size_t offs = 0;
|
||||
int need_drop = 0;
|
||||
int kicked = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb,
|
|||
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
||||
struct batadv_elp_packet *elp_packet;
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
||||
struct ethhdr *ethhdr;
|
||||
bool res;
|
||||
int ret = NET_RX_DROP;
|
||||
|
||||
|
|
@ -509,6 +509,7 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb,
|
|||
if (!res)
|
||||
goto free_skb;
|
||||
|
||||
ethhdr = eth_hdr(skb);
|
||||
if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
|
||||
goto free_skb;
|
||||
|
||||
|
|
|
|||
|
|
@ -122,8 +122,10 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
|
|||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||
|
||||
if (hard_iface->if_status != BATADV_IF_ACTIVE)
|
||||
if (hard_iface->if_status != BATADV_IF_ACTIVE) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
|
||||
batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
|
||||
|
|
@ -994,7 +996,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
|
|||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
||||
struct batadv_ogm2_packet *ogm_packet;
|
||||
struct ethhdr *ethhdr = eth_hdr(skb);
|
||||
struct ethhdr *ethhdr;
|
||||
int ogm_offset;
|
||||
u8 *packet_pos;
|
||||
int ret = NET_RX_DROP;
|
||||
|
|
@ -1008,6 +1010,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
|
|||
if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
|
||||
goto free_skb;
|
||||
|
||||
ethhdr = eth_hdr(skb);
|
||||
if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
|
||||
goto free_skb;
|
||||
|
||||
|
|
|
|||
|
|
@ -632,7 +632,19 @@ out:
|
|||
*/
|
||||
void batadv_update_min_mtu(struct net_device *soft_iface)
|
||||
{
|
||||
soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
|
||||
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
|
||||
int limit_mtu;
|
||||
int mtu;
|
||||
|
||||
mtu = batadv_hardif_min_mtu(soft_iface);
|
||||
|
||||
if (bat_priv->mtu_set_by_user)
|
||||
limit_mtu = bat_priv->mtu_set_by_user;
|
||||
else
|
||||
limit_mtu = ETH_DATA_LEN;
|
||||
|
||||
mtu = min(mtu, limit_mtu);
|
||||
dev_set_mtu(soft_iface, mtu);
|
||||
|
||||
/* Check if the local translate table should be cleaned up to match a
|
||||
* new (and smaller) MTU.
|
||||
|
|
|
|||
|
|
@ -496,7 +496,10 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
|
||||
|
||||
rtnl_lock();
|
||||
batadv_update_min_mtu(bat_priv->soft_iface);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
|
||||
|
|
|
|||
|
|
@ -156,11 +156,14 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
|
|||
|
||||
static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(dev);
|
||||
|
||||
/* check ranges */
|
||||
if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev))
|
||||
return -EINVAL;
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
bat_priv->mtu_set_by_user = new_mtu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -780,7 +780,6 @@ check_roaming:
|
|||
if (roamed_back) {
|
||||
batadv_tt_global_free(bat_priv, tt_global,
|
||||
"Roaming canceled");
|
||||
tt_global = NULL;
|
||||
} else {
|
||||
/* The global entry has to be marked as ROAMING and
|
||||
* has to be kept for consistency purpose
|
||||
|
|
|
|||
|
|
@ -1563,6 +1563,12 @@ struct batadv_priv {
|
|||
/** @soft_iface: net device which holds this struct as private data */
|
||||
struct net_device *soft_iface;
|
||||
|
||||
/**
|
||||
* @mtu_set_by_user: MTU was set once by user
|
||||
* protected by rtnl_lock
|
||||
*/
|
||||
int mtu_set_by_user;
|
||||
|
||||
/**
|
||||
* @bat_counters: mesh internal traffic statistic counters (see
|
||||
* batadv_counters)
|
||||
|
|
|
|||
|
|
@ -1207,6 +1207,15 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/* Reject outgoing connection to device with same BD ADDR against
|
||||
* CVE-2020-26555
|
||||
*/
|
||||
if (!bacmp(&hdev->bdaddr, dst)) {
|
||||
bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
|
||||
dst);
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
}
|
||||
|
||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||
if (!acl) {
|
||||
acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
|
||||
|
|
@ -1382,34 +1391,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
|
|||
if (!test_bit(HCI_CONN_AUTH, &conn->flags))
|
||||
goto auth;
|
||||
|
||||
/* An authenticated FIPS approved combination key has sufficient
|
||||
* security for security level 4. */
|
||||
if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 &&
|
||||
sec_level == BT_SECURITY_FIPS)
|
||||
goto encrypt;
|
||||
|
||||
/* An authenticated combination key has sufficient security for
|
||||
security level 3. */
|
||||
if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 ||
|
||||
conn->key_type == HCI_LK_AUTH_COMBINATION_P256) &&
|
||||
sec_level == BT_SECURITY_HIGH)
|
||||
goto encrypt;
|
||||
|
||||
/* An unauthenticated combination key has sufficient security for
|
||||
security level 1 and 2. */
|
||||
if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 ||
|
||||
conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) &&
|
||||
(sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
|
||||
goto encrypt;
|
||||
|
||||
/* A combination key has always sufficient security for the security
|
||||
levels 1 or 2. High security level requires the combination key
|
||||
is generated using maximum PIN code length (16).
|
||||
For pre 2.1 units. */
|
||||
if (conn->key_type == HCI_LK_COMBINATION &&
|
||||
(sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW ||
|
||||
conn->pin_length == 16))
|
||||
goto encrypt;
|
||||
switch (conn->key_type) {
|
||||
case HCI_LK_AUTH_COMBINATION_P256:
|
||||
/* An authenticated FIPS approved combination key has
|
||||
* sufficient security for security level 4 or lower.
|
||||
*/
|
||||
if (sec_level <= BT_SECURITY_FIPS)
|
||||
goto encrypt;
|
||||
break;
|
||||
case HCI_LK_AUTH_COMBINATION_P192:
|
||||
/* An authenticated combination key has sufficient security for
|
||||
* security level 3 or lower.
|
||||
*/
|
||||
if (sec_level <= BT_SECURITY_HIGH)
|
||||
goto encrypt;
|
||||
break;
|
||||
case HCI_LK_UNAUTH_COMBINATION_P192:
|
||||
case HCI_LK_UNAUTH_COMBINATION_P256:
|
||||
/* An unauthenticated combination key has sufficient security
|
||||
* for security level 2 or lower.
|
||||
*/
|
||||
if (sec_level <= BT_SECURITY_MEDIUM)
|
||||
goto encrypt;
|
||||
break;
|
||||
case HCI_LK_COMBINATION:
|
||||
/* A combination key has always sufficient security for the
|
||||
* security levels 2 or lower. High security level requires the
|
||||
* combination key is generated using maximum PIN code length
|
||||
* (16). For pre 2.1 units.
|
||||
*/
|
||||
if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16)
|
||||
goto encrypt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auth:
|
||||
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
/* Bluetooth HCI event handling. */
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
|
@ -2594,6 +2596,16 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
|
||||
ev->link_type);
|
||||
|
||||
/* Reject incoming connection from device with same BD ADDR against
|
||||
* CVE-2020-26555
|
||||
*/
|
||||
if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
|
||||
bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
|
||||
&ev->bdaddr);
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
|
||||
&flags);
|
||||
|
||||
|
|
@ -3935,6 +3947,15 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
/* Ignore NULL link key against CVE-2020-26555 */
|
||||
if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) {
|
||||
bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR",
|
||||
&ev->bdaddr);
|
||||
hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
|
||||
hci_conn_drop(conn);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_conn_hold(conn);
|
||||
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
|
||||
hci_conn_drop(conn);
|
||||
|
|
@ -4426,8 +4447,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn)
|
|||
* available, then do not declare that OOB data is
|
||||
* present.
|
||||
*/
|
||||
if (!memcmp(data->rand256, ZERO_KEY, 16) ||
|
||||
!memcmp(data->hash256, ZERO_KEY, 16))
|
||||
if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
|
||||
!crypto_memneq(data->hash256, ZERO_KEY, 16))
|
||||
return 0x00;
|
||||
|
||||
return 0x02;
|
||||
|
|
@ -4437,8 +4458,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn)
|
|||
* not supported by the hardware, then check that if
|
||||
* P-192 data values are present.
|
||||
*/
|
||||
if (!memcmp(data->rand192, ZERO_KEY, 16) ||
|
||||
!memcmp(data->hash192, ZERO_KEY, 16))
|
||||
if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
|
||||
!crypto_memneq(data->hash192, ZERO_KEY, 16))
|
||||
return 0x00;
|
||||
|
||||
return 0x01;
|
||||
|
|
@ -4454,7 +4475,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
if (!conn || !hci_conn_ssp_enabled(conn))
|
||||
goto unlock;
|
||||
|
||||
hci_conn_hold(conn);
|
||||
|
|
@ -4689,7 +4710,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
if (!conn || !hci_conn_ssp_enabled(conn))
|
||||
goto unlock;
|
||||
|
||||
/* Reset the authentication requirement to unknown */
|
||||
|
|
|
|||
|
|
@ -430,7 +430,8 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
|
|||
ni->type = hdev->dev_type;
|
||||
ni->bus = hdev->bus;
|
||||
bacpy(&ni->bdaddr, &hdev->bdaddr);
|
||||
memcpy(ni->name, hdev->name, 8);
|
||||
memcpy_and_pad(ni->name, sizeof(ni->name), hdev->name,
|
||||
strnlen(hdev->name, sizeof(ni->name)), '\0');
|
||||
|
||||
opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5723,9 +5723,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
|
|||
if (!chan)
|
||||
goto done;
|
||||
|
||||
chan = l2cap_chan_hold_unless_zero(chan);
|
||||
if (!chan)
|
||||
goto done;
|
||||
|
||||
l2cap_chan_lock(chan);
|
||||
l2cap_chan_del(chan, ECONNREFUSED);
|
||||
l2cap_chan_unlock(chan);
|
||||
l2cap_chan_put(chan);
|
||||
|
||||
done:
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
|
|
|||
|
|
@ -477,8 +477,8 @@ static int ceph_tcp_connect(struct ceph_connection *con)
|
|||
dout("connect %s\n", ceph_pr_addr(&con->peer_addr));
|
||||
|
||||
con_sock_state_connecting(con);
|
||||
ret = sock->ops->connect(sock, (struct sockaddr *)&ss, sizeof(ss),
|
||||
O_NONBLOCK);
|
||||
ret = kernel_connect(sock, (struct sockaddr *)&ss, sizeof(ss),
|
||||
O_NONBLOCK);
|
||||
if (ret == -EINPROGRESS) {
|
||||
dout("connect %s EINPROGRESS sk_state = %u\n",
|
||||
ceph_pr_addr(&con->peer_addr),
|
||||
|
|
|
|||
|
|
@ -2953,7 +2953,7 @@ static int devlink_param_get(struct devlink *devlink,
|
|||
const struct devlink_param *param,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
if (!param->get || devlink->reload_failed)
|
||||
if (!param->get)
|
||||
return -EOPNOTSUPP;
|
||||
return param->get(devlink, param->id, ctx);
|
||||
}
|
||||
|
|
@ -2962,7 +2962,7 @@ static int devlink_param_set(struct devlink *devlink,
|
|||
const struct devlink_param *param,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
if (!param->set || devlink->reload_failed)
|
||||
if (!param->set)
|
||||
return -EOPNOTSUPP;
|
||||
return param->set(devlink, param->id, ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1564,8 +1564,7 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
|
|||
|
||||
memset(&keys, 0, sizeof(keys));
|
||||
__skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric,
|
||||
&keys, NULL, 0, 0, 0,
|
||||
FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
|
||||
&keys, NULL, 0, 0, 0, 0);
|
||||
|
||||
return __flow_hash_from_keys(&keys, &hashrnd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,9 +59,8 @@ static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt,
|
|||
ret = BPF_OK;
|
||||
} else {
|
||||
skb_reset_mac_header(skb);
|
||||
ret = skb_do_redirect(skb);
|
||||
if (ret == 0)
|
||||
ret = BPF_REDIRECT;
|
||||
skb_do_redirect(skb);
|
||||
ret = BPF_REDIRECT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -254,7 +253,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)
|
|||
|
||||
err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
return net_xmit_errno(err);
|
||||
|
||||
/* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */
|
||||
return LWTUNNEL_XMIT_DONE;
|
||||
|
|
|
|||
|
|
@ -934,7 +934,9 @@ static void neigh_periodic_work(struct work_struct *work)
|
|||
(state == NUD_FAILED ||
|
||||
!time_in_range_open(jiffies, n->used,
|
||||
n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
|
||||
*np = n->next;
|
||||
rcu_assign_pointer(*np,
|
||||
rcu_dereference_protected(n->next,
|
||||
lockdep_is_held(&tbl->lock)));
|
||||
neigh_mark_dead(n);
|
||||
write_unlock(&n->lock);
|
||||
neigh_cleanup_and_release(n);
|
||||
|
|
|
|||
|
|
@ -645,19 +645,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
|
|||
seq_puts(seq, " Flags: ");
|
||||
|
||||
for (i = 0; i < NR_PKT_FLAGS; i++) {
|
||||
if (i == F_FLOW_SEQ)
|
||||
if (i == FLOW_SEQ_SHIFT)
|
||||
if (!pkt_dev->cflows)
|
||||
continue;
|
||||
|
||||
if (pkt_dev->flags & (1 << i))
|
||||
if (pkt_dev->flags & (1 << i)) {
|
||||
seq_printf(seq, "%s ", pkt_flag_names[i]);
|
||||
else if (i == F_FLOW_SEQ)
|
||||
seq_puts(seq, "FLOW_RND ");
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
if (i == F_IPSEC && pkt_dev->spi)
|
||||
seq_printf(seq, "spi:%u", pkt_dev->spi);
|
||||
if (i == IPSEC_SHIFT && pkt_dev->spi)
|
||||
seq_printf(seq, "spi:%u ", pkt_dev->spi);
|
||||
#endif
|
||||
} else if (i == FLOW_SEQ_SHIFT) {
|
||||
seq_puts(seq, "FLOW_RND ");
|
||||
}
|
||||
}
|
||||
|
||||
seq_puts(seq, "\n");
|
||||
|
|
|
|||
|
|
@ -2034,13 +2034,27 @@ out_err:
|
|||
return err;
|
||||
}
|
||||
|
||||
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
|
||||
struct netlink_ext_ack *exterr)
|
||||
int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
|
||||
struct netlink_ext_ack *exterr)
|
||||
{
|
||||
return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy,
|
||||
const struct ifinfomsg *ifmp;
|
||||
const struct nlattr *attrs;
|
||||
size_t len;
|
||||
|
||||
ifmp = nla_data(nla_peer);
|
||||
attrs = nla_data(nla_peer) + sizeof(struct ifinfomsg);
|
||||
len = nla_len(nla_peer) - sizeof(struct ifinfomsg);
|
||||
|
||||
if (ifmp->ifi_index < 0) {
|
||||
NL_SET_ERR_MSG_ATTR(exterr, nla_peer,
|
||||
"ifindex can't be negative");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return nla_parse_deprecated(tb, IFLA_MAX, attrs, len, ifla_policy,
|
||||
exterr);
|
||||
}
|
||||
EXPORT_SYMBOL(rtnl_nla_parse_ifla);
|
||||
EXPORT_SYMBOL(rtnl_nla_parse_ifinfomsg);
|
||||
|
||||
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
|
||||
{
|
||||
|
|
@ -3062,9 +3076,12 @@ replay:
|
|||
ifname[0] = '\0';
|
||||
|
||||
ifm = nlmsg_data(nlh);
|
||||
if (ifm->ifi_index > 0)
|
||||
if (ifm->ifi_index > 0) {
|
||||
dev = __dev_get_by_index(net, ifm->ifi_index);
|
||||
else {
|
||||
} else if (ifm->ifi_index < 0) {
|
||||
NL_SET_ERR_MSG(extack, "ifindex can't be negative");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (ifname[0])
|
||||
dev = __dev_get_by_name(net, ifname);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3807,21 +3807,20 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
|
|||
struct sk_buff *segs = NULL;
|
||||
struct sk_buff *tail = NULL;
|
||||
struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
|
||||
skb_frag_t *frag = skb_shinfo(head_skb)->frags;
|
||||
unsigned int mss = skb_shinfo(head_skb)->gso_size;
|
||||
unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
|
||||
struct sk_buff *frag_skb = head_skb;
|
||||
unsigned int offset = doffset;
|
||||
unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
|
||||
unsigned int partial_segs = 0;
|
||||
unsigned int headroom;
|
||||
unsigned int len = head_skb->len;
|
||||
struct sk_buff *frag_skb;
|
||||
skb_frag_t *frag;
|
||||
__be16 proto;
|
||||
bool csum, sg;
|
||||
int nfrags = skb_shinfo(head_skb)->nr_frags;
|
||||
int err = -ENOMEM;
|
||||
int i = 0;
|
||||
int pos;
|
||||
int nfrags, pos;
|
||||
int dummy;
|
||||
|
||||
if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) &&
|
||||
|
|
@ -3899,6 +3898,13 @@ normal:
|
|||
headroom = skb_headroom(head_skb);
|
||||
pos = skb_headlen(head_skb);
|
||||
|
||||
if (skb_orphan_frags(head_skb, GFP_ATOMIC))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
nfrags = skb_shinfo(head_skb)->nr_frags;
|
||||
frag = skb_shinfo(head_skb)->frags;
|
||||
frag_skb = head_skb;
|
||||
|
||||
do {
|
||||
struct sk_buff *nskb;
|
||||
skb_frag_t *nskb_frag;
|
||||
|
|
@ -3923,6 +3929,10 @@ normal:
|
|||
(skb_headlen(list_skb) == len || sg)) {
|
||||
BUG_ON(skb_headlen(list_skb) > len);
|
||||
|
||||
nskb = skb_clone(list_skb, GFP_ATOMIC);
|
||||
if (unlikely(!nskb))
|
||||
goto err;
|
||||
|
||||
i = 0;
|
||||
nfrags = skb_shinfo(list_skb)->nr_frags;
|
||||
frag = skb_shinfo(list_skb)->frags;
|
||||
|
|
@ -3941,12 +3951,8 @@ normal:
|
|||
frag++;
|
||||
}
|
||||
|
||||
nskb = skb_clone(list_skb, GFP_ATOMIC);
|
||||
list_skb = list_skb->next;
|
||||
|
||||
if (unlikely(!nskb))
|
||||
goto err;
|
||||
|
||||
if (unlikely(pskb_trim(nskb, len))) {
|
||||
kfree_skb(nskb);
|
||||
goto err;
|
||||
|
|
@ -4011,12 +4017,16 @@ normal:
|
|||
skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
|
||||
SKBTX_SHARED_FRAG;
|
||||
|
||||
if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
|
||||
skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
|
||||
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
|
||||
goto err;
|
||||
|
||||
while (pos < offset + len) {
|
||||
if (i >= nfrags) {
|
||||
if (skb_orphan_frags(list_skb, GFP_ATOMIC) ||
|
||||
skb_zerocopy_clone(nskb, list_skb,
|
||||
GFP_ATOMIC))
|
||||
goto err;
|
||||
|
||||
i = 0;
|
||||
nfrags = skb_shinfo(list_skb)->nr_frags;
|
||||
frag = skb_shinfo(list_skb)->frags;
|
||||
|
|
@ -4030,10 +4040,6 @@ normal:
|
|||
i--;
|
||||
frag--;
|
||||
}
|
||||
if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
|
||||
skb_zerocopy_clone(nskb, frag_skb,
|
||||
GFP_ATOMIC))
|
||||
goto err;
|
||||
|
||||
list_skb = list_skb->next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -702,7 +702,8 @@ bool sk_mc_loop(struct sock *sk)
|
|||
return false;
|
||||
if (!sk)
|
||||
return true;
|
||||
switch (sk->sk_family) {
|
||||
/* IPV6_ADDRFORM can change sk->sk_family under us. */
|
||||
switch (READ_ONCE(sk->sk_family)) {
|
||||
case AF_INET:
|
||||
return inet_sk(sk)->mc_loop;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
|
@ -2227,9 +2228,9 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)
|
|||
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
|
||||
if (refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf))
|
||||
break;
|
||||
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||
if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
|
||||
break;
|
||||
if (sk->sk_err)
|
||||
if (READ_ONCE(sk->sk_err))
|
||||
break;
|
||||
timeo = schedule_timeout(timeo);
|
||||
}
|
||||
|
|
@ -2257,7 +2258,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
|
|||
goto failure;
|
||||
|
||||
err = -EPIPE;
|
||||
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||
if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
|
||||
goto failure;
|
||||
|
||||
if (sk_wmem_alloc_get(sk) < READ_ONCE(sk->sk_sndbuf))
|
||||
|
|
@ -2636,7 +2637,7 @@ void __sk_mem_reduce_allocated(struct sock *sk, int amount)
|
|||
if (mem_cgroup_sockets_enabled && sk->sk_memcg)
|
||||
mem_cgroup_uncharge_skmem(sk->sk_memcg, amount);
|
||||
|
||||
if (sk_under_memory_pressure(sk) &&
|
||||
if (sk_under_global_memory_pressure(sk) &&
|
||||
(sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)))
|
||||
sk_leave_memory_pressure(sk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,12 +243,12 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info)
|
|||
int err;
|
||||
struct net *net = dev_net(skb->dev);
|
||||
|
||||
/* Only need dccph_dport & dccph_sport which are the first
|
||||
* 4 bytes in dccp header.
|
||||
* Our caller (icmp_socket_deliver()) already pulled 8 bytes for us.
|
||||
*/
|
||||
BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
|
||||
BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
|
||||
if (!pskb_may_pull(skb, offset + sizeof(*dh)))
|
||||
return -EINVAL;
|
||||
dh = (struct dccp_hdr *)(skb->data + offset);
|
||||
if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh)))
|
||||
return -EINVAL;
|
||||
iph = (struct iphdr *)skb->data;
|
||||
dh = (struct dccp_hdr *)(skb->data + offset);
|
||||
|
||||
sk = __inet_lookup_established(net, &dccp_hashinfo,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
|
|||
static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
u8 type, u8 code, int offset, __be32 info)
|
||||
{
|
||||
const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
|
||||
const struct ipv6hdr *hdr;
|
||||
const struct dccp_hdr *dh;
|
||||
struct dccp_sock *dp;
|
||||
struct ipv6_pinfo *np;
|
||||
|
|
@ -76,12 +76,12 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
|||
__u64 seq;
|
||||
struct net *net = dev_net(skb->dev);
|
||||
|
||||
/* Only need dccph_dport & dccph_sport which are the first
|
||||
* 4 bytes in dccp header.
|
||||
* Our caller (icmpv6_notify()) already pulled 8 bytes for us.
|
||||
*/
|
||||
BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
|
||||
BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
|
||||
if (!pskb_may_pull(skb, offset + sizeof(*dh)))
|
||||
return -EINVAL;
|
||||
dh = (struct dccp_hdr *)(skb->data + offset);
|
||||
if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh)))
|
||||
return -EINVAL;
|
||||
hdr = (const struct ipv6hdr *)skb->data;
|
||||
dh = (struct dccp_hdr *)(skb->data + offset);
|
||||
|
||||
sk = __inet6_lookup_established(net, &dccp_hashinfo,
|
||||
|
|
|
|||
|
|
@ -324,11 +324,15 @@ EXPORT_SYMBOL_GPL(dccp_disconnect);
|
|||
__poll_t dccp_poll(struct file *file, struct socket *sock,
|
||||
poll_table *wait)
|
||||
{
|
||||
__poll_t mask;
|
||||
struct sock *sk = sock->sk;
|
||||
__poll_t mask;
|
||||
u8 shutdown;
|
||||
int state;
|
||||
|
||||
sock_poll_wait(file, sock, wait);
|
||||
if (sk->sk_state == DCCP_LISTEN)
|
||||
|
||||
state = inet_sk_state_load(sk);
|
||||
if (state == DCCP_LISTEN)
|
||||
return inet_csk_listen_poll(sk);
|
||||
|
||||
/* Socket is not locked. We are protected from async events
|
||||
|
|
@ -337,20 +341,21 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,
|
|||
*/
|
||||
|
||||
mask = 0;
|
||||
if (sk->sk_err)
|
||||
if (READ_ONCE(sk->sk_err))
|
||||
mask = EPOLLERR;
|
||||
shutdown = READ_ONCE(sk->sk_shutdown);
|
||||
|
||||
if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
|
||||
if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED)
|
||||
mask |= EPOLLHUP;
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||
if (shutdown & RCV_SHUTDOWN)
|
||||
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
|
||||
|
||||
/* Connected? */
|
||||
if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
|
||||
if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
|
||||
if (atomic_read(&sk->sk_rmem_alloc) > 0)
|
||||
mask |= EPOLLIN | EPOLLRDNORM;
|
||||
|
||||
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
|
||||
if (!(shutdown & SEND_SHUTDOWN)) {
|
||||
if (sk_stream_is_writeable(sk)) {
|
||||
mask |= EPOLLOUT | EPOLLWRNORM;
|
||||
} else { /* send SIGIO later */
|
||||
|
|
@ -368,7 +373,6 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,
|
|||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(dccp_poll);
|
||||
|
||||
int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
||||
|
|
|
|||
|
|
@ -351,14 +351,14 @@ static void __inet_del_ifa(struct in_device *in_dev,
|
|||
{
|
||||
struct in_ifaddr *promote = NULL;
|
||||
struct in_ifaddr *ifa, *ifa1;
|
||||
struct in_ifaddr *last_prim;
|
||||
struct in_ifaddr __rcu **last_prim;
|
||||
struct in_ifaddr *prev_prom = NULL;
|
||||
int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
ifa1 = rtnl_dereference(*ifap);
|
||||
last_prim = rtnl_dereference(in_dev->ifa_list);
|
||||
last_prim = ifap;
|
||||
if (in_dev->dead)
|
||||
goto no_promotions;
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ static void __inet_del_ifa(struct in_device *in_dev,
|
|||
while ((ifa = rtnl_dereference(*ifap1)) != NULL) {
|
||||
if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
|
||||
ifa1->ifa_scope <= ifa->ifa_scope)
|
||||
last_prim = ifa;
|
||||
last_prim = &ifa->ifa_next;
|
||||
|
||||
if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
|
||||
ifa1->ifa_mask != ifa->ifa_mask ||
|
||||
|
|
@ -436,9 +436,9 @@ no_promotions:
|
|||
|
||||
rcu_assign_pointer(prev_prom->ifa_next, next_sec);
|
||||
|
||||
last_sec = rtnl_dereference(last_prim->ifa_next);
|
||||
last_sec = rtnl_dereference(*last_prim);
|
||||
rcu_assign_pointer(promote->ifa_next, last_sec);
|
||||
rcu_assign_pointer(last_prim->ifa_next, promote);
|
||||
rcu_assign_pointer(*last_prim, promote);
|
||||
}
|
||||
|
||||
promote->ifa_flags &= ~IFA_F_SECONDARY;
|
||||
|
|
|
|||
|
|
@ -567,7 +567,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb)
|
|||
skb->csum = csum_block_sub(skb->csum, csumdiff,
|
||||
skb->len - trimlen);
|
||||
}
|
||||
pskb_trim(skb, skb->len - trimlen);
|
||||
ret = pskb_trim(skb, skb->len - trimlen);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
ret = nexthdr[1];
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,8 @@ void fib_release_info(struct fib_info *fi)
|
|||
hlist_del(&nexthop_nh->nh_hash);
|
||||
} endfor_nexthops(fi)
|
||||
}
|
||||
fi->fib_dead = 1;
|
||||
/* Paired with READ_ONCE() from fib_table_lookup() */
|
||||
WRITE_ONCE(fi->fib_dead, 1);
|
||||
fib_info_put(fi);
|
||||
}
|
||||
spin_unlock_bh(&fib_info_lock);
|
||||
|
|
@ -1332,15 +1333,18 @@ __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
|
|||
unsigned char scope)
|
||||
{
|
||||
struct fib_nh *nh;
|
||||
__be32 saddr;
|
||||
|
||||
if (nhc->nhc_family != AF_INET)
|
||||
return inet_select_addr(nhc->nhc_dev, 0, scope);
|
||||
|
||||
nh = container_of(nhc, struct fib_nh, nh_common);
|
||||
nh->nh_saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope);
|
||||
nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
|
||||
saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope);
|
||||
|
||||
return nh->nh_saddr;
|
||||
WRITE_ONCE(nh->nh_saddr, saddr);
|
||||
WRITE_ONCE(nh->nh_saddr_genid, atomic_read(&net->ipv4.dev_addr_genid));
|
||||
|
||||
return saddr;
|
||||
}
|
||||
|
||||
__be32 fib_result_prefsrc(struct net *net, struct fib_result *res)
|
||||
|
|
@ -1354,8 +1358,9 @@ __be32 fib_result_prefsrc(struct net *net, struct fib_result *res)
|
|||
struct fib_nh *nh;
|
||||
|
||||
nh = container_of(nhc, struct fib_nh, nh_common);
|
||||
if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid))
|
||||
return nh->nh_saddr;
|
||||
if (READ_ONCE(nh->nh_saddr_genid) ==
|
||||
atomic_read(&net->ipv4.dev_addr_genid))
|
||||
return READ_ONCE(nh->nh_saddr);
|
||||
}
|
||||
|
||||
return fib_info_update_nhc_saddr(net, nhc, res->fi->fib_scope);
|
||||
|
|
@ -1586,6 +1591,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
|
|||
link_it:
|
||||
ofi = fib_find_info(fi);
|
||||
if (ofi) {
|
||||
/* fib_table_lookup() should not see @fi yet. */
|
||||
fi->fib_dead = 1;
|
||||
free_fib_info(fi);
|
||||
ofi->fib_treeref++;
|
||||
|
|
@ -1623,6 +1629,7 @@ err_inval:
|
|||
|
||||
failure:
|
||||
if (fi) {
|
||||
/* fib_table_lookup() should not see @fi yet. */
|
||||
fi->fib_dead = 1;
|
||||
free_fib_info(fi);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,8 @@ found:
|
|||
}
|
||||
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
|
||||
continue;
|
||||
if (fi->fib_dead)
|
||||
/* Paired with WRITE_ONCE() in fib_release_info() */
|
||||
if (READ_ONCE(fi->fib_dead))
|
||||
continue;
|
||||
if (fa->fa_info->fib_scope < flp->flowi4_scope)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -355,8 +355,9 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
|
|||
struct flowi4 fl4;
|
||||
int hlen = LL_RESERVED_SPACE(dev);
|
||||
int tlen = dev->needed_tailroom;
|
||||
unsigned int size = mtu;
|
||||
unsigned int size;
|
||||
|
||||
size = min(mtu, IP_MAX_MTU);
|
||||
while (1) {
|
||||
skb = alloc_skb(size + hlen + tlen,
|
||||
GFP_ATOMIC | __GFP_NOWARN);
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
|
|||
if (lwtunnel_xmit_redirect(dst->lwtstate)) {
|
||||
int res = lwtunnel_xmit(skb);
|
||||
|
||||
if (res < 0 || res == LWTUNNEL_XMIT_DONE)
|
||||
if (res != LWTUNNEL_XMIT_CONTINUE)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -314,12 +314,12 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
break;
|
||||
default:
|
||||
goto tx_err;
|
||||
|
|
|
|||
|
|
@ -179,6 +179,19 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
|
|||
if (unlikely(len > icsk->icsk_ack.rcv_mss +
|
||||
MAX_TCP_OPTION_SPACE))
|
||||
tcp_gro_dev_warn(sk, skb, len);
|
||||
/* If the skb has a len of exactly 1*MSS and has the PSH bit
|
||||
* set then it is likely the end of an application write. So
|
||||
* more data may not be arriving soon, and yet the data sender
|
||||
* may be waiting for an ACK if cwnd-bound or using TX zero
|
||||
* copy. So we set ICSK_ACK_PUSHED here so that
|
||||
* tcp_cleanup_rbuf() will send an ACK immediately if the app
|
||||
* reads all of the data and is not ping-pong. If len > MSS
|
||||
* then this logic does not matter (and does not hurt) because
|
||||
* tcp_cleanup_rbuf() will always ACK immediately if the app
|
||||
* reads data and there is more than an MSS of unACKed data.
|
||||
*/
|
||||
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH)
|
||||
icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
|
||||
} else {
|
||||
/* Otherwise, we make more careful check taking into account,
|
||||
* that SACKs block is variable.
|
||||
|
|
@ -231,7 +244,6 @@ void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
|
|||
inet_csk_exit_pingpong_mode(sk);
|
||||
icsk->icsk_ack.ato = TCP_ATO_MIN;
|
||||
}
|
||||
EXPORT_SYMBOL(tcp_enter_quickack_mode);
|
||||
|
||||
/* Send ACKs quickly, if "quick" count is not exhausted
|
||||
* and the session is not interactive.
|
||||
|
|
|
|||
|
|
@ -179,8 +179,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
|
|||
}
|
||||
|
||||
/* Account for an ACK we sent. */
|
||||
static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
|
||||
u32 rcv_nxt)
|
||||
static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
|
|
@ -194,7 +193,7 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
|
|||
|
||||
if (unlikely(rcv_nxt != tp->rcv_nxt))
|
||||
return; /* Special ACK sent by DCTCP to reflect ECN */
|
||||
tcp_dec_quickack_mode(sk, pkts);
|
||||
tcp_dec_quickack_mode(sk);
|
||||
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
|
||||
}
|
||||
|
||||
|
|
@ -1152,7 +1151,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
|
|||
icsk->icsk_af_ops->send_check(sk, skb);
|
||||
|
||||
if (likely(tcb->tcp_flags & TCPHDR_ACK))
|
||||
tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt);
|
||||
tcp_event_ack_sent(sk, rcv_nxt);
|
||||
|
||||
if (skb->len != tcp_header_size) {
|
||||
tcp_event_data_sent(tp, sk);
|
||||
|
|
@ -2263,6 +2262,18 @@ static bool tcp_pacing_check(struct sock *sk)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool tcp_rtx_queue_empty_or_single_skb(const struct sock *sk)
|
||||
{
|
||||
const struct rb_node *node = sk->tcp_rtx_queue.rb_node;
|
||||
|
||||
/* No skb in the rtx queue. */
|
||||
if (!node)
|
||||
return true;
|
||||
|
||||
/* Only one skb in rtx queue. */
|
||||
return !node->rb_left && !node->rb_right;
|
||||
}
|
||||
|
||||
/* TCP Small Queues :
|
||||
* Control number of packets in qdisc/devices to two packets / or ~1 ms.
|
||||
* (These limits are doubled for retransmits)
|
||||
|
|
@ -2300,12 +2311,12 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb,
|
|||
limit += extra_bytes;
|
||||
}
|
||||
if (refcount_read(&sk->sk_wmem_alloc) > limit) {
|
||||
/* Always send skb if rtx queue is empty.
|
||||
/* Always send skb if rtx queue is empty or has one skb.
|
||||
* No need to wait for TX completion to call us back,
|
||||
* after softirq/tasklet schedule.
|
||||
* This helps when TX completions are delayed too much.
|
||||
*/
|
||||
if (tcp_rtx_queue_empty(sk))
|
||||
if (tcp_rtx_queue_empty_or_single_skb(sk))
|
||||
return false;
|
||||
|
||||
set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags);
|
||||
|
|
@ -2508,7 +2519,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto)
|
|||
{
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
u32 timeout, rto_delta_us;
|
||||
u32 timeout, timeout_us, rto_delta_us;
|
||||
int early_retrans;
|
||||
|
||||
/* Don't do any loss probe on a Fast Open connection before 3WHS
|
||||
|
|
@ -2532,11 +2543,12 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto)
|
|||
* sample is available then probe after TCP_TIMEOUT_INIT.
|
||||
*/
|
||||
if (tp->srtt_us) {
|
||||
timeout = usecs_to_jiffies(tp->srtt_us >> 2);
|
||||
timeout_us = tp->srtt_us >> 2;
|
||||
if (tp->packets_out == 1)
|
||||
timeout += TCP_RTO_MIN;
|
||||
timeout_us += tcp_rto_min_us(sk);
|
||||
else
|
||||
timeout += TCP_TIMEOUT_MIN;
|
||||
timeout_us += TCP_TIMEOUT_MIN_US;
|
||||
timeout = usecs_to_jiffies(timeout_us);
|
||||
} else {
|
||||
timeout = TCP_TIMEOUT_INIT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ bool tcp_rack_mark_lost(struct sock *sk)
|
|||
tp->rack.advanced = 0;
|
||||
tcp_rack_detect_loss(sk, &timeout);
|
||||
if (timeout) {
|
||||
timeout = usecs_to_jiffies(timeout) + TCP_TIMEOUT_MIN;
|
||||
timeout = usecs_to_jiffies(timeout + TCP_TIMEOUT_MIN_US);
|
||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT,
|
||||
timeout, inet_csk(sk)->icsk_rto);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -605,7 +605,9 @@ out_reset_timer:
|
|||
tcp_stream_is_thin(tp) &&
|
||||
icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) {
|
||||
icsk->icsk_backoff = 0;
|
||||
icsk->icsk_rto = min(__tcp_set_rto(tp), TCP_RTO_MAX);
|
||||
icsk->icsk_rto = clamp(__tcp_set_rto(tp),
|
||||
tcp_rto_min(sk),
|
||||
TCP_RTO_MAX);
|
||||
} else {
|
||||
/* Use normal (exponential) backoff */
|
||||
icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
|
||||
|
|
|
|||
|
|
@ -1369,7 +1369,7 @@ retry:
|
|||
* idev->desync_factor if it's larger
|
||||
*/
|
||||
cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft);
|
||||
max_desync_factor = min_t(__u32,
|
||||
max_desync_factor = min_t(long,
|
||||
idev->cnf.max_desync_factor,
|
||||
cnf_temp_preferred_lft - regen_advance);
|
||||
|
||||
|
|
|
|||
|
|
@ -506,7 +506,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb)
|
|||
skb->csum = csum_block_sub(skb->csum, csumdiff,
|
||||
skb->len - trimlen);
|
||||
}
|
||||
pskb_trim(skb, skb->len - trimlen);
|
||||
ret = pskb_trim(skb, skb->len - trimlen);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
ret = nexthdr[1];
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
|
|||
if (lwtunnel_xmit_redirect(dst->lwtstate)) {
|
||||
int res = lwtunnel_xmit(skb);
|
||||
|
||||
if (res < 0 || res == LWTUNNEL_XMIT_DONE)
|
||||
if (res != LWTUNNEL_XMIT_CONTINUE)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -558,12 +558,12 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
vti6_addr_conflict(t, ipv6_hdr(skb)))
|
||||
goto tx_err;
|
||||
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
break;
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
break;
|
||||
default:
|
||||
goto tx_err;
|
||||
|
|
|
|||
|
|
@ -120,11 +120,11 @@ static void xfrm6_dst_destroy(struct dst_entry *dst)
|
|||
{
|
||||
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
||||
|
||||
if (likely(xdst->u.rt6.rt6i_idev))
|
||||
in6_dev_put(xdst->u.rt6.rt6i_idev);
|
||||
dst_destroy_metrics_generic(dst);
|
||||
if (xdst->u.rt6.rt6i_uncached_list)
|
||||
rt6_uncached_list_del(&xdst->u.rt6);
|
||||
if (likely(xdst->u.rt6.rt6i_idev))
|
||||
in6_dev_put(xdst->u.rt6.rt6i_idev);
|
||||
xfrm_dst_destroy(xdst);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1066,15 +1066,18 @@ partial_message:
|
|||
out_error:
|
||||
kcm_push(kcm);
|
||||
|
||||
if (copied && sock->type == SOCK_SEQPACKET) {
|
||||
if (sock->type == SOCK_SEQPACKET) {
|
||||
/* Wrote some bytes before encountering an
|
||||
* error, return partial success.
|
||||
*/
|
||||
goto partial_message;
|
||||
}
|
||||
|
||||
if (head != kcm->seq_skb)
|
||||
if (copied)
|
||||
goto partial_message;
|
||||
if (head != kcm->seq_skb)
|
||||
kfree_skb(head);
|
||||
} else {
|
||||
kfree_skb(head);
|
||||
kcm->seq_skb = NULL;
|
||||
}
|
||||
|
||||
err = sk_stream_error(sk, msg->msg_flags, err);
|
||||
|
||||
|
|
@ -1984,6 +1987,8 @@ static __net_exit void kcm_exit_net(struct net *net)
|
|||
* that all multiplexors and psocks have been destroyed.
|
||||
*/
|
||||
WARN_ON(!list_empty(&knet->mux_list));
|
||||
|
||||
mutex_destroy(&knet->mutex);
|
||||
}
|
||||
|
||||
static struct pernet_operations kcm_net_ops = {
|
||||
|
|
|
|||
|
|
@ -1852,9 +1852,9 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms
|
|||
if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
|
||||
struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
|
||||
|
||||
if ((xfilter->sadb_x_filter_splen >=
|
||||
if ((xfilter->sadb_x_filter_splen >
|
||||
(sizeof(xfrm_address_t) << 3)) ||
|
||||
(xfilter->sadb_x_filter_dplen >=
|
||||
(xfilter->sadb_x_filter_dplen >
|
||||
(sizeof(xfrm_address_t) << 3))) {
|
||||
mutex_unlock(&pfk->dump_lock);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -521,7 +521,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
*/
|
||||
if (len > INT_MAX - transhdrlen)
|
||||
return -EMSGSIZE;
|
||||
ulen = len + transhdrlen;
|
||||
|
||||
/* Mirror BSD error message compatibility */
|
||||
if (msg->msg_flags & MSG_OOB)
|
||||
|
|
@ -645,6 +644,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
|
||||
back_from_confirm:
|
||||
lock_sock(sk);
|
||||
ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0;
|
||||
err = ip6_append_data(sk, ip_generic_getfrag, msg,
|
||||
ulen, transhdrlen, &ipc6,
|
||||
&fl6, (struct rt6_info *)dst,
|
||||
|
|
|
|||
|
|
@ -651,7 +651,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
|
|||
}
|
||||
|
||||
if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED &&
|
||||
!ieee80211_is_deauth(hdr->frame_control)))
|
||||
!ieee80211_is_deauth(hdr->frame_control)) &&
|
||||
tx->skb->protocol != tx->sdata->control_port_protocol)
|
||||
return TX_DROP;
|
||||
|
||||
if (!skip_hw && tx->key &&
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
|
|||
if ((had_link == has_link) || chained)
|
||||
return 0;
|
||||
|
||||
if (had_link)
|
||||
netif_carrier_off(ndp->ndev.dev);
|
||||
else
|
||||
netif_carrier_on(ndp->ndev.dev);
|
||||
|
||||
if (!ndp->multi_package && !nc->package->multi_channel) {
|
||||
if (had_link) {
|
||||
ndp->flags |= NCSI_DEV_RESHUFFLE;
|
||||
|
|
|
|||
|
|
@ -770,9 +770,6 @@ static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Set the flag for GMA command which should only be called once */
|
||||
nca->ndp->gma_flag = 1;
|
||||
|
||||
/* Get Mac address from NCSI device */
|
||||
return nch->handler(nca);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -627,6 +627,9 @@ static int ncsi_rsp_handler_oem_mlx_gma(struct ncsi_request *nr)
|
|||
saddr.sa_family = ndev->type;
|
||||
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||
memcpy(saddr.sa_data, &rsp->data[MLX_MAC_ADDR_OFFSET], ETH_ALEN);
|
||||
/* Set the flag for GMA command which should only be called once */
|
||||
ndp->gma_flag = 1;
|
||||
|
||||
ret = ops->ndo_set_mac_address(ndev, &saddr);
|
||||
if (ret < 0)
|
||||
netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
|
||||
|
|
@ -671,6 +674,9 @@ static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
|
|||
if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
|
||||
return -ENXIO;
|
||||
|
||||
/* Set the flag for GMA command which should only be called once */
|
||||
ndp->gma_flag = 1;
|
||||
|
||||
ret = ops->ndo_set_mac_address(ndev, &saddr);
|
||||
if (ret < 0)
|
||||
netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
|
||||
|
|
|
|||
|
|
@ -1759,6 +1759,7 @@ static int
|
|||
proc_do_sync_threshold(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct netns_ipvs *ipvs = table->extra2;
|
||||
int *valp = table->data;
|
||||
int val[2];
|
||||
int rc;
|
||||
|
|
@ -1768,6 +1769,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
|
|||
.mode = table->mode,
|
||||
};
|
||||
|
||||
mutex_lock(&ipvs->sync_mutex);
|
||||
memcpy(val, valp, sizeof(val));
|
||||
rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
|
||||
if (write) {
|
||||
|
|
@ -1777,6 +1779,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
|
|||
else
|
||||
memcpy(valp, val, sizeof(val));
|
||||
}
|
||||
mutex_unlock(&ipvs->sync_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -4034,6 +4037,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
|
|||
ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
|
||||
ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
|
||||
tbl[idx].data = &ipvs->sysctl_sync_threshold;
|
||||
tbl[idx].extra2 = ipvs;
|
||||
tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
|
||||
ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
|
||||
tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
|
||||
|
|
|
|||
|
|
@ -1444,7 +1444,7 @@ static int bind_mcastif_addr(struct socket *sock, struct net_device *dev)
|
|||
sin.sin_addr.s_addr = addr;
|
||||
sin.sin_port = 0;
|
||||
|
||||
return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin));
|
||||
return kernel_bind(sock, (struct sockaddr *)&sin, sizeof(sin));
|
||||
}
|
||||
|
||||
static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen,
|
||||
|
|
@ -1510,8 +1510,8 @@ static int make_send_sock(struct netns_ipvs *ipvs, int id,
|
|||
}
|
||||
|
||||
get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id);
|
||||
result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr,
|
||||
salen, 0);
|
||||
result = kernel_connect(sock, (struct sockaddr *)&mcast_addr,
|
||||
salen, 0);
|
||||
if (result < 0) {
|
||||
pr_err("Error connecting to the multicast addr\n");
|
||||
goto error;
|
||||
|
|
@ -1551,7 +1551,7 @@ static int make_receive_sock(struct netns_ipvs *ipvs, int id,
|
|||
|
||||
get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
|
||||
sock->sk->sk_bound_dev_if = dev->ifindex;
|
||||
result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
|
||||
result = kernel_bind(sock, (struct sockaddr *)&mcast_addr, salen);
|
||||
if (result < 0) {
|
||||
pr_err("Error binding to the multicast addr\n");
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
|
|||
[SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
|
||||
[SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
|
||||
[SCTP_CONNTRACK_ESTABLISHED] = 210 SECS,
|
||||
[SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
|
||||
[SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
|
||||
[SCTP_CONNTRACK_SHUTDOWN_SENT] = 3 SECS,
|
||||
[SCTP_CONNTRACK_SHUTDOWN_RECD] = 3 SECS,
|
||||
[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
|
||||
[SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS,
|
||||
};
|
||||
|
|
@ -103,7 +103,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
|
|||
{
|
||||
/* ORIGINAL */
|
||||
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
|
||||
/* init */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW},
|
||||
/* init */ {sCL, sCL, sCW, sCE, sES, sCL, sCL, sSA, sCW},
|
||||
/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},
|
||||
/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
|
||||
/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL},
|
||||
|
|
|
|||
|
|
@ -26,12 +26,15 @@
|
|||
#define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
|
||||
|
||||
unsigned int nf_tables_net_id __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(nf_tables_net_id);
|
||||
|
||||
static LIST_HEAD(nf_tables_expressions);
|
||||
static LIST_HEAD(nf_tables_objects);
|
||||
static LIST_HEAD(nf_tables_flowtables);
|
||||
static LIST_HEAD(nf_tables_destroy_list);
|
||||
static LIST_HEAD(nf_tables_gc_list);
|
||||
static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
|
||||
static DEFINE_SPINLOCK(nf_tables_gc_list_lock);
|
||||
static u64 table_handle;
|
||||
|
||||
enum {
|
||||
|
|
@ -88,6 +91,9 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state)
|
|||
static void nf_tables_trans_destroy_work(struct work_struct *w);
|
||||
static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
|
||||
|
||||
static void nft_trans_gc_work(struct work_struct *work);
|
||||
static DECLARE_WORK(trans_gc_work, nft_trans_gc_work);
|
||||
|
||||
static void nft_ctx_init(struct nft_ctx *ctx,
|
||||
struct net *net,
|
||||
const struct sk_buff *skb,
|
||||
|
|
@ -403,6 +409,27 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
nft_setelem_data_deactivate(ctx->net, set, elem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
struct nft_set_iter iter = {
|
||||
.genmask = nft_genmask_next(ctx->net),
|
||||
.fn = nft_mapelem_deactivate,
|
||||
};
|
||||
|
||||
set->ops->walk(ctx, set, &iter);
|
||||
WARN_ON_ONCE(iter.err);
|
||||
}
|
||||
|
||||
static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -411,6 +438,9 @@ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
nft_use_dec(&ctx->table->use);
|
||||
|
||||
|
|
@ -1047,8 +1077,7 @@ static int nft_flush_table(struct nft_ctx *ctx)
|
|||
if (!nft_is_active_next(ctx->net, set))
|
||||
continue;
|
||||
|
||||
if (nft_set_is_anonymous(set) &&
|
||||
!list_empty(&set->bindings))
|
||||
if (nft_set_is_anonymous(set))
|
||||
continue;
|
||||
|
||||
err = nft_delset(ctx, set);
|
||||
|
|
@ -3811,6 +3840,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|||
}
|
||||
|
||||
INIT_LIST_HEAD(&set->bindings);
|
||||
refcount_set(&set->refs, 1);
|
||||
set->table = table;
|
||||
write_pnet(&set->net, net);
|
||||
set->ops = ops;
|
||||
|
|
@ -3841,7 +3871,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|||
return 0;
|
||||
|
||||
err4:
|
||||
ops->destroy(set);
|
||||
ops->destroy(&ctx, set);
|
||||
err3:
|
||||
kfree(set->name);
|
||||
err2:
|
||||
|
|
@ -3853,15 +3883,22 @@ err1:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void nft_set_destroy(struct nft_set *set)
|
||||
static void nft_set_put(struct nft_set *set)
|
||||
{
|
||||
if (refcount_dec_and_test(&set->refs)) {
|
||||
kfree(set->name);
|
||||
kvfree(set);
|
||||
}
|
||||
}
|
||||
|
||||
static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
if (WARN_ON(set->use > 0))
|
||||
return;
|
||||
|
||||
set->ops->destroy(set);
|
||||
set->ops->destroy(ctx, set);
|
||||
module_put(to_set_type(set->ops)->owner);
|
||||
kfree(set->name);
|
||||
kvfree(set);
|
||||
nft_set_put(set);
|
||||
}
|
||||
|
||||
static int nf_tables_delset(struct net *net, struct sock *nlsk,
|
||||
|
|
@ -3982,10 +4019,39 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|||
}
|
||||
}
|
||||
|
||||
static void nft_setelem_data_activate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem);
|
||||
|
||||
static int nft_mapelem_activate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
nft_setelem_data_activate(ctx->net, set, elem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
struct nft_set_iter iter = {
|
||||
.genmask = nft_genmask_next(ctx->net),
|
||||
.fn = nft_mapelem_activate,
|
||||
};
|
||||
|
||||
set->ops->walk(ctx, set, &iter);
|
||||
WARN_ON_ONCE(iter.err);
|
||||
}
|
||||
|
||||
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
if (nft_set_is_anonymous(set))
|
||||
if (nft_set_is_anonymous(set)) {
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_activate(ctx, set);
|
||||
|
||||
nft_clear(ctx->net, set);
|
||||
}
|
||||
|
||||
nft_use_inc_restore(&set->use);
|
||||
}
|
||||
|
|
@ -4006,13 +4072,20 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|||
nft_use_dec(&set->use);
|
||||
break;
|
||||
case NFT_TRANS_PREPARE:
|
||||
if (nft_set_is_anonymous(set))
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
if (nft_set_is_anonymous(set)) {
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
}
|
||||
nft_use_dec(&set->use);
|
||||
return;
|
||||
case NFT_TRANS_ABORT:
|
||||
case NFT_TRANS_RELEASE:
|
||||
if (nft_set_is_anonymous(set) &&
|
||||
set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
nft_use_dec(&set->use);
|
||||
/* fall through */
|
||||
default:
|
||||
|
|
@ -4025,7 +4098,7 @@ EXPORT_SYMBOL_GPL(nf_tables_deactivate_set);
|
|||
void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
if (list_empty(&set->bindings) && nft_set_is_anonymous(set))
|
||||
nft_set_destroy(set);
|
||||
nft_set_destroy(ctx, set);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_tables_destroy_set);
|
||||
|
||||
|
|
@ -4195,8 +4268,12 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
|
|||
const struct nft_set_iter *iter,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
|
||||
struct nft_set_dump_args *args;
|
||||
|
||||
if (nft_set_elem_expired(ext))
|
||||
return 0;
|
||||
|
||||
args = container_of(iter, struct nft_set_dump_args, iter);
|
||||
return nf_tables_fill_setelem(args->skb, set, elem);
|
||||
}
|
||||
|
|
@ -4575,6 +4652,7 @@ void *nft_set_elem_init(const struct nft_set *set,
|
|||
return elem;
|
||||
}
|
||||
|
||||
/* Drop references and destroy. Called from gc, dynset and abort path. */
|
||||
void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
||||
bool destroy_expr)
|
||||
{
|
||||
|
|
@ -4603,11 +4681,11 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
|
||||
|
||||
/* Only called from commit path, nft_set_elem_deactivate() already deals with
|
||||
* the refcounting from the preparation phase.
|
||||
/* Destroy element. References have been already dropped in the preparation
|
||||
* path via nft_setelem_data_deactivate().
|
||||
*/
|
||||
static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set, void *elem)
|
||||
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set, void *elem)
|
||||
{
|
||||
struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
|
||||
|
||||
|
|
@ -4615,6 +4693,7 @@ static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
|||
nf_tables_expr_destroy(ctx, nft_set_ext_expr(ext));
|
||||
kfree(elem);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_tables_set_elem_destroy);
|
||||
|
||||
static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
const struct nlattr *attr, u32 nlmsg_flags)
|
||||
|
|
@ -4800,7 +4879,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
|||
if (trans == NULL)
|
||||
goto err4;
|
||||
|
||||
ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
|
||||
ext->genmask = nft_genmask_cur(ctx->net);
|
||||
|
||||
err = set->ops->insert(ctx->net, set, &elem, &ext2);
|
||||
if (err) {
|
||||
if (err == -EEXIST) {
|
||||
|
|
@ -4920,9 +5000,9 @@ void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
|
|||
}
|
||||
}
|
||||
|
||||
static void nft_set_elem_activate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem)
|
||||
static void nft_setelem_data_activate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
|
||||
|
||||
|
|
@ -4932,9 +5012,9 @@ static void nft_set_elem_activate(const struct net *net,
|
|||
nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
|
||||
}
|
||||
|
||||
static void nft_set_elem_deactivate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem)
|
||||
void nft_setelem_data_deactivate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
|
||||
|
||||
|
|
@ -4943,6 +5023,7 @@ static void nft_set_elem_deactivate(const struct net *net,
|
|||
if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
|
||||
nft_use_dec(&(*nft_set_ext_obj(ext))->use);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_setelem_data_deactivate);
|
||||
|
||||
static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
const struct nlattr *attr)
|
||||
|
|
@ -5001,7 +5082,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
|||
kfree(elem.priv);
|
||||
elem.priv = priv;
|
||||
|
||||
nft_set_elem_deactivate(ctx->net, set, &elem);
|
||||
nft_setelem_data_deactivate(ctx->net, set, &elem);
|
||||
|
||||
nft_trans_elem(trans) = elem;
|
||||
nft_trans_commit_list_add_tail(ctx->net, trans);
|
||||
|
|
@ -5035,7 +5116,7 @@ static int nft_flush_set(const struct nft_ctx *ctx,
|
|||
}
|
||||
set->ndeact++;
|
||||
|
||||
nft_set_elem_deactivate(ctx->net, set, elem);
|
||||
nft_setelem_data_deactivate(ctx->net, set, elem);
|
||||
nft_trans_elem_set(trans) = set;
|
||||
nft_trans_elem(trans) = *elem;
|
||||
nft_trans_commit_list_add_tail(ctx->net, trans);
|
||||
|
|
@ -5066,8 +5147,10 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
|
|||
if (IS_ERR(set))
|
||||
return PTR_ERR(set);
|
||||
|
||||
if (!list_empty(&set->bindings) &&
|
||||
(set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS)))
|
||||
if (nft_set_is_anonymous(set))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT))
|
||||
return -EBUSY;
|
||||
|
||||
if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
|
||||
|
|
@ -5090,31 +5173,6 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
|
|||
return err;
|
||||
}
|
||||
|
||||
void nft_set_gc_batch_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct nft_set_gc_batch *gcb;
|
||||
unsigned int i;
|
||||
|
||||
gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
|
||||
for (i = 0; i < gcb->head.cnt; i++)
|
||||
nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
|
||||
kfree(gcb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
|
||||
|
||||
struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct nft_set_gc_batch *gcb;
|
||||
|
||||
gcb = kzalloc(sizeof(*gcb), gfp);
|
||||
if (gcb == NULL)
|
||||
return gcb;
|
||||
gcb->head.set = set;
|
||||
return gcb;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
|
||||
|
||||
/*
|
||||
* Stateful objects
|
||||
*/
|
||||
|
|
@ -6712,7 +6770,7 @@ static void nft_commit_release(struct nft_trans *trans)
|
|||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
break;
|
||||
case NFT_MSG_DELSET:
|
||||
nft_set_destroy(nft_trans_set(trans));
|
||||
nft_set_destroy(&trans->ctx, nft_trans_set(trans));
|
||||
break;
|
||||
case NFT_MSG_DELSETELEM:
|
||||
nf_tables_set_elem_destroy(&trans->ctx,
|
||||
|
|
@ -6891,6 +6949,186 @@ static void nft_chain_del(struct nft_chain *chain)
|
|||
list_del_rcu(&chain->list);
|
||||
}
|
||||
|
||||
static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx,
|
||||
struct nft_trans_gc *trans)
|
||||
{
|
||||
void **priv = trans->priv;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < trans->count; i++) {
|
||||
struct nft_set_elem elem = {
|
||||
.priv = priv[i],
|
||||
};
|
||||
|
||||
nft_setelem_data_deactivate(ctx->net, trans->set, &elem);
|
||||
trans->set->ops->remove(trans->net, trans->set, &elem);
|
||||
}
|
||||
}
|
||||
|
||||
void nft_trans_gc_destroy(struct nft_trans_gc *trans)
|
||||
{
|
||||
nft_set_put(trans->set);
|
||||
put_net(trans->net);
|
||||
kfree(trans);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_destroy);
|
||||
|
||||
static void nft_trans_gc_trans_free(struct rcu_head *rcu)
|
||||
{
|
||||
struct nft_set_elem elem = {};
|
||||
struct nft_trans_gc *trans;
|
||||
struct nft_ctx ctx = {};
|
||||
unsigned int i;
|
||||
|
||||
trans = container_of(rcu, struct nft_trans_gc, rcu);
|
||||
ctx.net = read_pnet(&trans->set->net);
|
||||
|
||||
for (i = 0; i < trans->count; i++) {
|
||||
elem.priv = trans->priv[i];
|
||||
atomic_dec(&trans->set->nelems);
|
||||
|
||||
nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv);
|
||||
}
|
||||
|
||||
nft_trans_gc_destroy(trans);
|
||||
}
|
||||
|
||||
static bool nft_trans_gc_work_done(struct nft_trans_gc *trans)
|
||||
{
|
||||
struct nftables_pernet *nft_net;
|
||||
struct nft_ctx ctx = {};
|
||||
|
||||
nft_net = net_generic(trans->net, nf_tables_net_id);
|
||||
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
|
||||
/* Check for race with transaction, otherwise this batch refers to
|
||||
* stale objects that might not be there anymore. Skip transaction if
|
||||
* set has been destroyed from control plane transaction in case gc
|
||||
* worker loses race.
|
||||
*/
|
||||
if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) {
|
||||
mutex_unlock(&nft_net->commit_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx.net = trans->net;
|
||||
ctx.table = trans->set->table;
|
||||
|
||||
nft_trans_gc_setelem_remove(&ctx, trans);
|
||||
mutex_unlock(&nft_net->commit_mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nft_trans_gc_work(struct work_struct *work)
|
||||
{
|
||||
struct nft_trans_gc *trans, *next;
|
||||
LIST_HEAD(trans_gc_list);
|
||||
|
||||
spin_lock(&nf_tables_destroy_list_lock);
|
||||
list_splice_init(&nf_tables_gc_list, &trans_gc_list);
|
||||
spin_unlock(&nf_tables_destroy_list_lock);
|
||||
|
||||
list_for_each_entry_safe(trans, next, &trans_gc_list, list) {
|
||||
list_del(&trans->list);
|
||||
if (!nft_trans_gc_work_done(trans)) {
|
||||
nft_trans_gc_destroy(trans);
|
||||
continue;
|
||||
}
|
||||
call_rcu(&trans->rcu, nft_trans_gc_trans_free);
|
||||
}
|
||||
}
|
||||
|
||||
struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
|
||||
unsigned int gc_seq, gfp_t gfp)
|
||||
{
|
||||
struct net *net = read_pnet(&set->net);
|
||||
struct nft_trans_gc *trans;
|
||||
|
||||
trans = kzalloc(sizeof(*trans), gfp);
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
refcount_inc(&set->refs);
|
||||
trans->set = set;
|
||||
trans->net = get_net(net);
|
||||
trans->seq = gc_seq;
|
||||
|
||||
return trans;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_alloc);
|
||||
|
||||
void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv)
|
||||
{
|
||||
trans->priv[trans->count++] = priv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_elem_add);
|
||||
|
||||
static void nft_trans_gc_queue_work(struct nft_trans_gc *trans)
|
||||
{
|
||||
spin_lock(&nf_tables_gc_list_lock);
|
||||
list_add_tail(&trans->list, &nf_tables_gc_list);
|
||||
spin_unlock(&nf_tables_gc_list_lock);
|
||||
|
||||
schedule_work(&trans_gc_work);
|
||||
}
|
||||
|
||||
static int nft_trans_gc_space(struct nft_trans_gc *trans)
|
||||
{
|
||||
return NFT_TRANS_GC_BATCHCOUNT - trans->count;
|
||||
}
|
||||
|
||||
struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
|
||||
unsigned int gc_seq, gfp_t gfp)
|
||||
{
|
||||
if (nft_trans_gc_space(gc))
|
||||
return gc;
|
||||
|
||||
nft_trans_gc_queue_work(gc);
|
||||
|
||||
return nft_trans_gc_alloc(gc->set, gc_seq, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_async);
|
||||
|
||||
void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans)
|
||||
{
|
||||
if (trans->count == 0) {
|
||||
nft_trans_gc_destroy(trans);
|
||||
return;
|
||||
}
|
||||
|
||||
nft_trans_gc_queue_work(trans);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_async_done);
|
||||
|
||||
struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
|
||||
{
|
||||
if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
|
||||
return NULL;
|
||||
|
||||
if (nft_trans_gc_space(gc))
|
||||
return gc;
|
||||
|
||||
call_rcu(&gc->rcu, nft_trans_gc_trans_free);
|
||||
|
||||
return nft_trans_gc_alloc(gc->set, 0, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_sync);
|
||||
|
||||
void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans)
|
||||
{
|
||||
WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net));
|
||||
|
||||
if (trans->count == 0) {
|
||||
nft_trans_gc_destroy(trans);
|
||||
return;
|
||||
}
|
||||
|
||||
call_rcu(&trans->rcu, nft_trans_gc_trans_free);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_sync_done);
|
||||
|
||||
static void nf_tables_module_autoload_cleanup(struct net *net)
|
||||
{
|
||||
struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
|
||||
|
|
@ -6945,6 +7183,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
struct nft_trans_elem *te;
|
||||
struct nft_chain *chain;
|
||||
struct nft_table *table;
|
||||
unsigned int gc_seq;
|
||||
int err;
|
||||
|
||||
if (list_empty(&nft_net->commit_list)) {
|
||||
|
|
@ -7001,6 +7240,10 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
while (++nft_net->base_seq == 0)
|
||||
;
|
||||
|
||||
/* Bump gc counter, it becomes odd, this is the busy mark. */
|
||||
gc_seq = READ_ONCE(nft_net->gc_seq);
|
||||
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
|
||||
|
||||
/* step 3. Start new generation, rules_gen_X now in use. */
|
||||
net->nft.gencursor = nft_gencursor_next(net);
|
||||
|
||||
|
|
@ -7078,6 +7321,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_DELSET:
|
||||
nft_trans_set(trans)->dead = 1;
|
||||
list_del_rcu(&nft_trans_set(trans)->list);
|
||||
nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
|
||||
NFT_MSG_DELSET, GFP_KERNEL);
|
||||
|
|
@ -7139,6 +7383,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
|
||||
|
||||
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
|
||||
nf_tables_commit_release(net);
|
||||
|
||||
return 0;
|
||||
|
|
@ -7173,7 +7419,7 @@ static void nf_tables_abort_release(struct nft_trans *trans)
|
|||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
break;
|
||||
case NFT_MSG_NEWSET:
|
||||
nft_set_destroy(nft_trans_set(trans));
|
||||
nft_set_destroy(&trans->ctx, nft_trans_set(trans));
|
||||
break;
|
||||
case NFT_MSG_NEWSETELEM:
|
||||
nft_set_elem_destroy(nft_trans_elem_set(trans),
|
||||
|
|
@ -7260,6 +7506,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
|||
case NFT_MSG_DELSET:
|
||||
nft_use_inc_restore(&trans->ctx.table->use);
|
||||
nft_clear(trans->ctx.net, nft_trans_set(trans));
|
||||
if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_activate(&trans->ctx, nft_trans_set(trans));
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_NEWSETELEM:
|
||||
|
|
@ -7274,7 +7522,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
|||
case NFT_MSG_DELSETELEM:
|
||||
te = (struct nft_trans_elem *)trans->data;
|
||||
|
||||
nft_set_elem_activate(net, te->set, &te->elem);
|
||||
nft_setelem_data_activate(net, te->set, &te->elem);
|
||||
te->set->ops->activate(net, te->set, &te->elem);
|
||||
te->set->ndeact--;
|
||||
|
||||
|
|
@ -7954,7 +8202,10 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
|
|||
list_for_each_entry_safe(set, ns, &table->sets, list) {
|
||||
list_del(&set->list);
|
||||
nft_use_dec(&table->use);
|
||||
nft_set_destroy(set);
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(&ctx, set);
|
||||
|
||||
nft_set_destroy(&ctx, set);
|
||||
}
|
||||
list_for_each_entry_safe(obj, ne, &table->objects, list) {
|
||||
nft_obj_del(obj);
|
||||
|
|
@ -7992,6 +8243,7 @@ static int __net_init nf_tables_init_net(struct net *net)
|
|||
mutex_init(&nft_net->commit_mutex);
|
||||
nft_net->base_seq = 1;
|
||||
nft_net->validate_state = NFT_VALIDATE_SKIP;
|
||||
nft_net->gc_seq = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8018,10 +8270,16 @@ static void __net_exit nf_tables_exit_net(struct net *net)
|
|||
WARN_ON_ONCE(!list_empty(&nft_net->module_list));
|
||||
}
|
||||
|
||||
static void nf_tables_exit_batch(struct list_head *net_exit_list)
|
||||
{
|
||||
flush_work(&trans_gc_work);
|
||||
}
|
||||
|
||||
static struct pernet_operations nf_tables_net_ops = {
|
||||
.init = nf_tables_init_net,
|
||||
.pre_exit = nf_tables_pre_exit_net,
|
||||
.exit = nf_tables_exit_net,
|
||||
.exit_batch = nf_tables_exit_batch,
|
||||
.id = &nf_tables_net_id,
|
||||
.size = sizeof(struct nftables_pernet),
|
||||
};
|
||||
|
|
@ -8086,6 +8344,7 @@ static void __exit nf_tables_module_exit(void)
|
|||
nft_chain_filter_fini();
|
||||
nft_chain_route_fini();
|
||||
unregister_pernet_subsys(&nf_tables_net_ops);
|
||||
cancel_work_sync(&trans_gc_work);
|
||||
cancel_work_sync(&trans_destroy_work);
|
||||
rcu_barrier();
|
||||
rhltable_destroy(&nft_objname_ht);
|
||||
|
|
|
|||
|
|
@ -161,6 +161,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
|||
if (IS_ERR(set))
|
||||
return PTR_ERR(set);
|
||||
|
||||
if (set->flags & NFT_SET_OBJECT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (set->ops->update == NULL)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ void nft_payload_eval(const struct nft_expr *expr,
|
|||
|
||||
switch (priv->base) {
|
||||
case NFT_PAYLOAD_LL_HEADER:
|
||||
if (!skb_mac_header_was_set(skb))
|
||||
if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0)
|
||||
goto err;
|
||||
|
||||
if (skb_vlan_tag_present(skb)) {
|
||||
|
|
|
|||
|
|
@ -270,13 +270,14 @@ static int nft_bitmap_init(const struct nft_set *set,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nft_bitmap_destroy(const struct nft_set *set)
|
||||
static void nft_bitmap_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_bitmap *priv = nft_set_priv(set);
|
||||
struct nft_bitmap_elem *be, *n;
|
||||
|
||||
list_for_each_entry_safe(be, n, &priv->list, head)
|
||||
nft_set_elem_destroy(set, be, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, be);
|
||||
}
|
||||
|
||||
static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
extern unsigned int nf_tables_net_id;
|
||||
|
||||
/* We target a hash table size of 4, element hint is 75% of final size */
|
||||
#define NFT_RHASH_ELEMENT_HINT 3
|
||||
|
|
@ -59,6 +62,8 @@ static inline int nft_rhash_cmp(struct rhashtable_compare_arg *arg,
|
|||
|
||||
if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
|
||||
return 1;
|
||||
if (nft_set_elem_is_dead(&he->ext))
|
||||
return 1;
|
||||
if (nft_set_elem_expired(&he->ext))
|
||||
return 1;
|
||||
if (!nft_set_elem_active(&he->ext, x->genmask))
|
||||
|
|
@ -187,7 +192,6 @@ static void nft_rhash_activate(const struct net *net, const struct nft_set *set,
|
|||
struct nft_rhash_elem *he = elem->priv;
|
||||
|
||||
nft_set_elem_change_active(net, set, &he->ext);
|
||||
nft_set_elem_clear_busy(&he->ext);
|
||||
}
|
||||
|
||||
static bool nft_rhash_flush(const struct net *net,
|
||||
|
|
@ -195,12 +199,9 @@ static bool nft_rhash_flush(const struct net *net,
|
|||
{
|
||||
struct nft_rhash_elem *he = priv;
|
||||
|
||||
if (!nft_set_elem_mark_busy(&he->ext) ||
|
||||
!nft_is_active(net, &he->ext)) {
|
||||
nft_set_elem_change_active(net, set, &he->ext);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
nft_set_elem_change_active(net, set, &he->ext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void *nft_rhash_deactivate(const struct net *net,
|
||||
|
|
@ -217,9 +218,8 @@ static void *nft_rhash_deactivate(const struct net *net,
|
|||
|
||||
rcu_read_lock();
|
||||
he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
|
||||
if (he != NULL &&
|
||||
!nft_rhash_flush(net, set, he))
|
||||
he = NULL;
|
||||
if (he)
|
||||
nft_set_elem_change_active(net, set, &he->ext);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
|
|
@ -251,7 +251,9 @@ static bool nft_rhash_delete(const struct nft_set *set,
|
|||
if (he == NULL)
|
||||
return false;
|
||||
|
||||
return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
|
||||
nft_set_elem_dead(&he->ext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
|
|
@ -277,8 +279,6 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
|
|||
|
||||
if (iter->count < iter->skip)
|
||||
goto cont;
|
||||
if (nft_set_elem_expired(&he->ext))
|
||||
goto cont;
|
||||
if (!nft_set_elem_active(&he->ext, iter->genmask))
|
||||
goto cont;
|
||||
|
||||
|
|
@ -297,49 +297,77 @@ cont:
|
|||
|
||||
static void nft_rhash_gc(struct work_struct *work)
|
||||
{
|
||||
struct nftables_pernet *nft_net;
|
||||
struct nft_set *set;
|
||||
struct nft_rhash_elem *he;
|
||||
struct nft_rhash *priv;
|
||||
struct nft_set_gc_batch *gcb = NULL;
|
||||
struct rhashtable_iter hti;
|
||||
struct nft_trans_gc *gc;
|
||||
struct net *net;
|
||||
u32 gc_seq;
|
||||
|
||||
priv = container_of(work, struct nft_rhash, gc_work.work);
|
||||
set = nft_set_container_of(priv);
|
||||
net = read_pnet(&set->net);
|
||||
nft_net = net_generic(net, nf_tables_net_id);
|
||||
gc_seq = READ_ONCE(nft_net->gc_seq);
|
||||
|
||||
gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
|
||||
if (!gc)
|
||||
goto done;
|
||||
|
||||
rhashtable_walk_enter(&priv->ht, &hti);
|
||||
rhashtable_walk_start(&hti);
|
||||
|
||||
while ((he = rhashtable_walk_next(&hti))) {
|
||||
if (IS_ERR(he)) {
|
||||
if (PTR_ERR(he) != -EAGAIN)
|
||||
break;
|
||||
if (PTR_ERR(he) != -EAGAIN) {
|
||||
nft_trans_gc_destroy(gc);
|
||||
gc = NULL;
|
||||
goto try_later;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ruleset has been updated, try later. */
|
||||
if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
|
||||
nft_trans_gc_destroy(gc);
|
||||
gc = NULL;
|
||||
goto try_later;
|
||||
}
|
||||
|
||||
if (nft_set_elem_is_dead(&he->ext))
|
||||
goto dead_elem;
|
||||
|
||||
if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPR)) {
|
||||
struct nft_expr *expr = nft_set_ext_expr(&he->ext);
|
||||
|
||||
if (expr->ops->gc &&
|
||||
expr->ops->gc(read_pnet(&set->net), expr))
|
||||
goto gc;
|
||||
goto needs_gc_run;
|
||||
}
|
||||
if (!nft_set_elem_expired(&he->ext))
|
||||
continue;
|
||||
gc:
|
||||
if (nft_set_elem_mark_busy(&he->ext))
|
||||
continue;
|
||||
|
||||
gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
|
||||
if (gcb == NULL)
|
||||
break;
|
||||
rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params);
|
||||
atomic_dec(&set->nelems);
|
||||
nft_set_gc_batch_add(gcb, he);
|
||||
needs_gc_run:
|
||||
nft_set_elem_dead(&he->ext);
|
||||
dead_elem:
|
||||
gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
|
||||
if (!gc)
|
||||
goto try_later;
|
||||
|
||||
nft_trans_gc_elem_add(gc, he);
|
||||
}
|
||||
|
||||
try_later:
|
||||
/* catchall list iteration requires rcu read side lock. */
|
||||
rhashtable_walk_stop(&hti);
|
||||
rhashtable_walk_exit(&hti);
|
||||
|
||||
nft_set_gc_batch_complete(gcb);
|
||||
if (gc)
|
||||
nft_trans_gc_queue_async_done(gc);
|
||||
|
||||
done:
|
||||
queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
|
||||
nft_set_gc_interval(set));
|
||||
}
|
||||
|
|
@ -374,25 +402,36 @@ static int nft_rhash_init(const struct nft_set *set,
|
|||
return err;
|
||||
|
||||
INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
|
||||
if (set->flags & NFT_SET_TIMEOUT)
|
||||
if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
|
||||
nft_rhash_gc_init(set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nft_rhash_ctx {
|
||||
const struct nft_ctx ctx;
|
||||
const struct nft_set *set;
|
||||
};
|
||||
|
||||
static void nft_rhash_elem_destroy(void *ptr, void *arg)
|
||||
{
|
||||
nft_set_elem_destroy(arg, ptr, true);
|
||||
struct nft_rhash_ctx *rhash_ctx = arg;
|
||||
|
||||
nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, ptr);
|
||||
}
|
||||
|
||||
static void nft_rhash_destroy(const struct nft_set *set)
|
||||
static void nft_rhash_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_rhash *priv = nft_set_priv(set);
|
||||
struct nft_rhash_ctx rhash_ctx = {
|
||||
.ctx = *ctx,
|
||||
.set = set,
|
||||
};
|
||||
|
||||
cancel_delayed_work_sync(&priv->gc_work);
|
||||
rcu_barrier();
|
||||
rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
|
||||
(void *)set);
|
||||
(void *)&rhash_ctx);
|
||||
}
|
||||
|
||||
/* Number of buckets is stored in u32, so cap our result to 1U<<31 */
|
||||
|
|
@ -621,7 +660,8 @@ static int nft_hash_init(const struct nft_set *set,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nft_hash_destroy(const struct nft_set *set)
|
||||
static void nft_hash_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_hash *priv = nft_set_priv(set);
|
||||
struct nft_hash_elem *he;
|
||||
|
|
@ -631,7 +671,7 @@ static void nft_hash_destroy(const struct nft_set *set)
|
|||
for (i = 0; i < priv->buckets; i++) {
|
||||
hlist_for_each_entry_safe(he, next, &priv->table[i], node) {
|
||||
hlist_del_rcu(&he->node);
|
||||
nft_set_elem_destroy(set, he, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, he);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@
|
|||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
extern unsigned int nf_tables_net_id;
|
||||
|
||||
struct nft_rbtree {
|
||||
struct rb_root root;
|
||||
|
|
@ -38,10 +41,18 @@ static bool nft_rbtree_interval_start(const struct nft_rbtree_elem *rbe)
|
|||
return !nft_rbtree_interval_end(rbe);
|
||||
}
|
||||
|
||||
static bool nft_rbtree_equal(const struct nft_set *set, const void *this,
|
||||
const struct nft_rbtree_elem *interval)
|
||||
static int nft_rbtree_cmp(const struct nft_set *set,
|
||||
const struct nft_rbtree_elem *e1,
|
||||
const struct nft_rbtree_elem *e2)
|
||||
{
|
||||
return memcmp(this, nft_set_ext_key(&interval->ext), set->klen) == 0;
|
||||
return memcmp(nft_set_ext_key(&e1->ext), nft_set_ext_key(&e2->ext),
|
||||
set->klen);
|
||||
}
|
||||
|
||||
static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe)
|
||||
{
|
||||
return nft_set_elem_expired(&rbe->ext) ||
|
||||
nft_set_elem_is_dead(&rbe->ext);
|
||||
}
|
||||
|
||||
static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
|
||||
|
|
@ -52,7 +63,6 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
|
|||
const struct nft_rbtree_elem *rbe, *interval = NULL;
|
||||
u8 genmask = nft_genmask_cur(net);
|
||||
const struct rb_node *parent;
|
||||
const void *this;
|
||||
int d;
|
||||
|
||||
parent = rcu_dereference_raw(priv->root.rb_node);
|
||||
|
|
@ -62,12 +72,11 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
|
|||
|
||||
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
|
||||
|
||||
this = nft_set_ext_key(&rbe->ext);
|
||||
d = memcmp(this, key, set->klen);
|
||||
d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen);
|
||||
if (d < 0) {
|
||||
parent = rcu_dereference_raw(parent->rb_left);
|
||||
if (interval &&
|
||||
nft_rbtree_equal(set, this, interval) &&
|
||||
!nft_rbtree_cmp(set, rbe, interval) &&
|
||||
nft_rbtree_interval_end(rbe) &&
|
||||
nft_rbtree_interval_start(interval))
|
||||
continue;
|
||||
|
|
@ -80,7 +89,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
|
|||
continue;
|
||||
}
|
||||
|
||||
if (nft_set_elem_expired(&rbe->ext))
|
||||
if (nft_rbtree_elem_expired(rbe))
|
||||
return false;
|
||||
|
||||
if (nft_rbtree_interval_end(rbe)) {
|
||||
|
|
@ -98,7 +107,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
|
|||
|
||||
if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
|
||||
nft_set_elem_active(&interval->ext, genmask) &&
|
||||
!nft_set_elem_expired(&interval->ext) &&
|
||||
!nft_rbtree_elem_expired(interval) &&
|
||||
nft_rbtree_interval_start(interval)) {
|
||||
*ext = &interval->ext;
|
||||
return true;
|
||||
|
|
@ -214,43 +223,254 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set,
|
|||
return rbe;
|
||||
}
|
||||
|
||||
static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
|
||||
struct nft_rbtree *priv,
|
||||
struct nft_rbtree_elem *rbe)
|
||||
{
|
||||
struct nft_set_elem elem = {
|
||||
.priv = rbe,
|
||||
};
|
||||
|
||||
nft_setelem_data_deactivate(net, set, &elem);
|
||||
rb_erase(&rbe->node, &priv->root);
|
||||
}
|
||||
|
||||
static int nft_rbtree_gc_elem(const struct nft_set *__set,
|
||||
struct nft_rbtree *priv,
|
||||
struct nft_rbtree_elem *rbe,
|
||||
u8 genmask)
|
||||
{
|
||||
struct nft_set *set = (struct nft_set *)__set;
|
||||
struct rb_node *prev = rb_prev(&rbe->node);
|
||||
struct net *net = read_pnet(&set->net);
|
||||
struct nft_rbtree_elem *rbe_prev;
|
||||
struct nft_trans_gc *gc;
|
||||
|
||||
gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
|
||||
if (!gc)
|
||||
return -ENOMEM;
|
||||
|
||||
/* search for end interval coming before this element.
|
||||
* end intervals don't carry a timeout extension, they
|
||||
* are coupled with the interval start element.
|
||||
*/
|
||||
while (prev) {
|
||||
rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
|
||||
if (nft_rbtree_interval_end(rbe_prev) &&
|
||||
nft_set_elem_active(&rbe_prev->ext, genmask))
|
||||
break;
|
||||
|
||||
prev = rb_prev(prev);
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
|
||||
nft_rbtree_gc_remove(net, set, priv, rbe_prev);
|
||||
|
||||
/* There is always room in this trans gc for this element,
|
||||
* memory allocation never actually happens, hence, the warning
|
||||
* splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT,
|
||||
* this is synchronous gc which never fails.
|
||||
*/
|
||||
gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
|
||||
if (WARN_ON_ONCE(!gc))
|
||||
return -ENOMEM;
|
||||
|
||||
nft_trans_gc_elem_add(gc, rbe_prev);
|
||||
}
|
||||
|
||||
nft_rbtree_gc_remove(net, set, priv, rbe);
|
||||
gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
|
||||
if (WARN_ON_ONCE(!gc))
|
||||
return -ENOMEM;
|
||||
|
||||
nft_trans_gc_elem_add(gc, rbe);
|
||||
|
||||
nft_trans_gc_queue_sync_done(gc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool nft_rbtree_update_first(const struct nft_set *set,
|
||||
struct nft_rbtree_elem *rbe,
|
||||
struct rb_node *first)
|
||||
{
|
||||
struct nft_rbtree_elem *first_elem;
|
||||
|
||||
first_elem = rb_entry(first, struct nft_rbtree_elem, node);
|
||||
/* this element is closest to where the new element is to be inserted:
|
||||
* update the first element for the node list path.
|
||||
*/
|
||||
if (nft_rbtree_cmp(set, rbe, first_elem) < 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
|
||||
struct nft_rbtree_elem *new,
|
||||
struct nft_set_ext **ext)
|
||||
{
|
||||
struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL;
|
||||
struct rb_node *node, *next, *parent, **p, *first = NULL;
|
||||
struct nft_rbtree *priv = nft_set_priv(set);
|
||||
u8 genmask = nft_genmask_next(net);
|
||||
struct nft_rbtree_elem *rbe;
|
||||
struct rb_node *parent, **p;
|
||||
int d;
|
||||
int d, err;
|
||||
|
||||
/* Descend the tree to search for an existing element greater than the
|
||||
* key value to insert that is greater than the new element. This is the
|
||||
* first element to walk the ordered elements to find possible overlap.
|
||||
*/
|
||||
parent = NULL;
|
||||
p = &priv->root.rb_node;
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
|
||||
d = memcmp(nft_set_ext_key(&rbe->ext),
|
||||
nft_set_ext_key(&new->ext),
|
||||
set->klen);
|
||||
d = nft_rbtree_cmp(set, rbe, new);
|
||||
|
||||
if (d < 0) {
|
||||
p = &parent->rb_left;
|
||||
} else if (d > 0) {
|
||||
if (!first ||
|
||||
nft_rbtree_update_first(set, rbe, first))
|
||||
first = &rbe->node;
|
||||
|
||||
p = &parent->rb_right;
|
||||
} else {
|
||||
if (nft_rbtree_interval_end(rbe))
|
||||
p = &parent->rb_left;
|
||||
else
|
||||
p = &parent->rb_right;
|
||||
}
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = rb_first(&priv->root);
|
||||
|
||||
/* Detect overlap by going through the list of valid tree nodes.
|
||||
* Values stored in the tree are in reversed order, starting from
|
||||
* highest to lowest value.
|
||||
*/
|
||||
for (node = first; node != NULL; node = next) {
|
||||
next = rb_next(node);
|
||||
|
||||
rbe = rb_entry(node, struct nft_rbtree_elem, node);
|
||||
|
||||
if (!nft_set_elem_active(&rbe->ext, genmask))
|
||||
continue;
|
||||
|
||||
/* perform garbage collection to avoid bogus overlap reports. */
|
||||
if (nft_set_elem_expired(&rbe->ext)) {
|
||||
err = nft_rbtree_gc_elem(set, priv, rbe, genmask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
d = nft_rbtree_cmp(set, rbe, new);
|
||||
if (d == 0) {
|
||||
/* Matching end element: no need to look for an
|
||||
* overlapping greater or equal element.
|
||||
*/
|
||||
if (nft_rbtree_interval_end(rbe)) {
|
||||
rbe_le = rbe;
|
||||
break;
|
||||
}
|
||||
|
||||
/* first element that is greater or equal to key value. */
|
||||
if (!rbe_ge) {
|
||||
rbe_ge = rbe;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* this is a closer more or equal element, update it. */
|
||||
if (nft_rbtree_cmp(set, rbe_ge, new) != 0) {
|
||||
rbe_ge = rbe;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* element is equal to key value, make sure flags are
|
||||
* the same, an existing more or equal start element
|
||||
* must not be replaced by more or equal end element.
|
||||
*/
|
||||
if ((nft_rbtree_interval_start(new) &&
|
||||
nft_rbtree_interval_start(rbe_ge)) ||
|
||||
(nft_rbtree_interval_end(new) &&
|
||||
nft_rbtree_interval_end(rbe_ge))) {
|
||||
rbe_ge = rbe;
|
||||
continue;
|
||||
}
|
||||
} else if (d > 0) {
|
||||
/* annotate element greater than the new element. */
|
||||
rbe_ge = rbe;
|
||||
continue;
|
||||
} else if (d < 0) {
|
||||
/* annotate element less than the new element. */
|
||||
rbe_le = rbe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* - new start element matching existing start element: full overlap
|
||||
* reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given.
|
||||
*/
|
||||
if (rbe_ge && !nft_rbtree_cmp(set, new, rbe_ge) &&
|
||||
nft_rbtree_interval_start(rbe_ge) == nft_rbtree_interval_start(new)) {
|
||||
*ext = &rbe_ge->ext;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/* - new end element matching existing end element: full overlap
|
||||
* reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given.
|
||||
*/
|
||||
if (rbe_le && !nft_rbtree_cmp(set, new, rbe_le) &&
|
||||
nft_rbtree_interval_end(rbe_le) == nft_rbtree_interval_end(new)) {
|
||||
*ext = &rbe_le->ext;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/* - new start element with existing closest, less or equal key value
|
||||
* being a start element: partial overlap, reported as -ENOTEMPTY.
|
||||
* Anonymous sets allow for two consecutive start element since they
|
||||
* are constant, skip them to avoid bogus overlap reports.
|
||||
*/
|
||||
if (!nft_set_is_anonymous(set) && rbe_le &&
|
||||
nft_rbtree_interval_start(rbe_le) && nft_rbtree_interval_start(new))
|
||||
return -ENOTEMPTY;
|
||||
|
||||
/* - new end element with existing closest, less or equal key value
|
||||
* being a end element: partial overlap, reported as -ENOTEMPTY.
|
||||
*/
|
||||
if (rbe_le &&
|
||||
nft_rbtree_interval_end(rbe_le) && nft_rbtree_interval_end(new))
|
||||
return -ENOTEMPTY;
|
||||
|
||||
/* - new end element with existing closest, greater or equal key value
|
||||
* being an end element: partial overlap, reported as -ENOTEMPTY
|
||||
*/
|
||||
if (rbe_ge &&
|
||||
nft_rbtree_interval_end(rbe_ge) && nft_rbtree_interval_end(new))
|
||||
return -ENOTEMPTY;
|
||||
|
||||
/* Accepted element: pick insertion point depending on key value */
|
||||
parent = NULL;
|
||||
p = &priv->root.rb_node;
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
|
||||
d = nft_rbtree_cmp(set, rbe, new);
|
||||
|
||||
if (d < 0)
|
||||
p = &parent->rb_left;
|
||||
else if (d > 0)
|
||||
p = &parent->rb_right;
|
||||
else {
|
||||
if (nft_rbtree_interval_end(rbe) &&
|
||||
nft_rbtree_interval_start(new)) {
|
||||
p = &parent->rb_left;
|
||||
} else if (nft_rbtree_interval_start(rbe) &&
|
||||
nft_rbtree_interval_end(new)) {
|
||||
p = &parent->rb_right;
|
||||
} else if (nft_set_elem_active(&rbe->ext, genmask)) {
|
||||
*ext = &rbe->ext;
|
||||
return -EEXIST;
|
||||
} else {
|
||||
p = &parent->rb_left;
|
||||
}
|
||||
}
|
||||
else if (nft_rbtree_interval_end(rbe))
|
||||
p = &parent->rb_left;
|
||||
else
|
||||
p = &parent->rb_right;
|
||||
}
|
||||
|
||||
rb_link_node_rcu(&new->node, parent, p);
|
||||
rb_insert_color(&new->node, &priv->root);
|
||||
return 0;
|
||||
|
|
@ -294,7 +514,6 @@ static void nft_rbtree_activate(const struct net *net,
|
|||
struct nft_rbtree_elem *rbe = elem->priv;
|
||||
|
||||
nft_set_elem_change_active(net, set, &rbe->ext);
|
||||
nft_set_elem_clear_busy(&rbe->ext);
|
||||
}
|
||||
|
||||
static bool nft_rbtree_flush(const struct net *net,
|
||||
|
|
@ -302,12 +521,9 @@ static bool nft_rbtree_flush(const struct net *net,
|
|||
{
|
||||
struct nft_rbtree_elem *rbe = priv;
|
||||
|
||||
if (!nft_set_elem_mark_busy(&rbe->ext) ||
|
||||
!nft_is_active(net, &rbe->ext)) {
|
||||
nft_set_elem_change_active(net, set, &rbe->ext);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
nft_set_elem_change_active(net, set, &rbe->ext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void *nft_rbtree_deactivate(const struct net *net,
|
||||
|
|
@ -338,6 +554,8 @@ static void *nft_rbtree_deactivate(const struct net *net,
|
|||
nft_rbtree_interval_end(this)) {
|
||||
parent = parent->rb_right;
|
||||
continue;
|
||||
} else if (nft_set_elem_expired(&rbe->ext)) {
|
||||
break;
|
||||
} else if (!nft_set_elem_active(&rbe->ext, genmask)) {
|
||||
parent = parent->rb_left;
|
||||
continue;
|
||||
|
|
@ -364,8 +582,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
|
|||
|
||||
if (iter->count < iter->skip)
|
||||
goto cont;
|
||||
if (nft_set_elem_expired(&rbe->ext))
|
||||
goto cont;
|
||||
if (!nft_set_elem_active(&rbe->ext, iter->genmask))
|
||||
goto cont;
|
||||
|
||||
|
|
@ -384,26 +600,40 @@ cont:
|
|||
|
||||
static void nft_rbtree_gc(struct work_struct *work)
|
||||
{
|
||||
struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL;
|
||||
struct nft_set_gc_batch *gcb = NULL;
|
||||
struct nft_rbtree_elem *rbe, *rbe_end = NULL;
|
||||
struct nftables_pernet *nft_net;
|
||||
struct nft_rbtree *priv;
|
||||
struct nft_trans_gc *gc;
|
||||
struct rb_node *node;
|
||||
struct nft_set *set;
|
||||
unsigned int gc_seq;
|
||||
struct net *net;
|
||||
u8 genmask;
|
||||
|
||||
priv = container_of(work, struct nft_rbtree, gc_work.work);
|
||||
set = nft_set_container_of(priv);
|
||||
net = read_pnet(&set->net);
|
||||
genmask = nft_genmask_cur(net);
|
||||
nft_net = net_generic(net, nf_tables_net_id);
|
||||
gc_seq = READ_ONCE(nft_net->gc_seq);
|
||||
|
||||
gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
|
||||
if (!gc)
|
||||
goto done;
|
||||
|
||||
write_lock_bh(&priv->lock);
|
||||
write_seqcount_begin(&priv->count);
|
||||
for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
|
||||
|
||||
/* Ruleset has been updated, try later. */
|
||||
if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
|
||||
nft_trans_gc_destroy(gc);
|
||||
gc = NULL;
|
||||
goto try_later;
|
||||
}
|
||||
|
||||
rbe = rb_entry(node, struct nft_rbtree_elem, node);
|
||||
|
||||
if (!nft_set_elem_active(&rbe->ext, genmask))
|
||||
continue;
|
||||
if (nft_set_elem_is_dead(&rbe->ext))
|
||||
goto dead_elem;
|
||||
|
||||
/* elements are reversed in the rbtree for historical reasons,
|
||||
* from highest to lowest value, that is why end element is
|
||||
|
|
@ -413,43 +643,38 @@ static void nft_rbtree_gc(struct work_struct *work)
|
|||
rbe_end = rbe;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!nft_set_elem_expired(&rbe->ext))
|
||||
continue;
|
||||
|
||||
if (nft_set_elem_mark_busy(&rbe->ext)) {
|
||||
rbe_end = NULL;
|
||||
nft_set_elem_dead(&rbe->ext);
|
||||
|
||||
if (!rbe_end)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rbe_prev) {
|
||||
rb_erase(&rbe_prev->node, &priv->root);
|
||||
rbe_prev = NULL;
|
||||
}
|
||||
gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
|
||||
if (!gcb)
|
||||
break;
|
||||
nft_set_elem_dead(&rbe_end->ext);
|
||||
|
||||
atomic_dec(&set->nelems);
|
||||
nft_set_gc_batch_add(gcb, rbe);
|
||||
rbe_prev = rbe;
|
||||
gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
|
||||
if (!gc)
|
||||
goto try_later;
|
||||
|
||||
if (rbe_end) {
|
||||
atomic_dec(&set->nelems);
|
||||
nft_set_gc_batch_add(gcb, rbe_end);
|
||||
rb_erase(&rbe_end->node, &priv->root);
|
||||
rbe_end = NULL;
|
||||
}
|
||||
node = rb_next(node);
|
||||
if (!node)
|
||||
break;
|
||||
nft_trans_gc_elem_add(gc, rbe_end);
|
||||
rbe_end = NULL;
|
||||
dead_elem:
|
||||
gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
|
||||
if (!gc)
|
||||
goto try_later;
|
||||
|
||||
nft_trans_gc_elem_add(gc, rbe);
|
||||
}
|
||||
if (rbe_prev)
|
||||
rb_erase(&rbe_prev->node, &priv->root);
|
||||
|
||||
try_later:
|
||||
write_seqcount_end(&priv->count);
|
||||
write_unlock_bh(&priv->lock);
|
||||
|
||||
nft_set_gc_batch_complete(gcb);
|
||||
|
||||
if (gc)
|
||||
nft_trans_gc_queue_async_done(gc);
|
||||
done:
|
||||
queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
|
||||
nft_set_gc_interval(set));
|
||||
}
|
||||
|
|
@ -478,7 +703,8 @@ static int nft_rbtree_init(const struct nft_set *set,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nft_rbtree_destroy(const struct nft_set *set)
|
||||
static void nft_rbtree_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_rbtree *priv = nft_set_priv(set);
|
||||
struct nft_rbtree_elem *rbe;
|
||||
|
|
@ -489,7 +715,7 @@ static void nft_rbtree_destroy(const struct nft_set *set)
|
|||
while ((node = priv->root.rb_node) != NULL) {
|
||||
rb_erase(node, &priv->root);
|
||||
rbe = rb_entry(node, struct nft_rbtree_elem, node);
|
||||
nft_set_elem_destroy(set, rbe, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, rbe);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -857,7 +857,8 @@ int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
|
|||
|
||||
offset -= iter->startbit;
|
||||
idx = offset / NETLBL_CATMAP_MAPSIZE;
|
||||
iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
|
||||
iter->bitmap[idx] |= (NETLBL_CATMAP_MAPTYPE)bitmap
|
||||
<< (offset % NETLBL_CATMAP_MAPSIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -638,6 +638,11 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
|
|||
goto out_release;
|
||||
}
|
||||
|
||||
if (sock->state == SS_CONNECTING) {
|
||||
err = -EALREADY;
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
sk->sk_state = TCP_CLOSE;
|
||||
sock->state = SS_UNCONNECTED;
|
||||
|
||||
|
|
|
|||
|
|
@ -205,17 +205,13 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
|
|||
|
||||
if (tmp_sock->ssap == ssap && tmp_sock->dsap == dsap) {
|
||||
llcp_sock = tmp_sock;
|
||||
sock_hold(&llcp_sock->sk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
read_unlock(&local->sockets.lock);
|
||||
|
||||
if (llcp_sock == NULL)
|
||||
return NULL;
|
||||
|
||||
sock_hold(&llcp_sock->sk);
|
||||
|
||||
return llcp_sock;
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +344,8 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
|
|||
|
||||
static
|
||||
struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local,
|
||||
const u8 *sn, size_t sn_len)
|
||||
const u8 *sn, size_t sn_len,
|
||||
bool needref)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct nfc_llcp_sock *llcp_sock, *tmp_sock;
|
||||
|
|
@ -384,6 +381,8 @@ struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local,
|
|||
|
||||
if (memcmp(sn, tmp_sock->service_name, sn_len) == 0) {
|
||||
llcp_sock = tmp_sock;
|
||||
if (needref)
|
||||
sock_hold(&llcp_sock->sk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -425,7 +424,8 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
|
|||
* to this service name.
|
||||
*/
|
||||
if (nfc_llcp_sock_from_sn(local, sock->service_name,
|
||||
sock->service_name_len) != NULL) {
|
||||
sock->service_name_len,
|
||||
false) != NULL) {
|
||||
mutex_unlock(&local->sdp_lock);
|
||||
|
||||
return LLCP_SAP_MAX;
|
||||
|
|
@ -833,16 +833,7 @@ out:
|
|||
static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
|
||||
const u8 *sn, size_t sn_len)
|
||||
{
|
||||
struct nfc_llcp_sock *llcp_sock;
|
||||
|
||||
llcp_sock = nfc_llcp_sock_from_sn(local, sn, sn_len);
|
||||
|
||||
if (llcp_sock == NULL)
|
||||
return NULL;
|
||||
|
||||
sock_hold(&llcp_sock->sk);
|
||||
|
||||
return llcp_sock;
|
||||
return nfc_llcp_sock_from_sn(local, sn, sn_len, true);
|
||||
}
|
||||
|
||||
static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
|
||||
|
|
@ -1307,7 +1298,8 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
|
|||
}
|
||||
|
||||
llcp_sock = nfc_llcp_sock_from_sn(local, service_name,
|
||||
service_name_len);
|
||||
service_name_len,
|
||||
true);
|
||||
if (!llcp_sock) {
|
||||
sap = 0;
|
||||
goto add_snl;
|
||||
|
|
@ -1327,6 +1319,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
|
|||
|
||||
if (sap == LLCP_SAP_MAX) {
|
||||
sap = 0;
|
||||
nfc_llcp_sock_put(llcp_sock);
|
||||
goto add_snl;
|
||||
}
|
||||
|
||||
|
|
@ -1344,6 +1337,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
|
|||
|
||||
pr_debug("%p %d\n", llcp_sock, sap);
|
||||
|
||||
nfc_llcp_sock_put(llcp_sock);
|
||||
add_snl:
|
||||
sdp = nfc_llcp_build_sdres_tlv(tid, sap);
|
||||
if (sdp == NULL)
|
||||
|
|
@ -1646,7 +1640,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
|
|||
timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0);
|
||||
INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work);
|
||||
|
||||
spin_lock(&llcp_devices_lock);
|
||||
list_add(&local->list, &llcp_devices);
|
||||
spin_unlock(&llcp_devices_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -894,6 +894,11 @@ static int nci_activate_target(struct nfc_dev *nfc_dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (protocol >= NFC_PROTO_MAX) {
|
||||
pr_err("the requested nfc protocol is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(nci_target->supported_protocols & (1 << protocol))) {
|
||||
pr_err("target does not support the requested protocol 0x%x\n",
|
||||
protocol);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge)
|
|||
int ret;
|
||||
|
||||
skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
/* add the NCI SPI header to the start of the buffer */
|
||||
hdr = skb_push(skb, NCI_SPI_HDR_LEN);
|
||||
|
|
|
|||
|
|
@ -86,10 +86,12 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
|
|||
break;
|
||||
|
||||
case RDMA_CM_EVENT_ADDR_RESOLVED:
|
||||
rdma_set_service_type(cm_id, conn->c_tos);
|
||||
/* XXX do we need to clean up if this fails? */
|
||||
ret = rdma_resolve_route(cm_id,
|
||||
if (conn) {
|
||||
rdma_set_service_type(cm_id, conn->c_tos);
|
||||
/* XXX do we need to clean up if this fails? */
|
||||
ret = rdma_resolve_route(cm_id,
|
||||
RDS_RDMA_RESOLVE_TIMEOUT_MS);
|
||||
}
|
||||
break;
|
||||
|
||||
case RDMA_CM_EVENT_ROUTE_RESOLVED:
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
|
|||
addrlen = sizeof(sin);
|
||||
}
|
||||
|
||||
ret = sock->ops->bind(sock, addr, addrlen);
|
||||
ret = kernel_bind(sock, addr, addrlen);
|
||||
if (ret) {
|
||||
rdsdebug("bind failed with %d at address %pI6c\n",
|
||||
ret, &conn->c_laddr);
|
||||
|
|
@ -169,7 +169,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
|
|||
* own the socket
|
||||
*/
|
||||
rds_tcp_set_callbacks(sock, cp);
|
||||
ret = sock->ops->connect(sock, addr, addrlen, O_NONBLOCK);
|
||||
ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK);
|
||||
|
||||
rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret);
|
||||
if (ret == -EINPROGRESS)
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6)
|
|||
addr_len = sizeof(*sin);
|
||||
}
|
||||
|
||||
ret = sock->ops->bind(sock, (struct sockaddr *)&ss, addr_len);
|
||||
ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len);
|
||||
if (ret < 0) {
|
||||
rdsdebug("could not bind %s listener socket: %d\n",
|
||||
isv6 ? "IPv6" : "IPv4", ret);
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
rfkill->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
|
||||
gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
|
||||
gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS);
|
||||
if (IS_ERR(gpio))
|
||||
return PTR_ERR(gpio);
|
||||
|
||||
rfkill->reset_gpio = gpio;
|
||||
|
||||
gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_OUT_LOW);
|
||||
gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_ASIS);
|
||||
if (IS_ERR(gpio))
|
||||
return PTR_ERR(gpio);
|
||||
|
||||
|
|
|
|||
|
|
@ -1503,10 +1503,28 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool req_create_or_replace(struct nlmsghdr *n)
|
||||
{
|
||||
return (n->nlmsg_flags & NLM_F_CREATE &&
|
||||
n->nlmsg_flags & NLM_F_REPLACE);
|
||||
}
|
||||
|
||||
static bool req_create_exclusive(struct nlmsghdr *n)
|
||||
{
|
||||
return (n->nlmsg_flags & NLM_F_CREATE &&
|
||||
n->nlmsg_flags & NLM_F_EXCL);
|
||||
}
|
||||
|
||||
static bool req_change(struct nlmsghdr *n)
|
||||
{
|
||||
return (!(n->nlmsg_flags & NLM_F_CREATE) &&
|
||||
!(n->nlmsg_flags & NLM_F_REPLACE) &&
|
||||
!(n->nlmsg_flags & NLM_F_EXCL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Create/change qdisc.
|
||||
*/
|
||||
|
||||
static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
|
|
@ -1603,27 +1621,35 @@ replay:
|
|||
*
|
||||
* We know, that some child q is already
|
||||
* attached to this parent and have choice:
|
||||
* either to change it or to create/graft new one.
|
||||
* 1) change it or 2) create/graft new one.
|
||||
* If the requested qdisc kind is different
|
||||
* than the existing one, then we choose graft.
|
||||
* If they are the same then this is "change"
|
||||
* operation - just let it fallthrough..
|
||||
*
|
||||
* 1. We are allowed to create/graft only
|
||||
* if CREATE and REPLACE flags are set.
|
||||
* if the request is explicitly stating
|
||||
* "please create if it doesn't exist".
|
||||
*
|
||||
* 2. If EXCL is set, requestor wanted to say,
|
||||
* that qdisc tcm_handle is not expected
|
||||
* 2. If the request is to exclusive create
|
||||
* then the qdisc tcm_handle is not expected
|
||||
* to exist, so that we choose create/graft too.
|
||||
*
|
||||
* 3. The last case is when no flags are set.
|
||||
* This will happen when for example tc
|
||||
* utility issues a "change" command.
|
||||
* Alas, it is sort of hole in API, we
|
||||
* cannot decide what to do unambiguously.
|
||||
* For now we select create/graft, if
|
||||
* user gave KIND, which does not match existing.
|
||||
* For now we select create/graft.
|
||||
*/
|
||||
if ((n->nlmsg_flags & NLM_F_CREATE) &&
|
||||
(n->nlmsg_flags & NLM_F_REPLACE) &&
|
||||
((n->nlmsg_flags & NLM_F_EXCL) ||
|
||||
(tca[TCA_KIND] &&
|
||||
nla_strcmp(tca[TCA_KIND], q->ops->id))))
|
||||
goto create_n_graft;
|
||||
if (tca[TCA_KIND] &&
|
||||
nla_strcmp(tca[TCA_KIND], q->ops->id)) {
|
||||
if (req_create_or_replace(n) ||
|
||||
req_create_exclusive(n))
|
||||
goto create_n_graft;
|
||||
else if (req_change(n))
|
||||
goto create_n_graft2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1657,6 +1683,7 @@ create_n_graft:
|
|||
NL_SET_ERR_MSG(extack, "Qdisc not found. To create specify NLM_F_CREATE flag");
|
||||
return -ENOENT;
|
||||
}
|
||||
create_n_graft2:
|
||||
if (clid == TC_H_INGRESS) {
|
||||
if (dev_ingress_queue(dev)) {
|
||||
q = qdisc_create(dev, dev_ingress_queue(dev), p,
|
||||
|
|
|
|||
|
|
@ -903,6 +903,14 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc,
|
|||
cl->cl_flags |= HFSC_USC;
|
||||
}
|
||||
|
||||
static void
|
||||
hfsc_upgrade_rt(struct hfsc_class *cl)
|
||||
{
|
||||
cl->cl_fsc = cl->cl_rsc;
|
||||
rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total);
|
||||
cl->cl_flags |= HFSC_FSC;
|
||||
}
|
||||
|
||||
static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = {
|
||||
[TCA_HFSC_RSC] = { .len = sizeof(struct tc_service_curve) },
|
||||
[TCA_HFSC_FSC] = { .len = sizeof(struct tc_service_curve) },
|
||||
|
|
@ -1012,10 +1020,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
if (parent == NULL)
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0)
|
||||
return -EINVAL;
|
||||
|
|
@ -1068,6 +1072,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
cl->cf_tree = RB_ROOT;
|
||||
|
||||
sch_tree_lock(sch);
|
||||
/* Check if the inner class is a misconfigured 'rt' */
|
||||
if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Forced curve change on parent 'rt' to 'sc'");
|
||||
hfsc_upgrade_rt(parent);
|
||||
}
|
||||
qdisc_class_hash_insert(&q->clhash, &cl->cl_common);
|
||||
list_add_tail(&cl->siblings, &parent->children);
|
||||
if (parent->level == 0)
|
||||
|
|
|
|||
|
|
@ -1156,8 +1156,7 @@ int sctp_assoc_update(struct sctp_association *asoc,
|
|||
/* Add any peer addresses from the new association. */
|
||||
list_for_each_entry(trans, &new->peer.transport_addr_list,
|
||||
transports)
|
||||
if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) &&
|
||||
!sctp_assoc_add_peer(asoc, &trans->ipaddr,
|
||||
if (!sctp_assoc_add_peer(asoc, &trans->ipaddr,
|
||||
GFP_ATOMIC, trans->state))
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
|
|||
assoc->init_retries, assoc->shutdown_retries,
|
||||
assoc->rtx_data_chunks,
|
||||
refcount_read(&sk->sk_wmem_alloc),
|
||||
sk->sk_wmem_queued,
|
||||
READ_ONCE(sk->sk_wmem_queued),
|
||||
sk->sk_sndbuf,
|
||||
sk->sk_rcvbuf);
|
||||
seq_printf(seq, "\n");
|
||||
|
|
|
|||
|
|
@ -1240,7 +1240,10 @@ static int sctp_side_effects(enum sctp_event_type event_type,
|
|||
default:
|
||||
pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n",
|
||||
status, state, event_type, subtype.chunk);
|
||||
BUG();
|
||||
error = status;
|
||||
if (error >= 0)
|
||||
error = -EINVAL;
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
#include <net/sctp/stream_sched.h>
|
||||
|
||||
/* Forward declarations for internal helper functions. */
|
||||
static bool sctp_writeable(struct sock *sk);
|
||||
static bool sctp_writeable(const struct sock *sk);
|
||||
static void sctp_wfree(struct sk_buff *skb);
|
||||
static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
|
||||
size_t msg_len);
|
||||
|
|
@ -97,7 +97,7 @@ struct percpu_counter sctp_sockets_allocated;
|
|||
|
||||
static void sctp_enter_memory_pressure(struct sock *sk)
|
||||
{
|
||||
sctp_memory_pressure = 1;
|
||||
WRITE_ONCE(sctp_memory_pressure, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
|
|||
|
||||
refcount_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
|
||||
asoc->sndbuf_used += chunk->skb->truesize + sizeof(struct sctp_chunk);
|
||||
sk->sk_wmem_queued += chunk->skb->truesize + sizeof(struct sctp_chunk);
|
||||
sk_wmem_queued_add(sk, chunk->skb->truesize + sizeof(struct sctp_chunk));
|
||||
sk_mem_charge(sk, chunk->skb->truesize);
|
||||
}
|
||||
|
||||
|
|
@ -2491,6 +2491,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
|
|||
if (trans) {
|
||||
trans->hbinterval =
|
||||
msecs_to_jiffies(params->spp_hbinterval);
|
||||
sctp_transport_reset_hb_timer(trans);
|
||||
} else if (asoc) {
|
||||
asoc->hbinterval =
|
||||
msecs_to_jiffies(params->spp_hbinterval);
|
||||
|
|
@ -9002,7 +9003,7 @@ static void sctp_wfree(struct sk_buff *skb)
|
|||
struct sock *sk = asoc->base.sk;
|
||||
|
||||
sk_mem_uncharge(sk, skb->truesize);
|
||||
sk->sk_wmem_queued -= skb->truesize + sizeof(struct sctp_chunk);
|
||||
sk_wmem_queued_add(sk, -(skb->truesize + sizeof(struct sctp_chunk)));
|
||||
asoc->sndbuf_used -= skb->truesize + sizeof(struct sctp_chunk);
|
||||
WARN_ON(refcount_sub_and_test(sizeof(struct sctp_chunk),
|
||||
&sk->sk_wmem_alloc));
|
||||
|
|
@ -9157,9 +9158,9 @@ void sctp_write_space(struct sock *sk)
|
|||
* UDP-style sockets or TCP-style sockets, this code should work.
|
||||
* - Daisy
|
||||
*/
|
||||
static bool sctp_writeable(struct sock *sk)
|
||||
static bool sctp_writeable(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_sndbuf > sk->sk_wmem_queued;
|
||||
return READ_ONCE(sk->sk_sndbuf) > READ_ONCE(sk->sk_wmem_queued);
|
||||
}
|
||||
|
||||
/* Wait for an association to go into ESTABLISHED state. If timeout is 0,
|
||||
|
|
|
|||
41
net/socket.c
41
net/socket.c
|
|
@ -642,6 +642,14 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int __sock_sendmsg(struct socket *sock, struct msghdr *msg)
|
||||
{
|
||||
int err = security_socket_sendmsg(sock, msg,
|
||||
msg_data_left(msg));
|
||||
|
||||
return err ?: sock_sendmsg_nosec(sock, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* sock_sendmsg - send a message through @sock
|
||||
* @sock: socket
|
||||
|
|
@ -652,10 +660,19 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
|
|||
*/
|
||||
int sock_sendmsg(struct socket *sock, struct msghdr *msg)
|
||||
{
|
||||
int err = security_socket_sendmsg(sock, msg,
|
||||
msg_data_left(msg));
|
||||
struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name;
|
||||
struct sockaddr_storage address;
|
||||
int ret;
|
||||
|
||||
return err ?: sock_sendmsg_nosec(sock, msg);
|
||||
if (msg->msg_name) {
|
||||
memcpy(&address, msg->msg_name, msg->msg_namelen);
|
||||
msg->msg_name = &address;
|
||||
}
|
||||
|
||||
ret = __sock_sendmsg(sock, msg);
|
||||
msg->msg_name = save_addr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sock_sendmsg);
|
||||
|
||||
|
|
@ -987,7 +1004,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
|||
if (sock->type == SOCK_SEQPACKET)
|
||||
msg.msg_flags |= MSG_EOR;
|
||||
|
||||
res = sock_sendmsg(sock, &msg);
|
||||
res = __sock_sendmsg(sock, &msg);
|
||||
*from = msg.msg_iter;
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1939,7 +1956,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
|
|||
if (sock->file->f_flags & O_NONBLOCK)
|
||||
flags |= MSG_DONTWAIT;
|
||||
msg.msg_flags = flags;
|
||||
err = sock_sendmsg(sock, &msg);
|
||||
err = __sock_sendmsg(sock, &msg);
|
||||
|
||||
out_put:
|
||||
fput_light(sock->file, fput_needed);
|
||||
|
|
@ -2284,7 +2301,7 @@ static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
|
|||
err = sock_sendmsg_nosec(sock, msg_sys);
|
||||
goto out_freectl;
|
||||
}
|
||||
err = sock_sendmsg(sock, msg_sys);
|
||||
err = __sock_sendmsg(sock, msg_sys);
|
||||
/*
|
||||
* If this is sendmmsg() and sending to current destination address was
|
||||
* successful, remember it.
|
||||
|
|
@ -3568,7 +3585,11 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd,
|
|||
|
||||
int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
return sock->ops->bind(sock, addr, addrlen);
|
||||
struct sockaddr_storage address;
|
||||
|
||||
memcpy(&address, addr, addrlen);
|
||||
|
||||
return sock->ops->bind(sock, (struct sockaddr *)&address, addrlen);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_bind);
|
||||
|
||||
|
|
@ -3638,7 +3659,11 @@ EXPORT_SYMBOL(kernel_accept);
|
|||
int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
|
||||
int flags)
|
||||
{
|
||||
return sock->ops->connect(sock, addr, addrlen, flags);
|
||||
struct sockaddr_storage address;
|
||||
|
||||
memcpy(&address, addr, addrlen);
|
||||
|
||||
return sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_connect);
|
||||
|
||||
|
|
|
|||
|
|
@ -2684,6 +2684,7 @@ out_msg_denied:
|
|||
case rpc_autherr_rejectedverf:
|
||||
case rpcsec_gsserr_credproblem:
|
||||
case rpcsec_gsserr_ctxproblem:
|
||||
rpcauth_invalcred(task);
|
||||
if (!task->tk_cred_retry)
|
||||
break;
|
||||
task->tk_cred_retry--;
|
||||
|
|
|
|||
|
|
@ -807,7 +807,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
|
|||
psock = sk_psock_get(sk);
|
||||
if (!psock || !policy) {
|
||||
err = tls_push_record(sk, flags, record_type);
|
||||
if (err && sk->sk_err == EBADMSG) {
|
||||
if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
|
||||
*copied -= sk_msg_free(sk, msg);
|
||||
tls_free_open_rec(sk);
|
||||
err = -sk->sk_err;
|
||||
|
|
@ -836,7 +836,7 @@ more_data:
|
|||
switch (psock->eval) {
|
||||
case __SK_PASS:
|
||||
err = tls_push_record(sk, flags, record_type);
|
||||
if (err && sk->sk_err == EBADMSG) {
|
||||
if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
|
||||
*copied -= sk_msg_free(sk, msg);
|
||||
tls_free_open_rec(sk);
|
||||
err = -sk->sk_err;
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
|
|||
* What the above comment does talk about? --ANK(980817)
|
||||
*/
|
||||
|
||||
if (unix_tot_inflight)
|
||||
if (READ_ONCE(unix_tot_inflight))
|
||||
unix_gc(); /* Garbage collect fds */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void unix_inflight(struct user_struct *user, struct file *fp)
|
|||
/* Paired with READ_ONCE() in wait_for_unix_gc() */
|
||||
WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1);
|
||||
}
|
||||
user->unix_inflight++;
|
||||
WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1);
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)
|
|||
/* Paired with READ_ONCE() in wait_for_unix_gc() */
|
||||
WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1);
|
||||
}
|
||||
user->unix_inflight--;
|
||||
WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1);
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ static inline bool too_many_unix_fds(struct task_struct *p)
|
|||
{
|
||||
struct user_struct *user = current_user();
|
||||
|
||||
if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
|
||||
if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE)))
|
||||
return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7132,7 +7132,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb,
|
|||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct mesh_config cfg;
|
||||
struct mesh_config cfg = {};
|
||||
u32 mask;
|
||||
int err;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
# Makefile for the XFRM subsystem.
|
||||
#
|
||||
|
||||
xfrm_interface-$(CONFIG_XFRM_INTERFACE) += xfrm_interface_core.o
|
||||
|
||||
obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
|
||||
xfrm_input.o xfrm_output.o \
|
||||
xfrm_sysctl.o xfrm_replay.o xfrm_device.o
|
||||
|
|
|
|||
|
|
@ -354,8 +354,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IPV6):
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
if (!dst) {
|
||||
fl.u.ip6.flowi6_oif = dev->ifindex;
|
||||
fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
|
||||
|
|
@ -369,8 +369,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
break;
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
if (!dst) {
|
||||
struct rtable *rt;
|
||||
|
||||
|
|
@ -522,7 +522,7 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
|
|||
struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
|
||||
struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
|
||||
|
||||
if (re) {
|
||||
if (re && x->replay_esn && x->preplay_esn) {
|
||||
struct xfrm_replay_state_esn *replay_esn;
|
||||
replay_esn = nla_data(re);
|
||||
memcpy(x->replay_esn, replay_esn,
|
||||
|
|
@ -2633,7 +2633,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
|
|||
[XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
|
||||
[XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
|
||||
[XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) },
|
||||
[XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
|
||||
[XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
|
||||
[XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
|
||||
|
|
|
|||
Loading…
Reference in a new issue