This is the 4.9.177 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlzdoVMACgkQONu9yGCS aT4qIQ//XMYZIYkQGwN57TzWVqaE1TqutVHuAnc+k111hEl4Af9bKedyOQKoA7EF WzWau8wUKZsoAegoHbao29Ow5JE6iO0Qy9hjgRIbHRQA+IziPmYbJZ/zE2KBZFyH LlC3cxcCujABPtdfSq8/ChXpvtcQAtvGLWwpppHxIhYUC0WPTlzdMYqCDR6DxJbQ Z1KKTjR4uEH2d7XwsRsBfoEeYiHL4Wi33ZFjN3IeXOjNiN54QIdH3INsEkOlugxE NmoZrkyMzh8wkVlhAhpimREI5+0YSjxyEBbi7Qdo76+dK7NHdR6AHMh4/l/i8Ytc qMK7tgXQ0VjZlsfZ1a803XEcM0TY/j4zGdSInpmKOP5uR1IsBz+THidKNlwmB4ZT AZjzgfLz/lmRm8W58SSSL1y9g1sNFJcziUjAq0j24kWseeTRd1gcooZP+RJBtHhN zGnG54l67RW1POFK+1sAIUElHrx36FMrAD3ae3nwUW7I91XO65ODS59S6xJJMzjl qKV6jm7ZhqvyCJKkxWDq9pSBE5EMccaFQpnzy1oQhxh1nFLaK9+jsAkbfey6tAjC d0hsqgUXRF8yFGUSE/Nd7LEn8Pf9lFl8GTrsF13xLXXuWknsFulmOnu8h8nNPnDG i8Os9NfS7VImodPCvGAXF+ACtlbzCiTYJhebiZw8Ak0+vSeURyQ= =O1S8 -----END PGP SIGNATURE----- Merge 4.9.177 into android-4.9 Changes in 4.9.177 netfilter: compat: initialize all fields in xt_init bpf: fix struct htab_elem layout bpf: convert htab map to hlist_nulls platform/x86: sony-laptop: Fix unintentional fall-through USB: serial: fix unthrottle races iio: adc: xilinx: fix potential use-after-free on remove libnvdimm/namespace: Fix a potential NULL pointer dereference HID: input: add mapping for Expose/Overview key HID: input: add mapping for keyboard Brightness Up/Down/Toggle keys HID: input: add mapping for "Toggle Display" key libnvdimm/btt: Fix a kmemdup failure check s390/dasd: Fix capacity calculation for large volumes mac80211: fix unaligned access in mesh table hash function s390/3270: fix lockdep false positive on view->lock mISDN: Check address length before reading address family x86/reboot, efi: Use EFI reboot for Acer TravelMate X514-51T KVM: x86: avoid misreporting level-triggered irqs as edge-triggered in tracing tools lib traceevent: Fix missing equality check for strcmp init: initialize jump labels before command line option parsing selftests: netfilter: check icmp pkttoobig errors are set as related ipvs: do not schedule icmp errors from tunnels MIPS: perf: ath79: Fix perfcount IRQ assignment s390: ctcm: fix ctcm_new_device error return code drm/sun4i: Set device driver data at bind time for use in unbind selftests/net: correct the return value for run_netsocktests gpu: ipu-v3: dp: fix CSC handling spi: Micrel eth switch: declare missing of table spi: ST ST95HF NFC: declare missing of table Input: synaptics-rmi4 - fix possible double free cw1200: fix missing unlock on error in cw1200_hw_scan() ALSA: pcm: remove SNDRV_PCM_IOCTL1_INFO internal command rtlwifi: rtl8723ae: Fix missing break in switch statement Don't jump to compute_result state from check_result state Revert "x86/vdso: Drop implicit common-page-size linker flag" Revert "x86: vdso: Use $LD instead of $CC to link" x86: vdso: Use $LD instead of $CC to link x86/vdso: Drop implicit common-page-size linker flag x86/vdso: Pass --eh-frame-hdr to the linker powerpc/64s: Include cpu header bridge: Fix error path for kobject_init_and_add() fib_rules: return 0 directly if an exactly same rule exists when NLM_F_EXCL not supplied net: ucc_geth - fix Oops when changing number of buffers in the ring packet: Fix error path in packet_init vlan: disable SIOCSHWTSTAMP in container vrf: sit mtu should not be updated when vrf netdev is the link ipv4: Fix raw socket lookup for local traffic bonding: fix arp_validate toggling in active-backup mode drivers/virt/fsl_hypervisor.c: dereferencing error pointers in ioctl drivers/virt/fsl_hypervisor.c: prevent integer overflow in ioctl powerpc/lib: fix book3s/32 boot failure due to code patching powerpc/booke64: set RI in default MSR Linux 4.9.177 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
e6d81da784
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 9
|
PATCHLEVEL = 9
|
||||||
SUBLEVEL = 176
|
SUBLEVEL = 177
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Roaring Lionus
|
NAME = Roaring Lionus
|
||||||
|
|
||||||
|
|
|
@ -183,12 +183,6 @@ const char *get_system_type(void)
|
||||||
return ath79_sys_type;
|
return ath79_sys_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_c0_perfcount_int(void)
|
|
||||||
{
|
|
||||||
return ATH79_MISC_IRQ(5);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
|
||||||
|
|
||||||
unsigned int get_c0_compare_int(void)
|
unsigned int get_c0_compare_int(void)
|
||||||
{
|
{
|
||||||
return CP0_LEGACY_COMPARE_IRQ;
|
return CP0_LEGACY_COMPARE_IRQ;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#if defined(CONFIG_PPC_BOOK3E_64)
|
#if defined(CONFIG_PPC_BOOK3E_64)
|
||||||
#define MSR_64BIT MSR_CM
|
#define MSR_64BIT MSR_CM
|
||||||
|
|
||||||
#define MSR_ (MSR_ME | MSR_CE)
|
#define MSR_ (MSR_ME | MSR_RI | MSR_CE)
|
||||||
#define MSR_KERNEL (MSR_ | MSR_64BIT)
|
#define MSR_KERNEL (MSR_ | MSR_64BIT)
|
||||||
#define MSR_USER32 (MSR_ | MSR_PR | MSR_EE)
|
#define MSR_USER32 (MSR_ | MSR_PR | MSR_EE)
|
||||||
#define MSR_USER64 (MSR_USER32 | MSR_64BIT)
|
#define MSR_USER64 (MSR_USER32 | MSR_64BIT)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//
|
//
|
||||||
// Copyright 2018, Michael Ellerman, IBM Corporation.
|
// Copyright 2018, Michael Ellerman, IBM Corporation.
|
||||||
|
|
||||||
|
#include <linux/cpu.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
|
|
@ -23,7 +23,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Make sure we aren't patching a freed init section */
|
/* Make sure we aren't patching a freed init section */
|
||||||
if (init_mem_is_free && init_section_contains(addr, 4)) {
|
if (*PTRRELOC(&init_mem_is_free) && init_section_contains(addr, 4)) {
|
||||||
pr_debug("Skipping init section patching addr: 0x%px\n", addr);
|
pr_debug("Skipping init section patching addr: 0x%px\n", addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,8 @@ quiet_cmd_vdso = VDSO $@
|
||||||
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
||||||
|
|
||||||
VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
|
VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
|
||||||
$(call ld-option, --build-id) -Bsymbolic
|
$(call ld-option, --build-id) $(call ld-option, --eh-frame-hdr) \
|
||||||
|
-Bsymbolic
|
||||||
GCOV_PROFILE := n
|
GCOV_PROFILE := n
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -82,6 +82,19 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some machines don't handle the default ACPI reboot method and
|
||||||
|
* require the EFI reboot method:
|
||||||
|
*/
|
||||||
|
static int __init set_efi_reboot(const struct dmi_system_id *d)
|
||||||
|
{
|
||||||
|
if (reboot_type != BOOT_EFI && !efi_runtime_disabled()) {
|
||||||
|
reboot_type = BOOT_EFI;
|
||||||
|
pr_info("%s series board detected. Selecting EFI-method for reboot.\n", d->ident);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void __noreturn machine_real_restart(unsigned int type)
|
void __noreturn machine_real_restart(unsigned int type)
|
||||||
{
|
{
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
@ -167,6 +180,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ /* Handle reboot issue on Acer TravelMate X514-51T */
|
||||||
|
.callback = set_efi_reboot,
|
||||||
|
.ident = "Acer TravelMate X514-51T",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate X514-51T"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/* Apple */
|
/* Apple */
|
||||||
{ /* Handle problems with rebooting on Apple MacBook5 */
|
{ /* Handle problems with rebooting on Apple MacBook5 */
|
||||||
|
|
|
@ -434,13 +434,13 @@ TRACE_EVENT(kvm_apic_ipi,
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(kvm_apic_accept_irq,
|
TRACE_EVENT(kvm_apic_accept_irq,
|
||||||
TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec),
|
TP_PROTO(__u32 apicid, __u16 dm, __u16 tm, __u8 vec),
|
||||||
TP_ARGS(apicid, dm, tm, vec),
|
TP_ARGS(apicid, dm, tm, vec),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__field( __u32, apicid )
|
__field( __u32, apicid )
|
||||||
__field( __u16, dm )
|
__field( __u16, dm )
|
||||||
__field( __u8, tm )
|
__field( __u16, tm )
|
||||||
__field( __u8, vec )
|
__field( __u8, vec )
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,8 @@ static int sun4i_drv_bind(struct device *dev)
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free_drm;
|
goto free_drm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_set_drvdata(dev, drm);
|
||||||
drm->dev_private = drv;
|
drm->dev_private = drv;
|
||||||
|
|
||||||
drm_vblank_init(drm, 1);
|
drm_vblank_init(drm, 1);
|
||||||
|
|
|
@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
|
||||||
ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
|
ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
|
||||||
DP_COM_CONF_CSC_DEF_BOTH);
|
DP_COM_CONF_CSC_DEF_BOTH);
|
||||||
} else {
|
} else {
|
||||||
if (flow->foreground.in_cs == flow->out_cs)
|
if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
|
||||||
|
flow->foreground.in_cs == flow->out_cs)
|
||||||
/*
|
/*
|
||||||
* foreground identical to output, apply color
|
* foreground identical to output, apply color
|
||||||
* conversion on background
|
* conversion on background
|
||||||
|
@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp)
|
||||||
struct ipu_dp_priv *priv = flow->priv;
|
struct ipu_dp_priv *priv = flow->priv;
|
||||||
u32 reg, csc;
|
u32 reg, csc;
|
||||||
|
|
||||||
|
dp->in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
||||||
|
|
||||||
if (!dp->foreground)
|
if (!dp->foreground)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp)
|
||||||
|
|
||||||
reg = readl(flow->base + DP_COM_CONF);
|
reg = readl(flow->base + DP_COM_CONF);
|
||||||
csc = reg & DP_COM_CONF_CSC_DEF_MASK;
|
csc = reg & DP_COM_CONF_CSC_DEF_MASK;
|
||||||
if (csc == DP_COM_CONF_CSC_DEF_FG)
|
reg &= ~DP_COM_CONF_CSC_DEF_MASK;
|
||||||
reg &= ~DP_COM_CONF_CSC_DEF_MASK;
|
if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG)
|
||||||
|
reg |= DP_COM_CONF_CSC_DEF_BG;
|
||||||
|
|
||||||
reg &= ~DP_COM_CONF_FG_EN;
|
reg &= ~DP_COM_CONF_FG_EN;
|
||||||
writel(reg, flow->base + DP_COM_CONF);
|
writel(reg, flow->base + DP_COM_CONF);
|
||||||
|
@ -350,6 +354,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
|
||||||
mutex_init(&priv->mutex);
|
mutex_init(&priv->mutex);
|
||||||
|
|
||||||
for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
|
for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
|
||||||
|
priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
||||||
|
priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
||||||
priv->flow[i].foreground.foreground = true;
|
priv->flow[i].foreground.foreground = true;
|
||||||
priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
|
priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
|
||||||
priv->flow[i].priv = priv;
|
priv->flow[i].priv = priv;
|
||||||
|
|
|
@ -607,6 +607,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */
|
||||||
|
switch (usage->hid & 0xf) {
|
||||||
|
case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
|
||||||
|
default: goto ignore;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some lazy vendors declare 255 usages for System Control,
|
* Some lazy vendors declare 255 usages for System Control,
|
||||||
* leading to the creation of ABS_X|Y axis and too many others.
|
* leading to the creation of ABS_X|Y axis and too many others.
|
||||||
|
@ -802,6 +810,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||||
case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break;
|
case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break;
|
||||||
case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break;
|
case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break;
|
||||||
|
|
||||||
|
case 0x079: map_key_clear(KEY_KBDILLUMUP); break;
|
||||||
|
case 0x07a: map_key_clear(KEY_KBDILLUMDOWN); break;
|
||||||
|
case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE); break;
|
||||||
|
|
||||||
case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
||||||
case 0x083: map_key_clear(KEY_LAST); break;
|
case 0x083: map_key_clear(KEY_LAST); break;
|
||||||
case 0x084: map_key_clear(KEY_ENTER); break;
|
case 0x084: map_key_clear(KEY_ENTER); break;
|
||||||
|
@ -932,6 +944,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||||
case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
|
case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
|
||||||
case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
|
case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
|
||||||
|
|
||||||
|
case 0x29f: map_key_clear(KEY_SCALE); break;
|
||||||
|
|
||||||
default: map_key_clear(KEY_UNKNOWN);
|
default: map_key_clear(KEY_UNKNOWN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1299,7 +1299,7 @@ static int xadc_remove(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
free_irq(irq, indio_dev);
|
free_irq(irq, indio_dev);
|
||||||
clk_disable_unprepare(xadc->clk);
|
clk_disable_unprepare(xadc->clk);
|
||||||
cancel_delayed_work(&xadc->zynq_unmask_work);
|
cancel_delayed_work_sync(&xadc->zynq_unmask_work);
|
||||||
kfree(xadc->data);
|
kfree(xadc->data);
|
||||||
kfree(indio_dev->channels);
|
kfree(indio_dev->channels);
|
||||||
|
|
||||||
|
|
|
@ -772,7 +772,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
|
||||||
|
|
||||||
error = rmi_register_function(fn);
|
error = rmi_register_function(fn);
|
||||||
if (error)
|
if (error)
|
||||||
goto err_put_fn;
|
return error;
|
||||||
|
|
||||||
if (pdt->function_number == 0x01)
|
if (pdt->function_number == 0x01)
|
||||||
data->f01_container = fn;
|
data->f01_container = fn;
|
||||||
|
@ -780,10 +780,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
|
||||||
list_add_tail(&fn->node, &data->function_list);
|
list_add_tail(&fn->node, &data->function_list);
|
||||||
|
|
||||||
return RMI_SCAN_CONTINUE;
|
return RMI_SCAN_CONTINUE;
|
||||||
|
|
||||||
err_put_fn:
|
|
||||||
put_device(&fn->dev);
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int rmi_driver_suspend(struct rmi_device *rmi_dev)
|
int rmi_driver_suspend(struct rmi_device *rmi_dev)
|
||||||
|
|
|
@ -22,6 +22,15 @@
|
||||||
#define AR71XX_RESET_REG_MISC_INT_ENABLE 4
|
#define AR71XX_RESET_REG_MISC_INT_ENABLE 4
|
||||||
|
|
||||||
#define ATH79_MISC_IRQ_COUNT 32
|
#define ATH79_MISC_IRQ_COUNT 32
|
||||||
|
#define ATH79_MISC_PERF_IRQ 5
|
||||||
|
|
||||||
|
static int ath79_perfcount_irq;
|
||||||
|
|
||||||
|
int get_c0_perfcount_int(void)
|
||||||
|
{
|
||||||
|
return ath79_perfcount_irq;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
||||||
|
|
||||||
static void ath79_misc_irq_handler(struct irq_desc *desc)
|
static void ath79_misc_irq_handler(struct irq_desc *desc)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +122,8 @@ static void __init ath79_misc_intc_domain_init(
|
||||||
{
|
{
|
||||||
void __iomem *base = domain->host_data;
|
void __iomem *base = domain->host_data;
|
||||||
|
|
||||||
|
ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ);
|
||||||
|
|
||||||
/* Disable and clear all interrupts */
|
/* Disable and clear all interrupts */
|
||||||
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||||
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
||||||
|
|
|
@ -712,10 +712,10 @@ base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!maddr || maddr->family != AF_ISDN)
|
if (addr_len < sizeof(struct sockaddr_mISDN))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (addr_len < sizeof(struct sockaddr_mISDN))
|
if (!maddr || maddr->family != AF_ISDN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
|
@ -3914,26 +3914,15 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
|
||||||
case check_state_check_result:
|
case check_state_check_result:
|
||||||
sh->check_state = check_state_idle;
|
sh->check_state = check_state_idle;
|
||||||
|
|
||||||
|
if (s->failed > 1)
|
||||||
|
break;
|
||||||
/* handle a successful check operation, if parity is correct
|
/* handle a successful check operation, if parity is correct
|
||||||
* we are done. Otherwise update the mismatch count and repair
|
* we are done. Otherwise update the mismatch count and repair
|
||||||
* parity if !MD_RECOVERY_CHECK
|
* parity if !MD_RECOVERY_CHECK
|
||||||
*/
|
*/
|
||||||
if (sh->ops.zero_sum_result == 0) {
|
if (sh->ops.zero_sum_result == 0) {
|
||||||
/* both parities are correct */
|
/* Any parity checked was correct */
|
||||||
if (!s->failed)
|
set_bit(STRIPE_INSYNC, &sh->state);
|
||||||
set_bit(STRIPE_INSYNC, &sh->state);
|
|
||||||
else {
|
|
||||||
/* in contrast to the raid5 case we can validate
|
|
||||||
* parity, but still have a failure to write
|
|
||||||
* back
|
|
||||||
*/
|
|
||||||
sh->check_state = check_state_compute_result;
|
|
||||||
/* Returning at this point means that we may go
|
|
||||||
* off and bring p and/or q uptodate again so
|
|
||||||
* we make sure to check zero_sum_result again
|
|
||||||
* to verify if p or q need writeback
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
|
atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
|
||||||
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
|
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
|
||||||
|
|
|
@ -1065,13 +1065,6 @@ static int bond_option_arp_validate_set(struct bonding *bond,
|
||||||
{
|
{
|
||||||
netdev_info(bond->dev, "Setting arp_validate to %s (%llu)\n",
|
netdev_info(bond->dev, "Setting arp_validate to %s (%llu)\n",
|
||||||
newval->string, newval->value);
|
newval->string, newval->value);
|
||||||
|
|
||||||
if (bond->dev->flags & IFF_UP) {
|
|
||||||
if (!newval->value)
|
|
||||||
bond->recv_probe = NULL;
|
|
||||||
else if (bond->params.arp_interval)
|
|
||||||
bond->recv_probe = bond_arp_rcv;
|
|
||||||
}
|
|
||||||
bond->params.arp_validate = newval->value;
|
bond->params.arp_validate = newval->value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -250,14 +250,12 @@ uec_set_ringparam(struct net_device *netdev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (netif_running(netdev))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
ug_info->bdRingLenRx[queue] = ring->rx_pending;
|
ug_info->bdRingLenRx[queue] = ring->rx_pending;
|
||||||
ug_info->bdRingLenTx[queue] = ring->tx_pending;
|
ug_info->bdRingLenTx[queue] = ring->tx_pending;
|
||||||
|
|
||||||
if (netif_running(netdev)) {
|
|
||||||
/* FIXME: restart automatically */
|
|
||||||
netdev_info(netdev, "Please re-open the interface\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,14 @@ static const struct spi_device_id ks8995_id[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(spi, ks8995_id);
|
MODULE_DEVICE_TABLE(spi, ks8995_id);
|
||||||
|
|
||||||
|
static const struct of_device_id ks8895_spi_of_match[] = {
|
||||||
|
{ .compatible = "micrel,ks8995" },
|
||||||
|
{ .compatible = "micrel,ksz8864" },
|
||||||
|
{ .compatible = "micrel,ksz8795" },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ks8895_spi_of_match);
|
||||||
|
|
||||||
static inline u8 get_chip_id(u8 val)
|
static inline u8 get_chip_id(u8 val)
|
||||||
{
|
{
|
||||||
return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
|
return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
|
||||||
|
@ -529,6 +537,7 @@ static int ks8995_remove(struct spi_device *spi)
|
||||||
static struct spi_driver ks8995_driver = {
|
static struct spi_driver ks8995_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "spi-ks8995",
|
.name = "spi-ks8995",
|
||||||
|
.of_match_table = of_match_ptr(ks8895_spi_of_match),
|
||||||
},
|
},
|
||||||
.probe = ks8995_probe,
|
.probe = ks8995_probe,
|
||||||
.remove = ks8995_remove,
|
.remove = ks8995_remove,
|
||||||
|
|
|
@ -1703,6 +1703,7 @@ static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw,
|
||||||
rtlhal->oem_id = RT_CID_819X_LENOVO;
|
rtlhal->oem_id = RT_CID_819X_LENOVO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case 0x1025:
|
case 0x1025:
|
||||||
rtlhal->oem_id = RT_CID_819X_ACER;
|
rtlhal->oem_id = RT_CID_819X_ACER;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -84,8 +84,11 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
|
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
|
||||||
req->ie_len);
|
req->ie_len);
|
||||||
if (!frame.skb)
|
if (!frame.skb) {
|
||||||
|
mutex_unlock(&priv->conf_mutex);
|
||||||
|
up(&priv->scan.lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (req->ie_len)
|
if (req->ie_len)
|
||||||
memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
|
memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
|
||||||
|
|
|
@ -1074,6 +1074,12 @@ static const struct spi_device_id st95hf_id[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(spi, st95hf_id);
|
MODULE_DEVICE_TABLE(spi, st95hf_id);
|
||||||
|
|
||||||
|
static const struct of_device_id st95hf_spi_of_match[] = {
|
||||||
|
{ .compatible = "st,st95hf" },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, st95hf_spi_of_match);
|
||||||
|
|
||||||
static int st95hf_probe(struct spi_device *nfc_spi_dev)
|
static int st95hf_probe(struct spi_device *nfc_spi_dev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1260,6 +1266,7 @@ static struct spi_driver st95hf_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "st95hf",
|
.name = "st95hf",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = of_match_ptr(st95hf_spi_of_match),
|
||||||
},
|
},
|
||||||
.id_table = st95hf_id,
|
.id_table = st95hf_id,
|
||||||
.probe = st95hf_probe,
|
.probe = st95hf_probe,
|
||||||
|
|
|
@ -190,14 +190,15 @@ static struct device *__nd_btt_create(struct nd_region *nd_region,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL);
|
nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL);
|
||||||
if (nd_btt->id < 0) {
|
if (nd_btt->id < 0)
|
||||||
kfree(nd_btt);
|
goto out_nd_btt;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nd_btt->lbasize = lbasize;
|
nd_btt->lbasize = lbasize;
|
||||||
if (uuid)
|
if (uuid) {
|
||||||
uuid = kmemdup(uuid, 16, GFP_KERNEL);
|
uuid = kmemdup(uuid, 16, GFP_KERNEL);
|
||||||
|
if (!uuid)
|
||||||
|
goto out_put_id;
|
||||||
|
}
|
||||||
nd_btt->uuid = uuid;
|
nd_btt->uuid = uuid;
|
||||||
dev = &nd_btt->dev;
|
dev = &nd_btt->dev;
|
||||||
dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id);
|
dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id);
|
||||||
|
@ -212,6 +213,13 @@ static struct device *__nd_btt_create(struct nd_region *nd_region,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
|
out_put_id:
|
||||||
|
ida_simple_remove(&nd_region->btt_ida, nd_btt->id);
|
||||||
|
|
||||||
|
out_nd_btt:
|
||||||
|
kfree(nd_btt);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct device *nd_btt_create(struct nd_region *nd_region)
|
struct device *nd_btt_create(struct nd_region *nd_region)
|
||||||
|
|
|
@ -2028,9 +2028,12 @@ struct device *create_namespace_blk(struct nd_region *nd_region,
|
||||||
if (!nsblk->uuid)
|
if (!nsblk->uuid)
|
||||||
goto blk_err;
|
goto blk_err;
|
||||||
memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
|
memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
|
||||||
if (name[0])
|
if (name[0]) {
|
||||||
nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN,
|
nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
if (!nsblk->alt_name)
|
||||||
|
goto blk_err;
|
||||||
|
}
|
||||||
res = nsblk_add_resource(nd_region, ndd, nsblk,
|
res = nsblk_add_resource(nd_region, ndd, nsblk,
|
||||||
__le64_to_cpu(nd_label->dpa));
|
__le64_to_cpu(nd_label->dpa));
|
||||||
if (!res)
|
if (!res)
|
||||||
|
|
|
@ -4422,14 +4422,16 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
|
||||||
}
|
}
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
dprintk("Resource %d isn't an IRQ nor an IO port\n",
|
|
||||||
resource->type);
|
|
||||||
|
|
||||||
case ACPI_RESOURCE_TYPE_END_TAG:
|
case ACPI_RESOURCE_TYPE_END_TAG:
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dprintk("Resource %d isn't an IRQ nor an IO port\n",
|
||||||
|
resource->type);
|
||||||
|
return AE_CTRL_TERMINATE;
|
||||||
|
|
||||||
}
|
}
|
||||||
return AE_CTRL_TERMINATE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sony_pic_possible_resources(struct acpi_device *device)
|
static int sony_pic_possible_resources(struct acpi_device *device)
|
||||||
|
|
|
@ -2054,14 +2054,14 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
|
||||||
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
|
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
|
||||||
|
|
||||||
raw:
|
raw:
|
||||||
block->blocks = (private->real_cyl *
|
block->blocks = ((unsigned long) private->real_cyl *
|
||||||
private->rdc_data.trk_per_cyl *
|
private->rdc_data.trk_per_cyl *
|
||||||
blk_per_trk);
|
blk_per_trk);
|
||||||
|
|
||||||
dev_info(&device->cdev->dev,
|
dev_info(&device->cdev->dev,
|
||||||
"DASD with %d KB/block, %d KB total size, %d KB/track, "
|
"DASD with %u KB/block, %lu KB total size, %u KB/track, "
|
||||||
"%s\n", (block->bp_block >> 10),
|
"%s\n", (block->bp_block >> 10),
|
||||||
((private->real_cyl *
|
(((unsigned long) private->real_cyl *
|
||||||
private->rdc_data.trk_per_cyl *
|
private->rdc_data.trk_per_cyl *
|
||||||
blk_per_trk * (block->bp_block >> 9)) >> 1),
|
blk_per_trk * (block->bp_block >> 9)) >> 1),
|
||||||
((blk_per_trk * block->bp_block) >> 10),
|
((blk_per_trk * block->bp_block) >> 10),
|
||||||
|
|
|
@ -628,7 +628,7 @@ con3270_init(void)
|
||||||
(void (*)(unsigned long)) con3270_read_tasklet,
|
(void (*)(unsigned long)) con3270_read_tasklet,
|
||||||
(unsigned long) condev->read);
|
(unsigned long) condev->read);
|
||||||
|
|
||||||
raw3270_add_view(&condev->view, &con3270_fn, 1);
|
raw3270_add_view(&condev->view, &con3270_fn, 1, RAW3270_VIEW_LOCK_IRQ);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&condev->freemem);
|
INIT_LIST_HEAD(&condev->freemem);
|
||||||
for (i = 0; i < CON3270_STRING_PAGES; i++) {
|
for (i = 0; i < CON3270_STRING_PAGES; i++) {
|
||||||
|
|
|
@ -462,7 +462,8 @@ fs3270_open(struct inode *inode, struct file *filp)
|
||||||
|
|
||||||
init_waitqueue_head(&fp->wait);
|
init_waitqueue_head(&fp->wait);
|
||||||
fp->fs_pid = get_pid(task_pid(current));
|
fp->fs_pid = get_pid(task_pid(current));
|
||||||
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
|
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor,
|
||||||
|
RAW3270_VIEW_LOCK_BH);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fs3270_free_view(&fp->view);
|
fs3270_free_view(&fp->view);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -919,7 +919,7 @@ raw3270_deactivate_view(struct raw3270_view *view)
|
||||||
* Add view to device with minor "minor".
|
* Add view to device with minor "minor".
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
|
raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor, int subclass)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct raw3270 *rp;
|
struct raw3270 *rp;
|
||||||
|
@ -941,6 +941,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
|
||||||
view->cols = rp->cols;
|
view->cols = rp->cols;
|
||||||
view->ascebc = rp->ascebc;
|
view->ascebc = rp->ascebc;
|
||||||
spin_lock_init(&view->lock);
|
spin_lock_init(&view->lock);
|
||||||
|
lockdep_set_subclass(&view->lock, subclass);
|
||||||
list_add(&view->list, &rp->view_list);
|
list_add(&view->list, &rp->view_list);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
|
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
|
||||||
|
|
|
@ -149,6 +149,8 @@ struct raw3270_fn {
|
||||||
struct raw3270_view {
|
struct raw3270_view {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
#define RAW3270_VIEW_LOCK_IRQ 0
|
||||||
|
#define RAW3270_VIEW_LOCK_BH 1
|
||||||
atomic_t ref_count;
|
atomic_t ref_count;
|
||||||
struct raw3270 *dev;
|
struct raw3270 *dev;
|
||||||
struct raw3270_fn *fn;
|
struct raw3270_fn *fn;
|
||||||
|
@ -157,7 +159,7 @@ struct raw3270_view {
|
||||||
unsigned char *ascebc; /* ascii -> ebcdic table */
|
unsigned char *ascebc; /* ascii -> ebcdic table */
|
||||||
};
|
};
|
||||||
|
|
||||||
int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
|
int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int);
|
||||||
int raw3270_activate_view(struct raw3270_view *);
|
int raw3270_activate_view(struct raw3270_view *);
|
||||||
void raw3270_del_view(struct raw3270_view *);
|
void raw3270_del_view(struct raw3270_view *);
|
||||||
void raw3270_deactivate_view(struct raw3270_view *);
|
void raw3270_deactivate_view(struct raw3270_view *);
|
||||||
|
|
|
@ -978,7 +978,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||||
return PTR_ERR(tp);
|
return PTR_ERR(tp);
|
||||||
|
|
||||||
rc = raw3270_add_view(&tp->view, &tty3270_fn,
|
rc = raw3270_add_view(&tp->view, &tty3270_fn,
|
||||||
tty->index + RAW3270_FIRSTMINOR);
|
tty->index + RAW3270_FIRSTMINOR,
|
||||||
|
RAW3270_VIEW_LOCK_BH);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
tty3270_free_view(tp);
|
tty3270_free_view(tp);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -1595,6 +1595,7 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
|
||||||
if (priv->channel[direction] == NULL) {
|
if (priv->channel[direction] == NULL) {
|
||||||
if (direction == CTCM_WRITE)
|
if (direction == CTCM_WRITE)
|
||||||
channel_free(priv->channel[CTCM_READ]);
|
channel_free(priv->channel[CTCM_READ]);
|
||||||
|
result = -ENODEV;
|
||||||
goto out_dev;
|
goto out_dev;
|
||||||
}
|
}
|
||||||
priv->channel[direction]->netdev = dev;
|
priv->channel[direction]->netdev = dev;
|
||||||
|
|
|
@ -350,6 +350,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
|
||||||
struct usb_serial_port *port = urb->context;
|
struct usb_serial_port *port = urb->context;
|
||||||
unsigned char *data = urb->transfer_buffer;
|
unsigned char *data = urb->transfer_buffer;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
bool stopped = false;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -357,33 +358,51 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
|
||||||
if (urb == port->read_urbs[i])
|
if (urb == port->read_urbs[i])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
set_bit(i, &port->read_urbs_free);
|
|
||||||
|
|
||||||
dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
|
dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
|
||||||
urb->actual_length);
|
urb->actual_length);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
|
usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
|
||||||
|
data);
|
||||||
|
port->serial->type->process_read_urb(urb);
|
||||||
break;
|
break;
|
||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
case -ECONNRESET:
|
case -ECONNRESET:
|
||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
dev_dbg(&port->dev, "%s - urb stopped: %d\n",
|
dev_dbg(&port->dev, "%s - urb stopped: %d\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
return;
|
stopped = true;
|
||||||
|
break;
|
||||||
case -EPIPE:
|
case -EPIPE:
|
||||||
dev_err(&port->dev, "%s - urb stopped: %d\n",
|
dev_err(&port->dev, "%s - urb stopped: %d\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
return;
|
stopped = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
|
dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
goto resubmit;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
|
/*
|
||||||
port->serial->type->process_read_urb(urb);
|
* Make sure URB processing is done before marking as free to avoid
|
||||||
|
* racing with unthrottle() on another CPU. Matches the barriers
|
||||||
|
* implied by the test_and_clear_bit() in
|
||||||
|
* usb_serial_generic_submit_read_urb().
|
||||||
|
*/
|
||||||
|
smp_mb__before_atomic();
|
||||||
|
set_bit(i, &port->read_urbs_free);
|
||||||
|
/*
|
||||||
|
* Make sure URB is marked as free before checking the throttled flag
|
||||||
|
* to avoid racing with unthrottle() on another CPU. Matches the
|
||||||
|
* smp_mb() in unthrottle().
|
||||||
|
*/
|
||||||
|
smp_mb__after_atomic();
|
||||||
|
|
||||||
|
if (stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
resubmit:
|
|
||||||
/* Throttle the device if requested by tty */
|
/* Throttle the device if requested by tty */
|
||||||
spin_lock_irqsave(&port->lock, flags);
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
port->throttled = port->throttle_req;
|
port->throttled = port->throttle_req;
|
||||||
|
@ -458,6 +477,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
|
||||||
port->throttled = port->throttle_req = 0;
|
port->throttled = port->throttle_req = 0;
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&port->lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Matches the smp_mb__after_atomic() in
|
||||||
|
* usb_serial_generic_read_bulk_callback().
|
||||||
|
*/
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (was_throttled)
|
if (was_throttled)
|
||||||
usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
|
usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,9 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p)
|
||||||
* hypervisor.
|
* hypervisor.
|
||||||
*/
|
*/
|
||||||
lb_offset = param.local_vaddr & (PAGE_SIZE - 1);
|
lb_offset = param.local_vaddr & (PAGE_SIZE - 1);
|
||||||
|
if (param.count == 0 ||
|
||||||
|
param.count > U64_MAX - lb_offset - PAGE_SIZE + 1)
|
||||||
|
return -EINVAL;
|
||||||
num_pages = (param.count + lb_offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
num_pages = (param.count + lb_offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||||
|
|
||||||
/* Allocate the buffers we need */
|
/* Allocate the buffers we need */
|
||||||
|
@ -334,8 +337,8 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
||||||
struct fsl_hv_ioctl_prop param;
|
struct fsl_hv_ioctl_prop param;
|
||||||
char __user *upath, *upropname;
|
char __user *upath, *upropname;
|
||||||
void __user *upropval;
|
void __user *upropval;
|
||||||
char *path = NULL, *propname = NULL;
|
char *path, *propname;
|
||||||
void *propval = NULL;
|
void *propval;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Get the parameters from the user. */
|
/* Get the parameters from the user. */
|
||||||
|
@ -347,32 +350,30 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
||||||
upropval = (void __user *)(uintptr_t)param.propval;
|
upropval = (void __user *)(uintptr_t)param.propval;
|
||||||
|
|
||||||
path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN);
|
path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN);
|
||||||
if (IS_ERR(path)) {
|
if (IS_ERR(path))
|
||||||
ret = PTR_ERR(path);
|
return PTR_ERR(path);
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN);
|
propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN);
|
||||||
if (IS_ERR(propname)) {
|
if (IS_ERR(propname)) {
|
||||||
ret = PTR_ERR(propname);
|
ret = PTR_ERR(propname);
|
||||||
goto out;
|
goto err_free_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.proplen > FH_DTPROP_MAX_PROPLEN) {
|
if (param.proplen > FH_DTPROP_MAX_PROPLEN) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto err_free_propname;
|
||||||
}
|
}
|
||||||
|
|
||||||
propval = kmalloc(param.proplen, GFP_KERNEL);
|
propval = kmalloc(param.proplen, GFP_KERNEL);
|
||||||
if (!propval) {
|
if (!propval) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto err_free_propname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set) {
|
if (set) {
|
||||||
if (copy_from_user(propval, upropval, param.proplen)) {
|
if (copy_from_user(propval, upropval, param.proplen)) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto err_free_propval;
|
||||||
}
|
}
|
||||||
|
|
||||||
param.ret = fh_partition_set_dtprop(param.handle,
|
param.ret = fh_partition_set_dtprop(param.handle,
|
||||||
|
@ -391,7 +392,7 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
||||||
if (copy_to_user(upropval, propval, param.proplen) ||
|
if (copy_to_user(upropval, propval, param.proplen) ||
|
||||||
put_user(param.proplen, &p->proplen)) {
|
put_user(param.proplen, &p->proplen)) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto err_free_propval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,10 +400,12 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
||||||
if (put_user(param.ret, &p->ret))
|
if (put_user(param.ret, &p->ret))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
|
||||||
out:
|
err_free_propval:
|
||||||
kfree(path);
|
|
||||||
kfree(propval);
|
kfree(propval);
|
||||||
|
err_free_propname:
|
||||||
kfree(propname);
|
kfree(propname);
|
||||||
|
err_free_path:
|
||||||
|
kfree(path);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1433,7 +1433,12 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
|
||||||
struct screen_info *si, efi_guid_t *proto,
|
struct screen_info *si, efi_guid_t *proto,
|
||||||
unsigned long size);
|
unsigned long size);
|
||||||
|
|
||||||
bool efi_runtime_disabled(void);
|
#ifdef CONFIG_EFI
|
||||||
|
extern bool efi_runtime_disabled(void);
|
||||||
|
#else
|
||||||
|
static inline bool efi_runtime_disabled(void) { return true; }
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
|
extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -29,6 +29,11 @@ struct hlist_nulls_node {
|
||||||
((ptr)->first = (struct hlist_nulls_node *) NULLS_MARKER(nulls))
|
((ptr)->first = (struct hlist_nulls_node *) NULLS_MARKER(nulls))
|
||||||
|
|
||||||
#define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member)
|
#define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member)
|
||||||
|
|
||||||
|
#define hlist_nulls_entry_safe(ptr, type, member) \
|
||||||
|
({ typeof(ptr) ____ptr = (ptr); \
|
||||||
|
!is_a_nulls(____ptr) ? hlist_nulls_entry(____ptr, type, member) : NULL; \
|
||||||
|
})
|
||||||
/**
|
/**
|
||||||
* ptr_is_a_nulls - Test if a ptr is a nulls
|
* ptr_is_a_nulls - Test if a ptr is a nulls
|
||||||
* @ptr: ptr to be tested
|
* @ptr: ptr to be tested
|
||||||
|
|
|
@ -118,5 +118,19 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
|
||||||
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
|
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
|
||||||
pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
|
pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hlist_nulls_for_each_entry_safe -
|
||||||
|
* iterate over list of given type safe against removal of list entry
|
||||||
|
* @tpos: the type * to use as a loop cursor.
|
||||||
|
* @pos: the &struct hlist_nulls_node to use as a loop cursor.
|
||||||
|
* @head: the head for your list.
|
||||||
|
* @member: the name of the hlist_nulls_node within the struct.
|
||||||
|
*/
|
||||||
|
#define hlist_nulls_for_each_entry_safe(tpos, pos, head, member) \
|
||||||
|
for (({barrier();}), \
|
||||||
|
pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \
|
||||||
|
(!is_a_nulls(pos)) && \
|
||||||
|
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); \
|
||||||
|
pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)); 1; });)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,7 +100,7 @@ struct snd_pcm_ops {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SNDRV_PCM_IOCTL1_RESET 0
|
#define SNDRV_PCM_IOCTL1_RESET 0
|
||||||
#define SNDRV_PCM_IOCTL1_INFO 1
|
/* 1 is absent slot. */
|
||||||
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
|
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
|
||||||
#define SNDRV_PCM_IOCTL1_GSTATE 3
|
#define SNDRV_PCM_IOCTL1_GSTATE 3
|
||||||
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
|
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
|
||||||
|
|
|
@ -516,6 +516,8 @@ asmlinkage __visible void __init start_kernel(void)
|
||||||
page_alloc_init();
|
page_alloc_init();
|
||||||
|
|
||||||
pr_notice("Kernel command line: %s\n", boot_command_line);
|
pr_notice("Kernel command line: %s\n", boot_command_line);
|
||||||
|
/* parameters may set static keys */
|
||||||
|
jump_label_init();
|
||||||
parse_early_param();
|
parse_early_param();
|
||||||
after_dashes = parse_args("Booting kernel",
|
after_dashes = parse_args("Booting kernel",
|
||||||
static_command_line, __start___param,
|
static_command_line, __start___param,
|
||||||
|
@ -525,8 +527,6 @@ asmlinkage __visible void __init start_kernel(void)
|
||||||
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
|
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
|
||||||
NULL, set_init_arg);
|
NULL, set_init_arg);
|
||||||
|
|
||||||
jump_label_init();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These use large bootmem allocations and must precede
|
* These use large bootmem allocations and must precede
|
||||||
* kmem_cache_init()
|
* kmem_cache_init()
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
#include <linux/jhash.h>
|
#include <linux/jhash.h>
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
|
#include <linux/rculist_nulls.h>
|
||||||
#include "percpu_freelist.h"
|
#include "percpu_freelist.h"
|
||||||
#define HTAB_CREATE_FLAG_MASK \
|
#define HTAB_CREATE_FLAG_MASK \
|
||||||
(BPF_F_NO_PREALLOC | BPF_F_RDONLY | BPF_F_WRONLY)
|
(BPF_F_NO_PREALLOC | BPF_F_RDONLY | BPF_F_WRONLY)
|
||||||
|
|
||||||
struct bucket {
|
struct bucket {
|
||||||
struct hlist_head head;
|
struct hlist_nulls_head head;
|
||||||
raw_spinlock_t lock;
|
raw_spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,9 +43,14 @@ enum extra_elem_state {
|
||||||
/* each htab element is struct htab_elem + key + value */
|
/* each htab element is struct htab_elem + key + value */
|
||||||
struct htab_elem {
|
struct htab_elem {
|
||||||
union {
|
union {
|
||||||
struct hlist_node hash_node;
|
struct hlist_nulls_node hash_node;
|
||||||
struct bpf_htab *htab;
|
struct {
|
||||||
struct pcpu_freelist_node fnode;
|
void *padding;
|
||||||
|
union {
|
||||||
|
struct bpf_htab *htab;
|
||||||
|
struct pcpu_freelist_node fnode;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
|
@ -116,8 +122,10 @@ skip_percpu_elems:
|
||||||
if (err)
|
if (err)
|
||||||
goto free_elems;
|
goto free_elems;
|
||||||
|
|
||||||
pcpu_freelist_populate(&htab->freelist, htab->elems, htab->elem_size,
|
pcpu_freelist_populate(&htab->freelist,
|
||||||
htab->map.max_entries);
|
htab->elems + offsetof(struct htab_elem, fnode),
|
||||||
|
htab->elem_size, htab->map.max_entries);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_elems:
|
free_elems:
|
||||||
|
@ -150,6 +158,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
|
||||||
int err, i;
|
int err, i;
|
||||||
u64 cost;
|
u64 cost;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(offsetof(struct htab_elem, htab) !=
|
||||||
|
offsetof(struct htab_elem, hash_node.pprev));
|
||||||
|
BUILD_BUG_ON(offsetof(struct htab_elem, fnode.next) !=
|
||||||
|
offsetof(struct htab_elem, hash_node.pprev));
|
||||||
|
|
||||||
if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK)
|
if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK)
|
||||||
/* reserved bits should not be used */
|
/* reserved bits should not be used */
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
@ -235,7 +248,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
|
||||||
goto free_htab;
|
goto free_htab;
|
||||||
|
|
||||||
for (i = 0; i < htab->n_buckets; i++) {
|
for (i = 0; i < htab->n_buckets; i++) {
|
||||||
INIT_HLIST_HEAD(&htab->buckets[i].head);
|
INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
|
||||||
raw_spin_lock_init(&htab->buckets[i].lock);
|
raw_spin_lock_init(&htab->buckets[i].lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,28 +285,52 @@ static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash)
|
||||||
return &htab->buckets[hash & (htab->n_buckets - 1)];
|
return &htab->buckets[hash & (htab->n_buckets - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct hlist_head *select_bucket(struct bpf_htab *htab, u32 hash)
|
static inline struct hlist_nulls_head *select_bucket(struct bpf_htab *htab, u32 hash)
|
||||||
{
|
{
|
||||||
return &__select_bucket(htab, hash)->head;
|
return &__select_bucket(htab, hash)->head;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct htab_elem *lookup_elem_raw(struct hlist_head *head, u32 hash,
|
/* this lookup function can only be called with bucket lock taken */
|
||||||
|
static struct htab_elem *lookup_elem_raw(struct hlist_nulls_head *head, u32 hash,
|
||||||
void *key, u32 key_size)
|
void *key, u32 key_size)
|
||||||
{
|
{
|
||||||
|
struct hlist_nulls_node *n;
|
||||||
struct htab_elem *l;
|
struct htab_elem *l;
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(l, head, hash_node)
|
hlist_nulls_for_each_entry_rcu(l, n, head, hash_node)
|
||||||
if (l->hash == hash && !memcmp(&l->key, key, key_size))
|
if (l->hash == hash && !memcmp(&l->key, key, key_size))
|
||||||
return l;
|
return l;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* can be called without bucket lock. it will repeat the loop in
|
||||||
|
* the unlikely event when elements moved from one bucket into another
|
||||||
|
* while link list is being walked
|
||||||
|
*/
|
||||||
|
static struct htab_elem *lookup_nulls_elem_raw(struct hlist_nulls_head *head,
|
||||||
|
u32 hash, void *key,
|
||||||
|
u32 key_size, u32 n_buckets)
|
||||||
|
{
|
||||||
|
struct hlist_nulls_node *n;
|
||||||
|
struct htab_elem *l;
|
||||||
|
|
||||||
|
again:
|
||||||
|
hlist_nulls_for_each_entry_rcu(l, n, head, hash_node)
|
||||||
|
if (l->hash == hash && !memcmp(&l->key, key, key_size))
|
||||||
|
return l;
|
||||||
|
|
||||||
|
if (unlikely(get_nulls_value(n) != (hash & (n_buckets - 1))))
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Called from syscall or from eBPF program */
|
/* Called from syscall or from eBPF program */
|
||||||
static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
|
static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
|
||||||
{
|
{
|
||||||
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
||||||
struct hlist_head *head;
|
struct hlist_nulls_head *head;
|
||||||
struct htab_elem *l;
|
struct htab_elem *l;
|
||||||
u32 hash, key_size;
|
u32 hash, key_size;
|
||||||
|
|
||||||
|
@ -306,7 +343,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
|
||||||
|
|
||||||
head = select_bucket(htab, hash);
|
head = select_bucket(htab, hash);
|
||||||
|
|
||||||
l = lookup_elem_raw(head, hash, key, key_size);
|
l = lookup_nulls_elem_raw(head, hash, key, key_size, htab->n_buckets);
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +362,7 @@ static void *htab_map_lookup_elem(struct bpf_map *map, void *key)
|
||||||
static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
|
static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
|
||||||
{
|
{
|
||||||
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
||||||
struct hlist_head *head;
|
struct hlist_nulls_head *head;
|
||||||
struct htab_elem *l, *next_l;
|
struct htab_elem *l, *next_l;
|
||||||
u32 hash, key_size;
|
u32 hash, key_size;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -342,13 +379,13 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
|
||||||
head = select_bucket(htab, hash);
|
head = select_bucket(htab, hash);
|
||||||
|
|
||||||
/* lookup the key */
|
/* lookup the key */
|
||||||
l = lookup_elem_raw(head, hash, key, key_size);
|
l = lookup_nulls_elem_raw(head, hash, key, key_size, htab->n_buckets);
|
||||||
|
|
||||||
if (!l)
|
if (!l)
|
||||||
goto find_first_elem;
|
goto find_first_elem;
|
||||||
|
|
||||||
/* key was found, get next key in the same bucket */
|
/* key was found, get next key in the same bucket */
|
||||||
next_l = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)),
|
next_l = hlist_nulls_entry_safe(rcu_dereference_raw(hlist_nulls_next_rcu(&l->hash_node)),
|
||||||
struct htab_elem, hash_node);
|
struct htab_elem, hash_node);
|
||||||
|
|
||||||
if (next_l) {
|
if (next_l) {
|
||||||
|
@ -367,7 +404,7 @@ find_first_elem:
|
||||||
head = select_bucket(htab, i);
|
head = select_bucket(htab, i);
|
||||||
|
|
||||||
/* pick first element in the bucket */
|
/* pick first element in the bucket */
|
||||||
next_l = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)),
|
next_l = hlist_nulls_entry_safe(rcu_dereference_raw(hlist_nulls_first_rcu(head)),
|
||||||
struct htab_elem, hash_node);
|
struct htab_elem, hash_node);
|
||||||
if (next_l) {
|
if (next_l) {
|
||||||
/* if it's not empty, just return it */
|
/* if it's not empty, just return it */
|
||||||
|
@ -431,9 +468,13 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (prealloc) {
|
if (prealloc) {
|
||||||
l_new = (struct htab_elem *)pcpu_freelist_pop(&htab->freelist);
|
struct pcpu_freelist_node *l;
|
||||||
if (!l_new)
|
|
||||||
|
l = pcpu_freelist_pop(&htab->freelist);
|
||||||
|
if (!l)
|
||||||
err = -E2BIG;
|
err = -E2BIG;
|
||||||
|
else
|
||||||
|
l_new = container_of(l, struct htab_elem, fnode);
|
||||||
} else {
|
} else {
|
||||||
if (atomic_inc_return(&htab->count) > htab->map.max_entries) {
|
if (atomic_inc_return(&htab->count) > htab->map.max_entries) {
|
||||||
atomic_dec(&htab->count);
|
atomic_dec(&htab->count);
|
||||||
|
@ -520,7 +561,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
|
||||||
{
|
{
|
||||||
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
||||||
struct htab_elem *l_new = NULL, *l_old;
|
struct htab_elem *l_new = NULL, *l_old;
|
||||||
struct hlist_head *head;
|
struct hlist_nulls_head *head;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct bucket *b;
|
struct bucket *b;
|
||||||
u32 key_size, hash;
|
u32 key_size, hash;
|
||||||
|
@ -559,9 +600,9 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
|
||||||
/* add new element to the head of the list, so that
|
/* add new element to the head of the list, so that
|
||||||
* concurrent search will find it before old elem
|
* concurrent search will find it before old elem
|
||||||
*/
|
*/
|
||||||
hlist_add_head_rcu(&l_new->hash_node, head);
|
hlist_nulls_add_head_rcu(&l_new->hash_node, head);
|
||||||
if (l_old) {
|
if (l_old) {
|
||||||
hlist_del_rcu(&l_old->hash_node);
|
hlist_nulls_del_rcu(&l_old->hash_node);
|
||||||
free_htab_elem(htab, l_old);
|
free_htab_elem(htab, l_old);
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -576,7 +617,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
|
||||||
{
|
{
|
||||||
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
||||||
struct htab_elem *l_new = NULL, *l_old;
|
struct htab_elem *l_new = NULL, *l_old;
|
||||||
struct hlist_head *head;
|
struct hlist_nulls_head *head;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct bucket *b;
|
struct bucket *b;
|
||||||
u32 key_size, hash;
|
u32 key_size, hash;
|
||||||
|
@ -628,7 +669,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
|
||||||
ret = PTR_ERR(l_new);
|
ret = PTR_ERR(l_new);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
hlist_add_head_rcu(&l_new->hash_node, head);
|
hlist_nulls_add_head_rcu(&l_new->hash_node, head);
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
err:
|
err:
|
||||||
|
@ -646,7 +687,7 @@ static int htab_percpu_map_update_elem(struct bpf_map *map, void *key,
|
||||||
static int htab_map_delete_elem(struct bpf_map *map, void *key)
|
static int htab_map_delete_elem(struct bpf_map *map, void *key)
|
||||||
{
|
{
|
||||||
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
|
||||||
struct hlist_head *head;
|
struct hlist_nulls_head *head;
|
||||||
struct bucket *b;
|
struct bucket *b;
|
||||||
struct htab_elem *l;
|
struct htab_elem *l;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -666,7 +707,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key)
|
||||||
l = lookup_elem_raw(head, hash, key, key_size);
|
l = lookup_elem_raw(head, hash, key, key_size);
|
||||||
|
|
||||||
if (l) {
|
if (l) {
|
||||||
hlist_del_rcu(&l->hash_node);
|
hlist_nulls_del_rcu(&l->hash_node);
|
||||||
free_htab_elem(htab, l);
|
free_htab_elem(htab, l);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -680,12 +721,12 @@ static void delete_all_elements(struct bpf_htab *htab)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < htab->n_buckets; i++) {
|
for (i = 0; i < htab->n_buckets; i++) {
|
||||||
struct hlist_head *head = select_bucket(htab, i);
|
struct hlist_nulls_head *head = select_bucket(htab, i);
|
||||||
struct hlist_node *n;
|
struct hlist_nulls_node *n;
|
||||||
struct htab_elem *l;
|
struct htab_elem *l;
|
||||||
|
|
||||||
hlist_for_each_entry_safe(l, n, head, hash_node) {
|
hlist_nulls_for_each_entry_safe(l, n, head, hash_node) {
|
||||||
hlist_del_rcu(&l->hash_node);
|
hlist_nulls_del_rcu(&l->hash_node);
|
||||||
if (l->state != HTAB_EXTRA_ELEM_USED)
|
if (l->state != HTAB_EXTRA_ELEM_USED)
|
||||||
htab_elem_free(htab, l);
|
htab_elem_free(htab, l);
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,10 +366,12 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
ifrr.ifr_ifru = ifr->ifr_ifru;
|
ifrr.ifr_ifru = ifr->ifr_ifru;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case SIOCSHWTSTAMP:
|
||||||
|
if (!net_eq(dev_net(dev), &init_net))
|
||||||
|
break;
|
||||||
case SIOCGMIIPHY:
|
case SIOCGMIIPHY:
|
||||||
case SIOCGMIIREG:
|
case SIOCGMIIREG:
|
||||||
case SIOCSMIIREG:
|
case SIOCSMIIREG:
|
||||||
case SIOCSHWTSTAMP:
|
|
||||||
case SIOCGHWTSTAMP:
|
case SIOCGHWTSTAMP:
|
||||||
if (netif_device_present(real_dev) && ops->ndo_do_ioctl)
|
if (netif_device_present(real_dev) && ops->ndo_do_ioctl)
|
||||||
err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd);
|
err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd);
|
||||||
|
|
|
@ -519,13 +519,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
|
||||||
call_netdevice_notifiers(NETDEV_JOIN, dev);
|
call_netdevice_notifiers(NETDEV_JOIN, dev);
|
||||||
|
|
||||||
err = dev_set_allmulti(dev, 1);
|
err = dev_set_allmulti(dev, 1);
|
||||||
if (err)
|
if (err) {
|
||||||
goto put_back;
|
kfree(p); /* kobject not yet init'd, manually free */
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
|
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
|
||||||
SYSFS_BRIDGE_PORT_ATTR);
|
SYSFS_BRIDGE_PORT_ATTR);
|
||||||
if (err)
|
if (err)
|
||||||
goto err1;
|
goto err2;
|
||||||
|
|
||||||
err = br_sysfs_addif(p);
|
err = br_sysfs_addif(p);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -608,12 +610,9 @@ err3:
|
||||||
sysfs_remove_link(br->ifobj, p->dev->name);
|
sysfs_remove_link(br->ifobj, p->dev->name);
|
||||||
err2:
|
err2:
|
||||||
kobject_put(&p->kobj);
|
kobject_put(&p->kobj);
|
||||||
p = NULL; /* kobject_put frees */
|
|
||||||
err1:
|
|
||||||
dev_set_allmulti(dev, -1);
|
dev_set_allmulti(dev, -1);
|
||||||
put_back:
|
err1:
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
kfree(p);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -486,9 +486,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||||
rule->uid_range = fib_kuid_range_unset;
|
rule->uid_range = fib_kuid_range_unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nlh->nlmsg_flags & NLM_F_EXCL) &&
|
if (rule_exists(ops, frh, tb, rule)) {
|
||||||
rule_exists(ops, frh, tb, rule)) {
|
if (nlh->nlmsg_flags & NLM_F_EXCL)
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
goto errout_free;
|
goto errout_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
|
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
|
||||||
{
|
{
|
||||||
|
int dif = inet_iif(skb);
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
int delivered = 0;
|
int delivered = 0;
|
||||||
|
@ -181,8 +182,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
|
||||||
|
|
||||||
net = dev_net(skb->dev);
|
net = dev_net(skb->dev);
|
||||||
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
|
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
|
||||||
iph->saddr, iph->daddr,
|
iph->saddr, iph->daddr, dif);
|
||||||
skb->dev->ifindex);
|
|
||||||
|
|
||||||
while (sk) {
|
while (sk) {
|
||||||
delivered = 1;
|
delivered = 1;
|
||||||
|
|
|
@ -1069,7 +1069,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
|
||||||
if (!tdev && tunnel->parms.link)
|
if (!tdev && tunnel->parms.link)
|
||||||
tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
|
tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
|
||||||
|
|
||||||
if (tdev) {
|
if (tdev && !netif_is_l3_master(tdev)) {
|
||||||
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
|
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
|
||||||
|
|
||||||
dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
|
dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
|
||||||
|
|
|
@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
|
||||||
static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
|
static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
|
||||||
{
|
{
|
||||||
/* Use last four bytes of hw addr as hash index */
|
/* Use last four bytes of hw addr as hash index */
|
||||||
return jhash_1word(*(u32 *)(addr+2), seed);
|
return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct rhashtable_params mesh_rht_params = {
|
static const struct rhashtable_params mesh_rht_params = {
|
||||||
|
|
|
@ -1643,7 +1643,7 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
if (!sysctl_schedule_icmp(ipvs))
|
if (ipip || !sysctl_schedule_icmp(ipvs))
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
if (!ip_vs_try_to_schedule(ipvs, AF_INET, skb, pd, &v, &cp, &ciph))
|
if (!ip_vs_try_to_schedule(ipvs, AF_INET, skb, pd, &v, &cp, &ciph))
|
||||||
|
|
|
@ -1728,7 +1728,7 @@ static int __init xt_init(void)
|
||||||
seqcount_init(&per_cpu(xt_recseq, i));
|
seqcount_init(&per_cpu(xt_recseq, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
|
xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
|
||||||
if (!xt)
|
if (!xt)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -4624,14 +4624,29 @@ static void __exit packet_exit(void)
|
||||||
|
|
||||||
static int __init packet_init(void)
|
static int __init packet_init(void)
|
||||||
{
|
{
|
||||||
int rc = proto_register(&packet_proto, 0);
|
int rc;
|
||||||
|
|
||||||
if (rc != 0)
|
rc = proto_register(&packet_proto, 0);
|
||||||
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
rc = sock_register(&packet_family_ops);
|
||||||
|
if (rc)
|
||||||
|
goto out_proto;
|
||||||
|
rc = register_pernet_subsys(&packet_net_ops);
|
||||||
|
if (rc)
|
||||||
|
goto out_sock;
|
||||||
|
rc = register_netdevice_notifier(&packet_netdev_notifier);
|
||||||
|
if (rc)
|
||||||
|
goto out_pernet;
|
||||||
|
|
||||||
sock_register(&packet_family_ops);
|
return 0;
|
||||||
register_pernet_subsys(&packet_net_ops);
|
|
||||||
register_netdevice_notifier(&packet_netdev_notifier);
|
out_pernet:
|
||||||
|
unregister_pernet_subsys(&packet_net_ops);
|
||||||
|
out_sock:
|
||||||
|
sock_unregister(PF_PACKET);
|
||||||
|
out_proto:
|
||||||
|
proto_unregister(&packet_proto);
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1849,8 +1849,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
|
||||||
unsigned int cmd, void *arg)
|
unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_IOCTL1_INFO:
|
|
||||||
return 0;
|
|
||||||
case SNDRV_PCM_IOCTL1_RESET:
|
case SNDRV_PCM_IOCTL1_RESET:
|
||||||
return snd_pcm_lib_ioctl_reset(substream, arg);
|
return snd_pcm_lib_ioctl_reset(substream, arg);
|
||||||
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
|
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
|
||||||
|
|
|
@ -214,11 +214,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
|
||||||
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
|
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
|
||||||
strlcpy(info->subname, substream->name, sizeof(info->subname));
|
strlcpy(info->subname, substream->name, sizeof(info->subname));
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
/* AB: FIXME!!! This is definitely nonsense */
|
|
||||||
if (runtime) {
|
|
||||||
info->sync = runtime->sync;
|
|
||||||
substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2204,7 +2204,7 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
|
||||||
return val & 0xffffffff;
|
return val & 0xffffffff;
|
||||||
|
|
||||||
if (strcmp(type, "u64") == 0 ||
|
if (strcmp(type, "u64") == 0 ||
|
||||||
strcmp(type, "s64"))
|
strcmp(type, "s64") == 0)
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
if (strcmp(type, "s8") == 0)
|
if (strcmp(type, "s8") == 0)
|
||||||
|
|
|
@ -6,7 +6,7 @@ echo "--------------------"
|
||||||
./socket
|
./socket
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "[FAIL]"
|
echo "[FAIL]"
|
||||||
|
exit 1
|
||||||
else
|
else
|
||||||
echo "[PASS]"
|
echo "[PASS]"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Makefile for netfilter selftests
|
# Makefile for netfilter selftests
|
||||||
|
|
||||||
TEST_PROGS := nft_trans_stress.sh nft_nat.sh
|
TEST_PROGS := nft_trans_stress.sh nft_nat.sh conntrack_icmp_related.sh
|
||||||
|
|
||||||
include ../lib.mk
|
include ../lib.mk
|
||||||
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# check that ICMP df-needed/pkttoobig icmp are set are set as related
|
||||||
|
# state
|
||||||
|
#
|
||||||
|
# Setup is:
|
||||||
|
#
|
||||||
|
# nsclient1 -> nsrouter1 -> nsrouter2 -> nsclient2
|
||||||
|
# MTU 1500, except for nsrouter2 <-> nsclient2 link (1280).
|
||||||
|
# ping nsclient2 from nsclient1, checking that conntrack did set RELATED
|
||||||
|
# 'fragmentation needed' icmp packet.
|
||||||
|
#
|
||||||
|
# In addition, nsrouter1 will perform IP masquerading, i.e. also
|
||||||
|
# check the icmp errors are propagated to the correct host as per
|
||||||
|
# nat of "established" icmp-echo "connection".
|
||||||
|
|
||||||
|
# Kselftest framework requirement - SKIP code is 4.
|
||||||
|
ksft_skip=4
|
||||||
|
ret=0
|
||||||
|
|
||||||
|
nft --version > /dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ];then
|
||||||
|
echo "SKIP: Could not run test without nft tool"
|
||||||
|
exit $ksft_skip
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip -Version > /dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ];then
|
||||||
|
echo "SKIP: Could not run test without ip tool"
|
||||||
|
exit $ksft_skip
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
for i in 1 2;do ip netns del nsclient$i;done
|
||||||
|
for i in 1 2;do ip netns del nsrouter$i;done
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4() {
|
||||||
|
echo -n 192.168.$1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6 () {
|
||||||
|
echo -n dead:$1::2
|
||||||
|
}
|
||||||
|
|
||||||
|
check_counter()
|
||||||
|
{
|
||||||
|
ns=$1
|
||||||
|
name=$2
|
||||||
|
expect=$3
|
||||||
|
local lret=0
|
||||||
|
|
||||||
|
cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect")
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2
|
||||||
|
ip netns exec $ns nft list counter inet filter "$name" 1>&2
|
||||||
|
lret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $lret
|
||||||
|
}
|
||||||
|
|
||||||
|
check_unknown()
|
||||||
|
{
|
||||||
|
expect="packets 0 bytes 0"
|
||||||
|
for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
|
||||||
|
check_counter $n "unknown" "$expect"
|
||||||
|
if [ $? -ne 0 ] ;then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
|
||||||
|
ip netns add $n
|
||||||
|
ip -net $n link set lo up
|
||||||
|
done
|
||||||
|
|
||||||
|
DEV=veth0
|
||||||
|
ip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1
|
||||||
|
DEV=veth0
|
||||||
|
ip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2
|
||||||
|
|
||||||
|
DEV=veth0
|
||||||
|
ip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2
|
||||||
|
|
||||||
|
DEV=veth0
|
||||||
|
for i in 1 2; do
|
||||||
|
ip -net nsclient$i link set $DEV up
|
||||||
|
ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV
|
||||||
|
ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV
|
||||||
|
done
|
||||||
|
|
||||||
|
ip -net nsrouter1 link set eth1 up
|
||||||
|
ip -net nsrouter1 link set veth0 up
|
||||||
|
|
||||||
|
ip -net nsrouter2 link set eth1 up
|
||||||
|
ip -net nsrouter2 link set eth2 up
|
||||||
|
|
||||||
|
ip -net nsclient1 route add default via 192.168.1.1
|
||||||
|
ip -net nsclient1 -6 route add default via dead:1::1
|
||||||
|
|
||||||
|
ip -net nsclient2 route add default via 192.168.2.1
|
||||||
|
ip -net nsclient2 route add default via dead:2::1
|
||||||
|
|
||||||
|
i=3
|
||||||
|
ip -net nsrouter1 addr add 192.168.1.1/24 dev eth1
|
||||||
|
ip -net nsrouter1 addr add 192.168.3.1/24 dev veth0
|
||||||
|
ip -net nsrouter1 addr add dead:1::1/64 dev eth1
|
||||||
|
ip -net nsrouter1 addr add dead:3::1/64 dev veth0
|
||||||
|
ip -net nsrouter1 route add default via 192.168.3.10
|
||||||
|
ip -net nsrouter1 -6 route add default via dead:3::10
|
||||||
|
|
||||||
|
ip -net nsrouter2 addr add 192.168.2.1/24 dev eth1
|
||||||
|
ip -net nsrouter2 addr add 192.168.3.10/24 dev eth2
|
||||||
|
ip -net nsrouter2 addr add dead:2::1/64 dev eth1
|
||||||
|
ip -net nsrouter2 addr add dead:3::10/64 dev eth2
|
||||||
|
ip -net nsrouter2 route add default via 192.168.3.1
|
||||||
|
ip -net nsrouter2 route add default via dead:3::1
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
for i in 4 6; do
|
||||||
|
ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1
|
||||||
|
ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1
|
||||||
|
done
|
||||||
|
|
||||||
|
for netns in nsrouter1 nsrouter2; do
|
||||||
|
ip netns exec $netns nft -f - <<EOF
|
||||||
|
table inet filter {
|
||||||
|
counter unknown { }
|
||||||
|
counter related { }
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0; policy accept;
|
||||||
|
meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept
|
||||||
|
meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state new,established accept
|
||||||
|
counter name "unknown" drop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
|
||||||
|
ip netns exec nsclient1 nft -f - <<EOF
|
||||||
|
table inet filter {
|
||||||
|
counter unknown { }
|
||||||
|
counter related { }
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy accept;
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
||||||
|
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
|
||||||
|
counter name "unknown" drop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
ip netns exec nsclient2 nft -f - <<EOF
|
||||||
|
table inet filter {
|
||||||
|
counter unknown { }
|
||||||
|
counter new { }
|
||||||
|
counter established { }
|
||||||
|
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy accept;
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
||||||
|
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept
|
||||||
|
counter name "unknown" drop
|
||||||
|
}
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0; policy accept;
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
||||||
|
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state "new" counter name "new"
|
||||||
|
meta l4proto { icmp, icmpv6 } ct state "established" counter name "established"
|
||||||
|
counter name "unknown" drop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
# make sure NAT core rewrites adress of icmp error if nat is used according to
|
||||||
|
# conntrack nat information (icmp error will be directed at nsrouter1 address,
|
||||||
|
# but it needs to be routed to nsclient1 address).
|
||||||
|
ip netns exec nsrouter1 nft -f - <<EOF
|
||||||
|
table ip nat {
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 0; policy accept;
|
||||||
|
ip protocol icmp oifname "veth0" counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table ip6 nat {
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 0; policy accept;
|
||||||
|
ip6 nexthdr icmpv6 oifname "veth0" counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
ip netns exec nsrouter2 ip link set eth1 mtu 1280
|
||||||
|
ip netns exec nsclient2 ip link set veth0 mtu 1280
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
ip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: netns ip routing/connectivity broken" 1>&2
|
||||||
|
cleanup
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2
|
||||||
|
cleanup
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_unknown
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expect="packets 0 bytes 0"
|
||||||
|
for netns in nsrouter1 nsrouter2 nsclient1;do
|
||||||
|
check_counter "$netns" "related" "$expect"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
expect="packets 2 bytes 2076"
|
||||||
|
check_counter nsclient2 "new" "$expect"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "ERROR: ping should have failed with PMTU too big error" 1>&2
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# nsrouter2 should have generated the icmp error, so
|
||||||
|
# related counter should be 0 (its in forward).
|
||||||
|
expect="packets 0 bytes 0"
|
||||||
|
check_counter "nsrouter2" "related" "$expect"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# but nsrouter1 should have seen it, same for nsclient1.
|
||||||
|
expect="packets 1 bytes 576"
|
||||||
|
for netns in nsrouter1 nsclient1;do
|
||||||
|
check_counter "$netns" "related" "$expect"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
ip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expect="packets 2 bytes 1856"
|
||||||
|
for netns in nsrouter1 nsclient1;do
|
||||||
|
check_counter "$netns" "related" "$expect"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $ret -eq 0 ];then
|
||||||
|
echo "PASS: icmp mtu error had RELATED state"
|
||||||
|
else
|
||||||
|
echo "ERROR: icmp error RELATED state test has failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
exit $ret
|
Loading…
Reference in New Issue