Annotation of /trunk/kernel-alx-legacy/patches-4.9/0316-4.9.217-all-fixes.patch
Parent Directory | Revision Log
Revision 3608 -
(hide annotations)
(download)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 105735 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 105735 byte(s)
-added kerenl-alx-legacy pkg
1 | niro | 3608 | diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting |
2 | index bdd025ceb763..85ed3450099a 100644 | ||
3 | --- a/Documentation/filesystems/porting | ||
4 | +++ b/Documentation/filesystems/porting | ||
5 | @@ -596,3 +596,10 @@ in your dentry operations instead. | ||
6 | [mandatory] | ||
7 | ->rename() has an added flags argument. Any flags not handled by the | ||
8 | filesystem should result in EINVAL being returned. | ||
9 | +-- | ||
10 | +[mandatory] | ||
11 | + | ||
12 | + [should've been added in 2016] stale comment in finish_open() | ||
13 | + nonwithstanding, failure exits in ->atomic_open() instances should | ||
14 | + *NOT* fput() the file, no matter what. Everything is handled by the | ||
15 | + caller. | ||
16 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt | ||
17 | index b2d2f4539a3f..e05d65d6fcb6 100644 | ||
18 | --- a/Documentation/kernel-parameters.txt | ||
19 | +++ b/Documentation/kernel-parameters.txt | ||
20 | @@ -335,6 +335,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | ||
21 | dynamic table installation which will install SSDT | ||
22 | tables to /sys/firmware/acpi/tables/dynamic. | ||
23 | |||
24 | + acpi_no_watchdog [HW,ACPI,WDT] | ||
25 | + Ignore the ACPI-based watchdog interface (WDAT) and let | ||
26 | + a native driver control the watchdog device instead. | ||
27 | + | ||
28 | acpi_rsdp= [ACPI,EFI,KEXEC] | ||
29 | Pass the RSDP address to the kernel, mostly used | ||
30 | on machines running EFI runtime service to boot the | ||
31 | diff --git a/Makefile b/Makefile | ||
32 | index f0290097784a..96b230200cbe 100644 | ||
33 | --- a/Makefile | ||
34 | +++ b/Makefile | ||
35 | @@ -1,6 +1,6 @@ | ||
36 | VERSION = 4 | ||
37 | PATCHLEVEL = 9 | ||
38 | -SUBLEVEL = 216 | ||
39 | +SUBLEVEL = 217 | ||
40 | EXTRAVERSION = | ||
41 | NAME = Roaring Lionus | ||
42 | |||
43 | diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h | ||
44 | index b29f1a9fd6f7..07c8e1a6c56e 100644 | ||
45 | --- a/arch/arc/include/asm/linkage.h | ||
46 | +++ b/arch/arc/include/asm/linkage.h | ||
47 | @@ -14,6 +14,8 @@ | ||
48 | #ifdef __ASSEMBLY__ | ||
49 | |||
50 | #define ASM_NL ` /* use '`' to mark new line in macro */ | ||
51 | +#define __ALIGN .align 4 | ||
52 | +#define __ALIGN_STR __stringify(__ALIGN) | ||
53 | |||
54 | /* annotation for data we want in DCCM - if enabled in .config */ | ||
55 | .macro ARCFP_DATA nm | ||
56 | diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c | ||
57 | index 890439737374..bf6e45dec017 100644 | ||
58 | --- a/arch/arm/kernel/vdso.c | ||
59 | +++ b/arch/arm/kernel/vdso.c | ||
60 | @@ -85,6 +85,8 @@ static bool __init cntvct_functional(void) | ||
61 | * this. | ||
62 | */ | ||
63 | np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); | ||
64 | + if (!np) | ||
65 | + np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); | ||
66 | if (!np) | ||
67 | goto out_put; | ||
68 | |||
69 | diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S | ||
70 | index 6709a8d33963..f1e34f16cfab 100644 | ||
71 | --- a/arch/arm/lib/copy_from_user.S | ||
72 | +++ b/arch/arm/lib/copy_from_user.S | ||
73 | @@ -100,7 +100,7 @@ ENTRY(arm_copy_from_user) | ||
74 | |||
75 | ENDPROC(arm_copy_from_user) | ||
76 | |||
77 | - .pushsection .fixup,"ax" | ||
78 | + .pushsection .text.fixup,"ax" | ||
79 | .align 0 | ||
80 | copy_abort_preamble | ||
81 | ldmfd sp!, {r1, r2, r3} | ||
82 | diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c | ||
83 | index c16c99bc2a10..6bfb9a68134c 100644 | ||
84 | --- a/arch/x86/events/amd/uncore.c | ||
85 | +++ b/arch/x86/events/amd/uncore.c | ||
86 | @@ -185,20 +185,18 @@ static int amd_uncore_event_init(struct perf_event *event) | ||
87 | |||
88 | /* | ||
89 | * NB and Last level cache counters (MSRs) are shared across all cores | ||
90 | - * that share the same NB / Last level cache. Interrupts can be directed | ||
91 | - * to a single target core, however, event counts generated by processes | ||
92 | - * running on other cores cannot be masked out. So we do not support | ||
93 | - * sampling and per-thread events. | ||
94 | + * that share the same NB / Last level cache. On family 16h and below, | ||
95 | + * Interrupts can be directed to a single target core, however, event | ||
96 | + * counts generated by processes running on other cores cannot be masked | ||
97 | + * out. So we do not support sampling and per-thread events via | ||
98 | + * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: | ||
99 | */ | ||
100 | - if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) | ||
101 | - return -EINVAL; | ||
102 | |||
103 | /* NB and Last level cache counters do not have usr/os/guest/host bits */ | ||
104 | if (event->attr.exclude_user || event->attr.exclude_kernel || | ||
105 | event->attr.exclude_host || event->attr.exclude_guest) | ||
106 | return -EINVAL; | ||
107 | |||
108 | - /* and we do not enable counter overflow interrupts */ | ||
109 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; | ||
110 | hwc->idx = -1; | ||
111 | |||
112 | @@ -275,6 +273,7 @@ static struct pmu amd_nb_pmu = { | ||
113 | .start = amd_uncore_start, | ||
114 | .stop = amd_uncore_stop, | ||
115 | .read = amd_uncore_read, | ||
116 | + .capabilities = PERF_PMU_CAP_NO_INTERRUPT, | ||
117 | }; | ||
118 | |||
119 | static struct pmu amd_llc_pmu = { | ||
120 | @@ -287,6 +286,7 @@ static struct pmu amd_llc_pmu = { | ||
121 | .start = amd_uncore_start, | ||
122 | .stop = amd_uncore_stop, | ||
123 | .read = amd_uncore_read, | ||
124 | + .capabilities = PERF_PMU_CAP_NO_INTERRUPT, | ||
125 | }; | ||
126 | |||
127 | static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) | ||
128 | diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c | ||
129 | index e9c7090858d6..da3cd734dee1 100644 | ||
130 | --- a/arch/x86/kvm/emulate.c | ||
131 | +++ b/arch/x86/kvm/emulate.c | ||
132 | @@ -5022,6 +5022,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) | ||
133 | ctxt->fetch.ptr = ctxt->fetch.data; | ||
134 | ctxt->fetch.end = ctxt->fetch.data + insn_len; | ||
135 | ctxt->opcode_len = 1; | ||
136 | + ctxt->intercept = x86_intercept_none; | ||
137 | if (insn_len > 0) | ||
138 | memcpy(ctxt->fetch.data, insn, insn_len); | ||
139 | else { | ||
140 | diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c | ||
141 | index 7ef0a0e105e1..4296f4932294 100644 | ||
142 | --- a/drivers/acpi/acpi_watchdog.c | ||
143 | +++ b/drivers/acpi/acpi_watchdog.c | ||
144 | @@ -58,12 +58,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 | +static bool acpi_no_watchdog; | ||
149 | + | ||
150 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | ||
151 | { | ||
152 | const struct acpi_table_wdat *wdat = NULL; | ||
153 | acpi_status status; | ||
154 | |||
155 | - if (acpi_disabled) | ||
156 | + if (acpi_disabled || acpi_no_watchdog) | ||
157 | return NULL; | ||
158 | |||
159 | status = acpi_get_table(ACPI_SIG_WDAT, 0, | ||
160 | @@ -91,6 +93,14 @@ bool acpi_has_watchdog(void) | ||
161 | } | ||
162 | EXPORT_SYMBOL_GPL(acpi_has_watchdog); | ||
163 | |||
164 | +/* ACPI watchdog can be disabled on boot command line */ | ||
165 | +static int __init disable_acpi_watchdog(char *str) | ||
166 | +{ | ||
167 | + acpi_no_watchdog = true; | ||
168 | + return 1; | ||
169 | +} | ||
170 | +__setup("acpi_no_watchdog", disable_acpi_watchdog); | ||
171 | + | ||
172 | void __init acpi_watchdog_init(void) | ||
173 | { | ||
174 | const struct acpi_wdat_entry *entries; | ||
175 | diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c | ||
176 | index 44ef1d66caa6..f287eec36b28 100644 | ||
177 | --- a/drivers/block/virtio_blk.c | ||
178 | +++ b/drivers/block/virtio_blk.c | ||
179 | @@ -215,10 +215,12 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, | ||
180 | err = __virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); | ||
181 | if (err) { | ||
182 | virtqueue_kick(vblk->vqs[qid].vq); | ||
183 | - blk_mq_stop_hw_queue(hctx); | ||
184 | + /* Don't stop the queue if -ENOMEM: we may have failed to | ||
185 | + * bounce the buffer due to global resource outage. | ||
186 | + */ | ||
187 | + if (err == -ENOSPC) | ||
188 | + blk_mq_stop_hw_queue(hctx); | ||
189 | spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); | ||
190 | - /* Out of mem doesn't actually happen, since we fall back | ||
191 | - * to direct descriptors */ | ||
192 | if (err == -ENOMEM || err == -ENOSPC) | ||
193 | return BLK_MQ_RQ_QUEUE_BUSY; | ||
194 | return BLK_MQ_RQ_QUEUE_ERROR; | ||
195 | diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c | ||
196 | index 3e626fd9bd4e..1c65f5ac4368 100644 | ||
197 | --- a/drivers/firmware/efi/efivars.c | ||
198 | +++ b/drivers/firmware/efi/efivars.c | ||
199 | @@ -139,13 +139,16 @@ static ssize_t | ||
200 | efivar_attr_read(struct efivar_entry *entry, char *buf) | ||
201 | { | ||
202 | struct efi_variable *var = &entry->var; | ||
203 | + unsigned long size = sizeof(var->Data); | ||
204 | char *str = buf; | ||
205 | + int ret; | ||
206 | |||
207 | if (!entry || !buf) | ||
208 | return -EINVAL; | ||
209 | |||
210 | - var->DataSize = 1024; | ||
211 | - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | ||
212 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | ||
213 | + var->DataSize = size; | ||
214 | + if (ret) | ||
215 | return -EIO; | ||
216 | |||
217 | if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) | ||
218 | @@ -172,13 +175,16 @@ static ssize_t | ||
219 | efivar_size_read(struct efivar_entry *entry, char *buf) | ||
220 | { | ||
221 | struct efi_variable *var = &entry->var; | ||
222 | + unsigned long size = sizeof(var->Data); | ||
223 | char *str = buf; | ||
224 | + int ret; | ||
225 | |||
226 | if (!entry || !buf) | ||
227 | return -EINVAL; | ||
228 | |||
229 | - var->DataSize = 1024; | ||
230 | - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | ||
231 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | ||
232 | + var->DataSize = size; | ||
233 | + if (ret) | ||
234 | return -EIO; | ||
235 | |||
236 | str += sprintf(str, "0x%lx\n", var->DataSize); | ||
237 | @@ -189,12 +195,15 @@ static ssize_t | ||
238 | efivar_data_read(struct efivar_entry *entry, char *buf) | ||
239 | { | ||
240 | struct efi_variable *var = &entry->var; | ||
241 | + unsigned long size = sizeof(var->Data); | ||
242 | + int ret; | ||
243 | |||
244 | if (!entry || !buf) | ||
245 | return -EINVAL; | ||
246 | |||
247 | - var->DataSize = 1024; | ||
248 | - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | ||
249 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | ||
250 | + var->DataSize = size; | ||
251 | + if (ret) | ||
252 | return -EIO; | ||
253 | |||
254 | memcpy(buf, var->Data, var->DataSize); | ||
255 | @@ -263,6 +272,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) | ||
256 | u8 *data; | ||
257 | int err; | ||
258 | |||
259 | + if (!entry || !buf) | ||
260 | + return -EINVAL; | ||
261 | + | ||
262 | if (is_compat()) { | ||
263 | struct compat_efi_variable *compat; | ||
264 | |||
265 | @@ -314,14 +326,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) | ||
266 | { | ||
267 | struct efi_variable *var = &entry->var; | ||
268 | struct compat_efi_variable *compat; | ||
269 | + unsigned long datasize = sizeof(var->Data); | ||
270 | size_t size; | ||
271 | + int ret; | ||
272 | |||
273 | if (!entry || !buf) | ||
274 | return 0; | ||
275 | |||
276 | - var->DataSize = 1024; | ||
277 | - if (efivar_entry_get(entry, &entry->var.Attributes, | ||
278 | - &entry->var.DataSize, entry->var.Data)) | ||
279 | + ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); | ||
280 | + var->DataSize = datasize; | ||
281 | + if (ret) | ||
282 | return -EIO; | ||
283 | |||
284 | if (is_compat()) { | ||
285 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | ||
286 | index ac8885562919..0c2ed1254585 100644 | ||
287 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | ||
288 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | ||
289 | @@ -363,8 +363,7 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device * | ||
290 | router.ddc_valid = false; | ||
291 | router.cd_valid = false; | ||
292 | for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { | ||
293 | - uint8_t grph_obj_type= | ||
294 | - grph_obj_type = | ||
295 | + uint8_t grph_obj_type = | ||
296 | (le16_to_cpu(path->usGraphicObjIds[j]) & | ||
297 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | ||
298 | |||
299 | diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c | ||
300 | index 31c087e1746d..197eb75d10ef 100644 | ||
301 | --- a/drivers/hid/hid-apple.c | ||
302 | +++ b/drivers/hid/hid-apple.c | ||
303 | @@ -341,7 +341,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
304 | unsigned long **bit, int *max) | ||
305 | { | ||
306 | if (usage->hid == (HID_UP_CUSTOM | 0x0003) || | ||
307 | - usage->hid == (HID_UP_MSVENDOR | 0x0003)) { | ||
308 | + usage->hid == (HID_UP_MSVENDOR | 0x0003) || | ||
309 | + usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { | ||
310 | /* The fn key on Apple USB keyboards */ | ||
311 | set_bit(EV_REP, hi->input->evbit); | ||
312 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); | ||
313 | diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | ||
314 | index 10af8585c820..95052373a828 100644 | ||
315 | --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | ||
316 | +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | ||
317 | @@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { | ||
318 | }, | ||
319 | .driver_data = (void *)&sipodev_desc | ||
320 | }, | ||
321 | + { | ||
322 | + .ident = "Trekstor SURFBOOK E11B", | ||
323 | + .matches = { | ||
324 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), | ||
325 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), | ||
326 | + }, | ||
327 | + .driver_data = (void *)&sipodev_desc | ||
328 | + }, | ||
329 | { | ||
330 | .ident = "Direkt-Tek DTLAPY116-2", | ||
331 | .matches = { | ||
332 | diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c | ||
333 | index d51734e0c350..977070ce4fe9 100644 | ||
334 | --- a/drivers/iommu/dmar.c | ||
335 | +++ b/drivers/iommu/dmar.c | ||
336 | @@ -39,6 +39,7 @@ | ||
337 | #include <linux/dmi.h> | ||
338 | #include <linux/slab.h> | ||
339 | #include <linux/iommu.h> | ||
340 | +#include <linux/limits.h> | ||
341 | #include <asm/irq_remapping.h> | ||
342 | #include <asm/iommu_table.h> | ||
343 | |||
344 | @@ -138,6 +139,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) | ||
345 | |||
346 | BUG_ON(dev->is_virtfn); | ||
347 | |||
348 | + /* | ||
349 | + * Ignore devices that have a domain number higher than what can | ||
350 | + * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 | ||
351 | + */ | ||
352 | + if (pci_domain_nr(dev->bus) > U16_MAX) | ||
353 | + return NULL; | ||
354 | + | ||
355 | /* Only generate path[] for device addition event */ | ||
356 | if (event == BUS_NOTIFY_ADD_DEVICE) | ||
357 | for (tmp = dev; tmp; tmp = tmp->bus->self) | ||
358 | @@ -450,12 +458,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, | ||
359 | |||
360 | /* Check for NUL termination within the designated length */ | ||
361 | if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { | ||
362 | - WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | ||
363 | + pr_warn(FW_BUG | ||
364 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" | ||
365 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
366 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
367 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
368 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
369 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | pr_info("ANDD device: %x name: %s\n", andd->device_number, | ||
373 | @@ -481,14 +490,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) | ||
374 | return 0; | ||
375 | } | ||
376 | } | ||
377 | - WARN_TAINT( | ||
378 | - 1, TAINT_FIRMWARE_WORKAROUND, | ||
379 | + pr_warn(FW_BUG | ||
380 | "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" | ||
381 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
382 | - drhd->reg_base_addr, | ||
383 | + rhsa->base_address, | ||
384 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
385 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
386 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
387 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | @@ -834,14 +843,14 @@ int __init dmar_table_init(void) | ||
392 | |||
393 | static void warn_invalid_dmar(u64 addr, const char *message) | ||
394 | { | ||
395 | - WARN_TAINT_ONCE( | ||
396 | - 1, TAINT_FIRMWARE_WORKAROUND, | ||
397 | + pr_warn_once(FW_BUG | ||
398 | "Your BIOS is broken; DMAR reported at address %llx%s!\n" | ||
399 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
400 | addr, message, | ||
401 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
402 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
403 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
404 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
405 | } | ||
406 | |||
407 | static int __ref | ||
408 | diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c | ||
409 | index 5c6e0a9fd2f3..593a4bfcba42 100644 | ||
410 | --- a/drivers/iommu/intel-iommu.c | ||
411 | +++ b/drivers/iommu/intel-iommu.c | ||
412 | @@ -4085,10 +4085,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) | ||
413 | |||
414 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ | ||
415 | drhd = dmar_find_matched_drhd_unit(pdev); | ||
416 | - if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, | ||
417 | - TAINT_FIRMWARE_WORKAROUND, | ||
418 | - "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) | ||
419 | + if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { | ||
420 | + pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); | ||
421 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
422 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; | ||
423 | + } | ||
424 | } | ||
425 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); | ||
426 | |||
427 | @@ -5192,8 +5193,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | ||
428 | u64 phys = 0; | ||
429 | |||
430 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); | ||
431 | - if (pte) | ||
432 | - phys = dma_pte_addr(pte); | ||
433 | + if (pte && dma_pte_present(pte)) | ||
434 | + phys = dma_pte_addr(pte) + | ||
435 | + (iova & (BIT_MASK(level_to_offset_bits(level) + | ||
436 | + VTD_PAGE_SHIFT) - 1)); | ||
437 | |||
438 | return phys; | ||
439 | } | ||
440 | diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c | ||
441 | index 9834d28d52e8..1f8fbd7776fb 100644 | ||
442 | --- a/drivers/net/bonding/bond_alb.c | ||
443 | +++ b/drivers/net/bonding/bond_alb.c | ||
444 | @@ -71,11 +71,6 @@ struct arp_pkt { | ||
445 | }; | ||
446 | #pragma pack() | ||
447 | |||
448 | -static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) | ||
449 | -{ | ||
450 | - return (struct arp_pkt *)skb_network_header(skb); | ||
451 | -} | ||
452 | - | ||
453 | /* Forward declaration */ | ||
454 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], | ||
455 | bool strict_match); | ||
456 | @@ -574,10 +569,11 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) | ||
457 | spin_unlock(&bond->mode_lock); | ||
458 | } | ||
459 | |||
460 | -static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond) | ||
461 | +static struct slave *rlb_choose_channel(struct sk_buff *skb, | ||
462 | + struct bonding *bond, | ||
463 | + const struct arp_pkt *arp) | ||
464 | { | ||
465 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | ||
466 | - struct arp_pkt *arp = arp_pkt(skb); | ||
467 | struct slave *assigned_slave, *curr_active_slave; | ||
468 | struct rlb_client_info *client_info; | ||
469 | u32 hash_index = 0; | ||
470 | @@ -674,8 +670,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon | ||
471 | */ | ||
472 | static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) | ||
473 | { | ||
474 | - struct arp_pkt *arp = arp_pkt(skb); | ||
475 | struct slave *tx_slave = NULL; | ||
476 | + struct arp_pkt *arp; | ||
477 | + | ||
478 | + if (!pskb_network_may_pull(skb, sizeof(*arp))) | ||
479 | + return NULL; | ||
480 | + arp = (struct arp_pkt *)skb_network_header(skb); | ||
481 | |||
482 | /* Don't modify or load balance ARPs that do not originate locally | ||
483 | * (e.g.,arrive via a bridge). | ||
484 | @@ -685,7 +685,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) | ||
485 | |||
486 | if (arp->op_code == htons(ARPOP_REPLY)) { | ||
487 | /* the arp must be sent on the selected rx channel */ | ||
488 | - tx_slave = rlb_choose_channel(skb, bond); | ||
489 | + tx_slave = rlb_choose_channel(skb, bond, arp); | ||
490 | if (tx_slave) | ||
491 | ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr); | ||
492 | netdev_dbg(bond->dev, "Server sent ARP Reply packet\n"); | ||
493 | @@ -695,7 +695,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) | ||
494 | * When the arp reply is received the entry will be updated | ||
495 | * with the correct unicast address of the client. | ||
496 | */ | ||
497 | - rlb_choose_channel(skb, bond); | ||
498 | + rlb_choose_channel(skb, bond, arp); | ||
499 | |||
500 | /* The ARP reply packets must be delayed so that | ||
501 | * they can cancel out the influence of the ARP request. | ||
502 | diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | ||
503 | index fbe3c2c114f9..736e550163e1 100644 | ||
504 | --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c | ||
505 | +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | ||
506 | @@ -6439,13 +6439,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu) | ||
507 | return -EINVAL; | ||
508 | |||
509 | if (netif_running(dev)) | ||
510 | - bnxt_close_nic(bp, false, false); | ||
511 | + bnxt_close_nic(bp, true, false); | ||
512 | |||
513 | dev->mtu = new_mtu; | ||
514 | bnxt_set_ring_params(bp); | ||
515 | |||
516 | if (netif_running(dev)) | ||
517 | - return bnxt_open_nic(bp, false, false); | ||
518 | + return bnxt_open_nic(bp, true, false); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c | ||
523 | index 1b07c6216e2a..8df32398d343 100644 | ||
524 | --- a/drivers/net/ethernet/freescale/fec_main.c | ||
525 | +++ b/drivers/net/ethernet/freescale/fec_main.c | ||
526 | @@ -2470,15 +2470,15 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) | ||
527 | return -EINVAL; | ||
528 | } | ||
529 | |||
530 | - cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); | ||
531 | + cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); | ||
532 | if (cycle > 0xFFFF) { | ||
533 | pr_err("Rx coalesced usec exceed hardware limitation\n"); | ||
534 | return -EINVAL; | ||
535 | } | ||
536 | |||
537 | - cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); | ||
538 | + cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); | ||
539 | if (cycle > 0xFFFF) { | ||
540 | - pr_err("Rx coalesced usec exceed hardware limitation\n"); | ||
541 | + pr_err("Tx coalesced usec exceed hardware limitation\n"); | ||
542 | return -EINVAL; | ||
543 | } | ||
544 | |||
545 | diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c | ||
546 | index d94e151cff12..d4747caf1e7c 100644 | ||
547 | --- a/drivers/net/ethernet/micrel/ks8851_mll.c | ||
548 | +++ b/drivers/net/ethernet/micrel/ks8851_mll.c | ||
549 | @@ -831,14 +831,17 @@ static irqreturn_t ks_irq(int irq, void *pw) | ||
550 | { | ||
551 | struct net_device *netdev = pw; | ||
552 | struct ks_net *ks = netdev_priv(netdev); | ||
553 | + unsigned long flags; | ||
554 | u16 status; | ||
555 | |||
556 | + spin_lock_irqsave(&ks->statelock, flags); | ||
557 | /*this should be the first in IRQ handler */ | ||
558 | ks_save_cmd_reg(ks); | ||
559 | |||
560 | status = ks_rdreg16(ks, KS_ISR); | ||
561 | if (unlikely(!status)) { | ||
562 | ks_restore_cmd_reg(ks); | ||
563 | + spin_unlock_irqrestore(&ks->statelock, flags); | ||
564 | return IRQ_NONE; | ||
565 | } | ||
566 | |||
567 | @@ -864,6 +867,7 @@ static irqreturn_t ks_irq(int irq, void *pw) | ||
568 | ks->netdev->stats.rx_over_errors++; | ||
569 | /* this should be the last in IRQ handler*/ | ||
570 | ks_restore_cmd_reg(ks); | ||
571 | + spin_unlock_irqrestore(&ks->statelock, flags); | ||
572 | return IRQ_HANDLED; | ||
573 | } | ||
574 | |||
575 | @@ -933,6 +937,7 @@ static int ks_net_stop(struct net_device *netdev) | ||
576 | |||
577 | /* shutdown RX/TX QMU */ | ||
578 | ks_disable_qmu(ks); | ||
579 | + ks_disable_int(ks); | ||
580 | |||
581 | /* set powermode to soft power down to save power */ | ||
582 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); | ||
583 | @@ -989,10 +994,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) | ||
584 | { | ||
585 | netdev_tx_t retv = NETDEV_TX_OK; | ||
586 | struct ks_net *ks = netdev_priv(netdev); | ||
587 | + unsigned long flags; | ||
588 | |||
589 | - disable_irq(netdev->irq); | ||
590 | - ks_disable_int(ks); | ||
591 | - spin_lock(&ks->statelock); | ||
592 | + spin_lock_irqsave(&ks->statelock, flags); | ||
593 | |||
594 | /* Extra space are required: | ||
595 | * 4 byte for alignment, 4 for status/length, 4 for CRC | ||
596 | @@ -1006,9 +1010,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) | ||
597 | dev_kfree_skb(skb); | ||
598 | } else | ||
599 | retv = NETDEV_TX_BUSY; | ||
600 | - spin_unlock(&ks->statelock); | ||
601 | - ks_enable_int(ks); | ||
602 | - enable_irq(netdev->irq); | ||
603 | + spin_unlock_irqrestore(&ks->statelock, flags); | ||
604 | return retv; | ||
605 | } | ||
606 | |||
607 | diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c | ||
608 | index c747ab652665..6c0982a39486 100644 | ||
609 | --- a/drivers/net/ipvlan/ipvlan_core.c | ||
610 | +++ b/drivers/net/ipvlan/ipvlan_core.c | ||
611 | @@ -251,6 +251,7 @@ acct: | ||
612 | } else { | ||
613 | kfree_skb(skb); | ||
614 | } | ||
615 | + cond_resched(); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | @@ -443,19 +444,21 @@ static int ipvlan_process_outbound(struct sk_buff *skb) | ||
620 | struct ethhdr *ethh = eth_hdr(skb); | ||
621 | int ret = NET_XMIT_DROP; | ||
622 | |||
623 | - /* In this mode we dont care about multicast and broadcast traffic */ | ||
624 | - if (is_multicast_ether_addr(ethh->h_dest)) { | ||
625 | - pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n", | ||
626 | - ntohs(skb->protocol)); | ||
627 | - kfree_skb(skb); | ||
628 | - goto out; | ||
629 | - } | ||
630 | - | ||
631 | /* The ipvlan is a pseudo-L2 device, so the packets that we receive | ||
632 | * will have L2; which need to discarded and processed further | ||
633 | * in the net-ns of the main-device. | ||
634 | */ | ||
635 | if (skb_mac_header_was_set(skb)) { | ||
636 | + /* In this mode we dont care about | ||
637 | + * multicast and broadcast traffic */ | ||
638 | + if (is_multicast_ether_addr(ethh->h_dest)) { | ||
639 | + pr_debug_ratelimited( | ||
640 | + "Dropped {multi|broad}cast of type=[%x]\n", | ||
641 | + ntohs(skb->protocol)); | ||
642 | + kfree_skb(skb); | ||
643 | + goto out; | ||
644 | + } | ||
645 | + | ||
646 | skb_pull(skb, sizeof(*ethh)); | ||
647 | skb->mac_header = (typeof(skb->mac_header))~0U; | ||
648 | skb_reset_network_header(skb); | ||
649 | diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c | ||
650 | index 72fb55ca27f3..72f37e546ed2 100644 | ||
651 | --- a/drivers/net/ipvlan/ipvlan_main.c | ||
652 | +++ b/drivers/net/ipvlan/ipvlan_main.c | ||
653 | @@ -217,7 +217,6 @@ static void ipvlan_uninit(struct net_device *dev) | ||
654 | static int ipvlan_open(struct net_device *dev) | ||
655 | { | ||
656 | struct ipvl_dev *ipvlan = netdev_priv(dev); | ||
657 | - struct net_device *phy_dev = ipvlan->phy_dev; | ||
658 | struct ipvl_addr *addr; | ||
659 | |||
660 | if (ipvlan->port->mode == IPVLAN_MODE_L3 || | ||
661 | @@ -229,7 +228,7 @@ static int ipvlan_open(struct net_device *dev) | ||
662 | list_for_each_entry(addr, &ipvlan->addrs, anode) | ||
663 | ipvlan_ht_addr_add(ipvlan, addr); | ||
664 | |||
665 | - return dev_uc_add(phy_dev, phy_dev->dev_addr); | ||
666 | + return 0; | ||
667 | } | ||
668 | |||
669 | static int ipvlan_stop(struct net_device *dev) | ||
670 | @@ -241,8 +240,6 @@ static int ipvlan_stop(struct net_device *dev) | ||
671 | dev_uc_unsync(phy_dev, dev); | ||
672 | dev_mc_unsync(phy_dev, dev); | ||
673 | |||
674 | - dev_uc_del(phy_dev, phy_dev->dev_addr); | ||
675 | - | ||
676 | list_for_each_entry(addr, &ipvlan->addrs, anode) | ||
677 | ipvlan_ht_addr_del(addr); | ||
678 | |||
679 | diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c | ||
680 | index a48ed0873cc7..8c64b06cb98c 100644 | ||
681 | --- a/drivers/net/macsec.c | ||
682 | +++ b/drivers/net/macsec.c | ||
683 | @@ -2871,6 +2871,11 @@ static void macsec_dev_set_rx_mode(struct net_device *dev) | ||
684 | dev_uc_sync(real_dev, dev); | ||
685 | } | ||
686 | |||
687 | +static sci_t dev_to_sci(struct net_device *dev, __be16 port) | ||
688 | +{ | ||
689 | + return make_sci(dev->dev_addr, port); | ||
690 | +} | ||
691 | + | ||
692 | static int macsec_set_mac_address(struct net_device *dev, void *p) | ||
693 | { | ||
694 | struct macsec_dev *macsec = macsec_priv(dev); | ||
695 | @@ -2892,6 +2897,7 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) | ||
696 | |||
697 | out: | ||
698 | ether_addr_copy(dev->dev_addr, addr->sa_data); | ||
699 | + macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | @@ -2976,6 +2982,7 @@ static const struct device_type macsec_type = { | ||
704 | |||
705 | static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { | ||
706 | [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, | ||
707 | + [IFLA_MACSEC_PORT] = { .type = NLA_U16 }, | ||
708 | [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, | ||
709 | [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, | ||
710 | [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, | ||
711 | @@ -3160,11 +3167,6 @@ static bool sci_exists(struct net_device *dev, sci_t sci) | ||
712 | return false; | ||
713 | } | ||
714 | |||
715 | -static sci_t dev_to_sci(struct net_device *dev, __be16 port) | ||
716 | -{ | ||
717 | - return make_sci(dev->dev_addr, port); | ||
718 | -} | ||
719 | - | ||
720 | static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) | ||
721 | { | ||
722 | struct macsec_dev *macsec = macsec_priv(dev); | ||
723 | diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c | ||
724 | index e2b3d3c4d4df..294881621430 100644 | ||
725 | --- a/drivers/net/macvlan.c | ||
726 | +++ b/drivers/net/macvlan.c | ||
727 | @@ -309,6 +309,8 @@ static void macvlan_process_broadcast(struct work_struct *w) | ||
728 | if (src) | ||
729 | dev_put(src->dev); | ||
730 | kfree_skb(skb); | ||
731 | + | ||
732 | + cond_resched(); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c | ||
737 | index 487d0372a444..2f5587306022 100644 | ||
738 | --- a/drivers/net/phy/phy_device.c | ||
739 | +++ b/drivers/net/phy/phy_device.c | ||
740 | @@ -80,7 +80,7 @@ static LIST_HEAD(phy_fixup_list); | ||
741 | static DEFINE_MUTEX(phy_fixup_lock); | ||
742 | |||
743 | #ifdef CONFIG_PM | ||
744 | -static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) | ||
745 | +static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | ||
746 | { | ||
747 | struct device_driver *drv = phydev->mdio.dev.driver; | ||
748 | struct phy_driver *phydrv = to_phy_driver(drv); | ||
749 | @@ -92,11 +92,10 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) | ||
750 | /* PHY not attached? May suspend if the PHY has not already been | ||
751 | * suspended as part of a prior call to phy_disconnect() -> | ||
752 | * phy_detach() -> phy_suspend() because the parent netdev might be the | ||
753 | - * MDIO bus driver and clock gated at this point. Also may resume if | ||
754 | - * PHY is not attached. | ||
755 | + * MDIO bus driver and clock gated at this point. | ||
756 | */ | ||
757 | if (!netdev) | ||
758 | - return suspend ? !phydev->suspended : phydev->suspended; | ||
759 | + goto out; | ||
760 | |||
761 | /* Don't suspend PHY if the attached netdev parent may wakeup. | ||
762 | * The parent may point to a PCI device, as in tg3 driver. | ||
763 | @@ -111,7 +110,8 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) | ||
764 | if (device_may_wakeup(&netdev->dev)) | ||
765 | return false; | ||
766 | |||
767 | - return true; | ||
768 | +out: | ||
769 | + return !phydev->suspended; | ||
770 | } | ||
771 | |||
772 | static int mdio_bus_phy_suspend(struct device *dev) | ||
773 | @@ -126,9 +126,11 @@ static int mdio_bus_phy_suspend(struct device *dev) | ||
774 | if (phydev->attached_dev && phydev->adjust_link) | ||
775 | phy_stop_machine(phydev); | ||
776 | |||
777 | - if (!mdio_bus_phy_may_suspend(phydev, true)) | ||
778 | + if (!mdio_bus_phy_may_suspend(phydev)) | ||
779 | return 0; | ||
780 | |||
781 | + phydev->suspended_by_mdio_bus = true; | ||
782 | + | ||
783 | return phy_suspend(phydev); | ||
784 | } | ||
785 | |||
786 | @@ -137,9 +139,11 @@ static int mdio_bus_phy_resume(struct device *dev) | ||
787 | struct phy_device *phydev = to_phy_device(dev); | ||
788 | int ret; | ||
789 | |||
790 | - if (!mdio_bus_phy_may_suspend(phydev, false)) | ||
791 | + if (!phydev->suspended_by_mdio_bus) | ||
792 | goto no_resume; | ||
793 | |||
794 | + phydev->suspended_by_mdio_bus = false; | ||
795 | + | ||
796 | ret = phy_resume(phydev); | ||
797 | if (ret < 0) | ||
798 | return ret; | ||
799 | diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c | ||
800 | index ddceed3c5a4a..a516470da015 100644 | ||
801 | --- a/drivers/net/slip/slhc.c | ||
802 | +++ b/drivers/net/slip/slhc.c | ||
803 | @@ -232,7 +232,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, | ||
804 | register struct cstate *cs = lcs->next; | ||
805 | register unsigned long deltaS, deltaA; | ||
806 | register short changes = 0; | ||
807 | - int hlen; | ||
808 | + int nlen, hlen; | ||
809 | unsigned char new_seq[16]; | ||
810 | register unsigned char *cp = new_seq; | ||
811 | struct iphdr *ip; | ||
812 | @@ -248,6 +248,8 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, | ||
813 | return isize; | ||
814 | |||
815 | ip = (struct iphdr *) icp; | ||
816 | + if (ip->version != 4 || ip->ihl < 5) | ||
817 | + return isize; | ||
818 | |||
819 | /* Bail if this packet isn't TCP, or is an IP fragment */ | ||
820 | if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { | ||
821 | @@ -258,10 +260,14 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, | ||
822 | comp->sls_o_tcp++; | ||
823 | return isize; | ||
824 | } | ||
825 | - /* Extract TCP header */ | ||
826 | + nlen = ip->ihl * 4; | ||
827 | + if (isize < nlen + sizeof(*th)) | ||
828 | + return isize; | ||
829 | |||
830 | - th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); | ||
831 | - hlen = ip->ihl*4 + th->doff*4; | ||
832 | + th = (struct tcphdr *)(icp + nlen); | ||
833 | + if (th->doff < sizeof(struct tcphdr) / 4) | ||
834 | + return isize; | ||
835 | + hlen = nlen + th->doff * 4; | ||
836 | |||
837 | /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or | ||
838 | * some other control bit is set). Also uncompressible if | ||
839 | diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c | ||
840 | index fd2573cca803..d0c18e3557f1 100644 | ||
841 | --- a/drivers/net/team/team.c | ||
842 | +++ b/drivers/net/team/team.c | ||
843 | @@ -2216,6 +2216,8 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { | ||
844 | [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, | ||
845 | [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, | ||
846 | [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, | ||
847 | + [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, | ||
848 | + [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, | ||
849 | }; | ||
850 | |||
851 | static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) | ||
852 | diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c | ||
853 | index ba7cfc089516..6e74965d26a0 100644 | ||
854 | --- a/drivers/net/usb/r8152.c | ||
855 | +++ b/drivers/net/usb/r8152.c | ||
856 | @@ -3423,7 +3423,10 @@ static void r8153_init(struct r8152 *tp) | ||
857 | if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & | ||
858 | AUTOLOAD_DONE) | ||
859 | break; | ||
860 | + | ||
861 | msleep(20); | ||
862 | + if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
863 | + break; | ||
864 | } | ||
865 | |||
866 | for (i = 0; i < 500; i++) { | ||
867 | @@ -3447,7 +3450,10 @@ static void r8153_init(struct r8152 *tp) | ||
868 | ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; | ||
869 | if (ocp_data == PHY_STAT_LAN_ON) | ||
870 | break; | ||
871 | + | ||
872 | msleep(20); | ||
873 | + if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
874 | + break; | ||
875 | } | ||
876 | |||
877 | usb_disable_lpm(tp->udev); | ||
878 | diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c | ||
879 | index df9704de0715..c6fc09d17462 100644 | ||
880 | --- a/drivers/net/wireless/marvell/mwifiex/tdls.c | ||
881 | +++ b/drivers/net/wireless/marvell/mwifiex/tdls.c | ||
882 | @@ -917,59 +917,117 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, | ||
883 | |||
884 | switch (*pos) { | ||
885 | case WLAN_EID_SUPP_RATES: | ||
886 | + if (pos[1] > 32) | ||
887 | + return; | ||
888 | sta_ptr->tdls_cap.rates_len = pos[1]; | ||
889 | for (i = 0; i < pos[1]; i++) | ||
890 | sta_ptr->tdls_cap.rates[i] = pos[i + 2]; | ||
891 | break; | ||
892 | |||
893 | case WLAN_EID_EXT_SUPP_RATES: | ||
894 | + if (pos[1] > 32) | ||
895 | + return; | ||
896 | basic = sta_ptr->tdls_cap.rates_len; | ||
897 | + if (pos[1] > 32 - basic) | ||
898 | + return; | ||
899 | for (i = 0; i < pos[1]; i++) | ||
900 | sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; | ||
901 | sta_ptr->tdls_cap.rates_len += pos[1]; | ||
902 | break; | ||
903 | case WLAN_EID_HT_CAPABILITY: | ||
904 | - memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos, | ||
905 | + if (pos > end - sizeof(struct ieee80211_ht_cap) - 2) | ||
906 | + return; | ||
907 | + if (pos[1] != sizeof(struct ieee80211_ht_cap)) | ||
908 | + return; | ||
909 | + /* copy the ie's value into ht_capb*/ | ||
910 | + memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, | ||
911 | sizeof(struct ieee80211_ht_cap)); | ||
912 | sta_ptr->is_11n_enabled = 1; | ||
913 | break; | ||
914 | case WLAN_EID_HT_OPERATION: | ||
915 | - memcpy(&sta_ptr->tdls_cap.ht_oper, pos, | ||
916 | + if (pos > end - | ||
917 | + sizeof(struct ieee80211_ht_operation) - 2) | ||
918 | + return; | ||
919 | + if (pos[1] != sizeof(struct ieee80211_ht_operation)) | ||
920 | + return; | ||
921 | + /* copy the ie's value into ht_oper*/ | ||
922 | + memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, | ||
923 | sizeof(struct ieee80211_ht_operation)); | ||
924 | break; | ||
925 | case WLAN_EID_BSS_COEX_2040: | ||
926 | + if (pos > end - 3) | ||
927 | + return; | ||
928 | + if (pos[1] != 1) | ||
929 | + return; | ||
930 | sta_ptr->tdls_cap.coex_2040 = pos[2]; | ||
931 | break; | ||
932 | case WLAN_EID_EXT_CAPABILITY: | ||
933 | + if (pos > end - sizeof(struct ieee_types_header)) | ||
934 | + return; | ||
935 | + if (pos[1] < sizeof(struct ieee_types_header)) | ||
936 | + return; | ||
937 | + if (pos[1] > 8) | ||
938 | + return; | ||
939 | memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, | ||
940 | sizeof(struct ieee_types_header) + | ||
941 | min_t(u8, pos[1], 8)); | ||
942 | break; | ||
943 | case WLAN_EID_RSN: | ||
944 | + if (pos > end - sizeof(struct ieee_types_header)) | ||
945 | + return; | ||
946 | + if (pos[1] < sizeof(struct ieee_types_header)) | ||
947 | + return; | ||
948 | + if (pos[1] > IEEE_MAX_IE_SIZE - | ||
949 | + sizeof(struct ieee_types_header)) | ||
950 | + return; | ||
951 | memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, | ||
952 | sizeof(struct ieee_types_header) + | ||
953 | min_t(u8, pos[1], IEEE_MAX_IE_SIZE - | ||
954 | sizeof(struct ieee_types_header))); | ||
955 | break; | ||
956 | case WLAN_EID_QOS_CAPA: | ||
957 | + if (pos > end - 3) | ||
958 | + return; | ||
959 | + if (pos[1] != 1) | ||
960 | + return; | ||
961 | sta_ptr->tdls_cap.qos_info = pos[2]; | ||
962 | break; | ||
963 | case WLAN_EID_VHT_OPERATION: | ||
964 | - if (priv->adapter->is_hw_11ac_capable) | ||
965 | - memcpy(&sta_ptr->tdls_cap.vhtoper, pos, | ||
966 | + if (priv->adapter->is_hw_11ac_capable) { | ||
967 | + if (pos > end - | ||
968 | + sizeof(struct ieee80211_vht_operation) - 2) | ||
969 | + return; | ||
970 | + if (pos[1] != | ||
971 | + sizeof(struct ieee80211_vht_operation)) | ||
972 | + return; | ||
973 | + /* copy the ie's value into vhtoper*/ | ||
974 | + memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2, | ||
975 | sizeof(struct ieee80211_vht_operation)); | ||
976 | + } | ||
977 | break; | ||
978 | case WLAN_EID_VHT_CAPABILITY: | ||
979 | if (priv->adapter->is_hw_11ac_capable) { | ||
980 | - memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos, | ||
981 | + if (pos > end - | ||
982 | + sizeof(struct ieee80211_vht_cap) - 2) | ||
983 | + return; | ||
984 | + if (pos[1] != sizeof(struct ieee80211_vht_cap)) | ||
985 | + return; | ||
986 | + /* copy the ie's value into vhtcap*/ | ||
987 | + memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, | ||
988 | sizeof(struct ieee80211_vht_cap)); | ||
989 | sta_ptr->is_11ac_enabled = 1; | ||
990 | } | ||
991 | break; | ||
992 | case WLAN_EID_AID: | ||
993 | - if (priv->adapter->is_hw_11ac_capable) | ||
994 | + if (priv->adapter->is_hw_11ac_capable) { | ||
995 | + if (pos > end - 4) | ||
996 | + return; | ||
997 | + if (pos[1] != 2) | ||
998 | + return; | ||
999 | sta_ptr->tdls_cap.aid = | ||
1000 | le16_to_cpu(*(__le16 *)(pos + 2)); | ||
1001 | + } | ||
1002 | + break; | ||
1003 | default: | ||
1004 | break; | ||
1005 | } | ||
1006 | diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c | ||
1007 | index d6475dcce9df..0262c8f7e7c7 100644 | ||
1008 | --- a/fs/cifs/dir.c | ||
1009 | +++ b/fs/cifs/dir.c | ||
1010 | @@ -551,7 +551,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | ||
1011 | if (server->ops->close) | ||
1012 | server->ops->close(xid, tcon, &fid); | ||
1013 | cifs_del_pending_open(&open); | ||
1014 | - fput(file); | ||
1015 | rc = -ENOMEM; | ||
1016 | } | ||
1017 | |||
1018 | diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c | ||
1019 | index bd6202b70447..daad7b04f88c 100644 | ||
1020 | --- a/fs/gfs2/inode.c | ||
1021 | +++ b/fs/gfs2/inode.c | ||
1022 | @@ -1248,7 +1248,7 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | ||
1023 | if (!(*opened & FILE_OPENED)) | ||
1024 | return finish_no_open(file, d); | ||
1025 | dput(d); | ||
1026 | - return 0; | ||
1027 | + return excl && (flags & O_CREAT) ? -EEXIST : 0; | ||
1028 | } | ||
1029 | |||
1030 | BUG_ON(d != NULL); | ||
1031 | diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c | ||
1032 | index 04dd0652bb5c..8de458d64134 100644 | ||
1033 | --- a/fs/jbd2/transaction.c | ||
1034 | +++ b/fs/jbd2/transaction.c | ||
1035 | @@ -1037,8 +1037,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh, | ||
1036 | /* For undo access buffer must have data copied */ | ||
1037 | if (undo && !jh->b_committed_data) | ||
1038 | goto out; | ||
1039 | - if (jh->b_transaction != handle->h_transaction && | ||
1040 | - jh->b_next_transaction != handle->h_transaction) | ||
1041 | + if (READ_ONCE(jh->b_transaction) != handle->h_transaction && | ||
1042 | + READ_ONCE(jh->b_next_transaction) != handle->h_transaction) | ||
1043 | goto out; | ||
1044 | /* | ||
1045 | * There are two reasons for the barrier here: | ||
1046 | @@ -2448,8 +2448,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) | ||
1047 | * our jh reference and thus __jbd2_journal_file_buffer() must not | ||
1048 | * take a new one. | ||
1049 | */ | ||
1050 | - jh->b_transaction = jh->b_next_transaction; | ||
1051 | - jh->b_next_transaction = NULL; | ||
1052 | + WRITE_ONCE(jh->b_transaction, jh->b_next_transaction); | ||
1053 | + WRITE_ONCE(jh->b_next_transaction, NULL); | ||
1054 | if (buffer_freed(bh)) | ||
1055 | jlist = BJ_Forget; | ||
1056 | else if (jh->b_modified) | ||
1057 | diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c | ||
1058 | index c2665d920cf8..2517fcd423b6 100644 | ||
1059 | --- a/fs/nfs/dir.c | ||
1060 | +++ b/fs/nfs/dir.c | ||
1061 | @@ -678,8 +678,6 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | ||
1062 | goto out_label_free; | ||
1063 | } | ||
1064 | |||
1065 | - array = kmap(page); | ||
1066 | - | ||
1067 | status = nfs_readdir_alloc_pages(pages, array_size); | ||
1068 | if (status < 0) | ||
1069 | goto out_release_array; | ||
1070 | diff --git a/fs/open.c b/fs/open.c | ||
1071 | index 8db6e3a5fc10..e17cc79bd88a 100644 | ||
1072 | --- a/fs/open.c | ||
1073 | +++ b/fs/open.c | ||
1074 | @@ -824,9 +824,6 @@ cleanup_file: | ||
1075 | * the return value of d_splice_alias(), then the caller needs to perform dput() | ||
1076 | * on it after finish_open(). | ||
1077 | * | ||
1078 | - * On successful return @file is a fully instantiated open file. After this, if | ||
1079 | - * an error occurs in ->atomic_open(), it needs to clean up with fput(). | ||
1080 | - * | ||
1081 | * Returns zero on success or -errno if the open failed. | ||
1082 | */ | ||
1083 | int finish_open(struct file *file, struct dentry *dentry, | ||
1084 | diff --git a/include/linux/phy.h b/include/linux/phy.h | ||
1085 | index 867110c9d707..8eafced47540 100644 | ||
1086 | --- a/include/linux/phy.h | ||
1087 | +++ b/include/linux/phy.h | ||
1088 | @@ -333,6 +333,7 @@ struct phy_c45_device_ids { | ||
1089 | * is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc. | ||
1090 | * has_fixups: Set to true if this phy has fixups/quirks. | ||
1091 | * suspended: Set to true if this phy has been suspended successfully. | ||
1092 | + * suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus. | ||
1093 | * state: state of the PHY for management purposes | ||
1094 | * dev_flags: Device-specific flags used by the PHY driver. | ||
1095 | * link_timeout: The number of timer firings to wait before the | ||
1096 | @@ -369,6 +370,7 @@ struct phy_device { | ||
1097 | bool is_pseudo_fixed_link; | ||
1098 | bool has_fixups; | ||
1099 | bool suspended; | ||
1100 | + bool suspended_by_mdio_bus; | ||
1101 | |||
1102 | enum phy_state state; | ||
1103 | |||
1104 | diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h | ||
1105 | index 456e4a6006ab..0b0ad792dd5c 100644 | ||
1106 | --- a/include/net/fib_rules.h | ||
1107 | +++ b/include/net/fib_rules.h | ||
1108 | @@ -87,6 +87,7 @@ struct fib_rules_ops { | ||
1109 | [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ | ||
1110 | [FRA_PRIORITY] = { .type = NLA_U32 }, \ | ||
1111 | [FRA_FWMARK] = { .type = NLA_U32 }, \ | ||
1112 | + [FRA_TUN_ID] = { .type = NLA_U64 }, \ | ||
1113 | [FRA_FWMASK] = { .type = NLA_U32 }, \ | ||
1114 | [FRA_TABLE] = { .type = NLA_U32 }, \ | ||
1115 | [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \ | ||
1116 | diff --git a/kernel/cgroup.c b/kernel/cgroup.c | ||
1117 | index bb0cf1caf1cd..2d7a4fc42a88 100644 | ||
1118 | --- a/kernel/cgroup.c | ||
1119 | +++ b/kernel/cgroup.c | ||
1120 | @@ -6335,6 +6335,10 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd) | ||
1121 | return; | ||
1122 | } | ||
1123 | |||
1124 | + /* Don't associate the sock with unrelated interrupted task's cgroup. */ | ||
1125 | + if (in_interrupt()) | ||
1126 | + return; | ||
1127 | + | ||
1128 | rcu_read_lock(); | ||
1129 | |||
1130 | while (true) { | ||
1131 | diff --git a/kernel/signal.c b/kernel/signal.c | ||
1132 | index 57fadbe69c2e..d90ccbeb909d 100644 | ||
1133 | --- a/kernel/signal.c | ||
1134 | +++ b/kernel/signal.c | ||
1135 | @@ -373,27 +373,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi | ||
1136 | { | ||
1137 | struct sigqueue *q = NULL; | ||
1138 | struct user_struct *user; | ||
1139 | + int sigpending; | ||
1140 | |||
1141 | /* | ||
1142 | * Protect access to @t credentials. This can go away when all | ||
1143 | * callers hold rcu read lock. | ||
1144 | + * | ||
1145 | + * NOTE! A pending signal will hold on to the user refcount, | ||
1146 | + * and we get/put the refcount only when the sigpending count | ||
1147 | + * changes from/to zero. | ||
1148 | */ | ||
1149 | rcu_read_lock(); | ||
1150 | - user = get_uid(__task_cred(t)->user); | ||
1151 | - atomic_inc(&user->sigpending); | ||
1152 | + user = __task_cred(t)->user; | ||
1153 | + sigpending = atomic_inc_return(&user->sigpending); | ||
1154 | + if (sigpending == 1) | ||
1155 | + get_uid(user); | ||
1156 | rcu_read_unlock(); | ||
1157 | |||
1158 | - if (override_rlimit || | ||
1159 | - atomic_read(&user->sigpending) <= | ||
1160 | - task_rlimit(t, RLIMIT_SIGPENDING)) { | ||
1161 | + if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) { | ||
1162 | q = kmem_cache_alloc(sigqueue_cachep, flags); | ||
1163 | } else { | ||
1164 | print_dropped_signal(sig); | ||
1165 | } | ||
1166 | |||
1167 | if (unlikely(q == NULL)) { | ||
1168 | - atomic_dec(&user->sigpending); | ||
1169 | - free_uid(user); | ||
1170 | + if (atomic_dec_and_test(&user->sigpending)) | ||
1171 | + free_uid(user); | ||
1172 | } else { | ||
1173 | INIT_LIST_HEAD(&q->list); | ||
1174 | q->flags = 0; | ||
1175 | @@ -407,8 +412,8 @@ static void __sigqueue_free(struct sigqueue *q) | ||
1176 | { | ||
1177 | if (q->flags & SIGQUEUE_PREALLOC) | ||
1178 | return; | ||
1179 | - atomic_dec(&q->user->sigpending); | ||
1180 | - free_uid(q->user); | ||
1181 | + if (atomic_dec_and_test(&q->user->sigpending)) | ||
1182 | + free_uid(q->user); | ||
1183 | kmem_cache_free(sigqueue_cachep, q); | ||
1184 | } | ||
1185 | |||
1186 | diff --git a/kernel/workqueue.c b/kernel/workqueue.c | ||
1187 | index 7d970b565c4d..00c295d3104b 100644 | ||
1188 | --- a/kernel/workqueue.c | ||
1189 | +++ b/kernel/workqueue.c | ||
1190 | @@ -1384,14 +1384,16 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, | ||
1191 | WARN_ON_ONCE(!is_chained_work(wq))) | ||
1192 | return; | ||
1193 | retry: | ||
1194 | - if (req_cpu == WORK_CPU_UNBOUND) | ||
1195 | - cpu = wq_select_unbound_cpu(raw_smp_processor_id()); | ||
1196 | - | ||
1197 | /* pwq which will be used unless @work is executing elsewhere */ | ||
1198 | - if (!(wq->flags & WQ_UNBOUND)) | ||
1199 | - pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); | ||
1200 | - else | ||
1201 | + if (wq->flags & WQ_UNBOUND) { | ||
1202 | + if (req_cpu == WORK_CPU_UNBOUND) | ||
1203 | + cpu = wq_select_unbound_cpu(raw_smp_processor_id()); | ||
1204 | pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); | ||
1205 | + } else { | ||
1206 | + if (req_cpu == WORK_CPU_UNBOUND) | ||
1207 | + cpu = raw_smp_processor_id(); | ||
1208 | + pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); | ||
1209 | + } | ||
1210 | |||
1211 | /* | ||
1212 | * If @work was previously on a different pool, it might still be | ||
1213 | diff --git a/mm/memcontrol.c b/mm/memcontrol.c | ||
1214 | index 0f8422239dea..b85a1c040bc9 100644 | ||
1215 | --- a/mm/memcontrol.c | ||
1216 | +++ b/mm/memcontrol.c | ||
1217 | @@ -5726,6 +5726,10 @@ void mem_cgroup_sk_alloc(struct sock *sk) | ||
1218 | return; | ||
1219 | } | ||
1220 | |||
1221 | + /* Do not associate the sock with unrelated interrupted task's memcg. */ | ||
1222 | + if (in_interrupt()) | ||
1223 | + return; | ||
1224 | + | ||
1225 | rcu_read_lock(); | ||
1226 | memcg = mem_cgroup_from_task(current); | ||
1227 | if (memcg == root_mem_cgroup) | ||
1228 | diff --git a/mm/slub.c b/mm/slub.c | ||
1229 | index fa6d62d559eb..4a5b2a0f9360 100644 | ||
1230 | --- a/mm/slub.c | ||
1231 | +++ b/mm/slub.c | ||
1232 | @@ -3114,6 +3114,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, | ||
1233 | void *object = c->freelist; | ||
1234 | |||
1235 | if (unlikely(!object)) { | ||
1236 | + /* | ||
1237 | + * We may have removed an object from c->freelist using | ||
1238 | + * the fastpath in the previous iteration; in that case, | ||
1239 | + * c->tid has not been bumped yet. | ||
1240 | + * Since ___slab_alloc() may reenable interrupts while | ||
1241 | + * allocating memory, we should bump c->tid now. | ||
1242 | + */ | ||
1243 | + c->tid = next_tid(c->tid); | ||
1244 | + | ||
1245 | /* | ||
1246 | * Invoking slow path likely have side-effect | ||
1247 | * of re-populating per CPU c->freelist | ||
1248 | diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c | ||
1249 | index 780700fcbe63..2b663622bdb4 100644 | ||
1250 | --- a/net/batman-adv/bat_iv_ogm.c | ||
1251 | +++ b/net/batman-adv/bat_iv_ogm.c | ||
1252 | @@ -34,6 +34,7 @@ | ||
1253 | #include <linux/kref.h> | ||
1254 | #include <linux/list.h> | ||
1255 | #include <linux/lockdep.h> | ||
1256 | +#include <linux/mutex.h> | ||
1257 | #include <linux/netdevice.h> | ||
1258 | #include <linux/netlink.h> | ||
1259 | #include <linux/pkt_sched.h> | ||
1260 | @@ -149,7 +150,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node) | ||
1261 | * Return: 0 on success, a negative error code otherwise. | ||
1262 | */ | ||
1263 | static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node, | ||
1264 | - int max_if_num) | ||
1265 | + unsigned int max_if_num) | ||
1266 | { | ||
1267 | void *data_ptr; | ||
1268 | size_t old_size; | ||
1269 | @@ -193,7 +194,8 @@ unlock: | ||
1270 | */ | ||
1271 | static void | ||
1272 | batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node, | ||
1273 | - int max_if_num, int del_if_num) | ||
1274 | + unsigned int max_if_num, | ||
1275 | + unsigned int del_if_num) | ||
1276 | { | ||
1277 | size_t chunk_size; | ||
1278 | size_t if_offset; | ||
1279 | @@ -231,7 +233,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node, | ||
1280 | */ | ||
1281 | static void | ||
1282 | batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node, | ||
1283 | - int max_if_num, int del_if_num) | ||
1284 | + unsigned int max_if_num, | ||
1285 | + unsigned int del_if_num) | ||
1286 | { | ||
1287 | size_t if_offset; | ||
1288 | void *data_ptr; | ||
1289 | @@ -268,7 +271,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node, | ||
1290 | * Return: 0 on success, a negative error code otherwise. | ||
1291 | */ | ||
1292 | static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node, | ||
1293 | - int max_if_num, int del_if_num) | ||
1294 | + unsigned int max_if_num, | ||
1295 | + unsigned int del_if_num) | ||
1296 | { | ||
1297 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); | ||
1298 | |||
1299 | @@ -302,7 +306,8 @@ static struct batadv_orig_node * | ||
1300 | batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr) | ||
1301 | { | ||
1302 | struct batadv_orig_node *orig_node; | ||
1303 | - int size, hash_added; | ||
1304 | + int hash_added; | ||
1305 | + size_t size; | ||
1306 | |||
1307 | orig_node = batadv_orig_hash_find(bat_priv, addr); | ||
1308 | if (orig_node) | ||
1309 | @@ -366,14 +371,18 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) | ||
1310 | unsigned char *ogm_buff; | ||
1311 | u32 random_seqno; | ||
1312 | |||
1313 | + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1314 | + | ||
1315 | /* randomize initial seqno to avoid collision */ | ||
1316 | get_random_bytes(&random_seqno, sizeof(random_seqno)); | ||
1317 | atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); | ||
1318 | |||
1319 | hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; | ||
1320 | ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); | ||
1321 | - if (!ogm_buff) | ||
1322 | + if (!ogm_buff) { | ||
1323 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1324 | return -ENOMEM; | ||
1325 | + } | ||
1326 | |||
1327 | hard_iface->bat_iv.ogm_buff = ogm_buff; | ||
1328 | |||
1329 | @@ -385,35 +394,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) | ||
1330 | batadv_ogm_packet->reserved = 0; | ||
1331 | batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; | ||
1332 | |||
1333 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1334 | + | ||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1338 | static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) | ||
1339 | { | ||
1340 | + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1341 | + | ||
1342 | kfree(hard_iface->bat_iv.ogm_buff); | ||
1343 | hard_iface->bat_iv.ogm_buff = NULL; | ||
1344 | + | ||
1345 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1346 | } | ||
1347 | |||
1348 | static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) | ||
1349 | { | ||
1350 | struct batadv_ogm_packet *batadv_ogm_packet; | ||
1351 | - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
1352 | + void *ogm_buff; | ||
1353 | |||
1354 | - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | ||
1355 | + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1356 | + | ||
1357 | + ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
1358 | + if (!ogm_buff) | ||
1359 | + goto unlock; | ||
1360 | + | ||
1361 | + batadv_ogm_packet = ogm_buff; | ||
1362 | ether_addr_copy(batadv_ogm_packet->orig, | ||
1363 | hard_iface->net_dev->dev_addr); | ||
1364 | ether_addr_copy(batadv_ogm_packet->prev_sender, | ||
1365 | hard_iface->net_dev->dev_addr); | ||
1366 | + | ||
1367 | +unlock: | ||
1368 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1369 | } | ||
1370 | |||
1371 | static void | ||
1372 | batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) | ||
1373 | { | ||
1374 | struct batadv_ogm_packet *batadv_ogm_packet; | ||
1375 | - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
1376 | + void *ogm_buff; | ||
1377 | |||
1378 | - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | ||
1379 | + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1380 | + | ||
1381 | + ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
1382 | + if (!ogm_buff) | ||
1383 | + goto unlock; | ||
1384 | + | ||
1385 | + batadv_ogm_packet = ogm_buff; | ||
1386 | batadv_ogm_packet->ttl = BATADV_TTL; | ||
1387 | + | ||
1388 | +unlock: | ||
1389 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1390 | } | ||
1391 | |||
1392 | /* when do we schedule our own ogm to be sent */ | ||
1393 | @@ -898,7 +931,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) | ||
1394 | u32 i; | ||
1395 | size_t word_index; | ||
1396 | u8 *w; | ||
1397 | - int if_num; | ||
1398 | + unsigned int if_num; | ||
1399 | |||
1400 | for (i = 0; i < hash->size; i++) { | ||
1401 | head = &hash->table[i]; | ||
1402 | @@ -919,7 +952,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) | ||
1403 | } | ||
1404 | } | ||
1405 | |||
1406 | -static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | ||
1407 | +/** | ||
1408 | + * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer | ||
1409 | + * @hard_iface: interface whose ogm buffer should be transmitted | ||
1410 | + */ | ||
1411 | +static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) | ||
1412 | { | ||
1413 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | ||
1414 | unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; | ||
1415 | @@ -930,8 +967,10 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | ||
1416 | u16 tvlv_len = 0; | ||
1417 | unsigned long send_time; | ||
1418 | |||
1419 | - if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) || | ||
1420 | - (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)) | ||
1421 | + lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1422 | + | ||
1423 | + /* interface already disabled by batadv_iv_ogm_iface_disable */ | ||
1424 | + if (!*ogm_buff) | ||
1425 | return; | ||
1426 | |||
1427 | /* the interface gets activated here to avoid race conditions between | ||
1428 | @@ -1000,6 +1039,17 @@ out: | ||
1429 | batadv_hardif_put(primary_if); | ||
1430 | } | ||
1431 | |||
1432 | +static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | ||
1433 | +{ | ||
1434 | + if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || | ||
1435 | + hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) | ||
1436 | + return; | ||
1437 | + | ||
1438 | + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1439 | + batadv_iv_ogm_schedule_buff(hard_iface); | ||
1440 | + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); | ||
1441 | +} | ||
1442 | + | ||
1443 | /** | ||
1444 | * batadv_iv_ogm_orig_update - use OGM to update corresponding data in an | ||
1445 | * originator | ||
1446 | @@ -1028,7 +1078,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | ||
1447 | struct batadv_neigh_node *tmp_neigh_node = NULL; | ||
1448 | struct batadv_neigh_node *router = NULL; | ||
1449 | struct batadv_orig_node *orig_node_tmp; | ||
1450 | - int if_num; | ||
1451 | + unsigned int if_num; | ||
1452 | u8 sum_orig, sum_neigh; | ||
1453 | u8 *neigh_addr; | ||
1454 | u8 tq_avg; | ||
1455 | @@ -1186,7 +1236,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | ||
1456 | u8 total_count; | ||
1457 | u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; | ||
1458 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; | ||
1459 | - int if_num; | ||
1460 | + unsigned int if_num; | ||
1461 | unsigned int tq_asym_penalty, inv_asym_penalty; | ||
1462 | unsigned int combined_tq; | ||
1463 | unsigned int tq_iface_penalty; | ||
1464 | @@ -1227,7 +1277,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | ||
1465 | orig_node->last_seen = jiffies; | ||
1466 | |||
1467 | /* find packet count of corresponding one hop neighbor */ | ||
1468 | - spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); | ||
1469 | + spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); | ||
1470 | if_num = if_incoming->if_num; | ||
1471 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; | ||
1472 | neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); | ||
1473 | @@ -1237,7 +1287,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | ||
1474 | } else { | ||
1475 | neigh_rq_count = 0; | ||
1476 | } | ||
1477 | - spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); | ||
1478 | + spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); | ||
1479 | |||
1480 | /* pay attention to not get a value bigger than 100 % */ | ||
1481 | if (orig_eq_count > neigh_rq_count) | ||
1482 | @@ -1705,9 +1755,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, | ||
1483 | |||
1484 | if (is_my_orig) { | ||
1485 | unsigned long *word; | ||
1486 | - int offset; | ||
1487 | + size_t offset; | ||
1488 | s32 bit_pos; | ||
1489 | - s16 if_num; | ||
1490 | + unsigned int if_num; | ||
1491 | u8 *weight; | ||
1492 | |||
1493 | orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, | ||
1494 | @@ -2473,12 +2523,22 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1, | ||
1495 | return ret; | ||
1496 | } | ||
1497 | |||
1498 | -static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface) | ||
1499 | +static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface) | ||
1500 | { | ||
1501 | /* begin scheduling originator messages on that interface */ | ||
1502 | batadv_iv_ogm_schedule(hard_iface); | ||
1503 | } | ||
1504 | |||
1505 | +/** | ||
1506 | + * batadv_iv_init_sel_class - initialize GW selection class | ||
1507 | + * @bat_priv: the bat priv with all the soft interface information | ||
1508 | + */ | ||
1509 | +static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv) | ||
1510 | +{ | ||
1511 | + /* set default TQ difference threshold to 20 */ | ||
1512 | + atomic_set(&bat_priv->gw.sel_class, 20); | ||
1513 | +} | ||
1514 | + | ||
1515 | static struct batadv_gw_node * | ||
1516 | batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv) | ||
1517 | { | ||
1518 | @@ -2803,8 +2863,8 @@ unlock: | ||
1519 | static struct batadv_algo_ops batadv_batman_iv __read_mostly = { | ||
1520 | .name = "BATMAN_IV", | ||
1521 | .iface = { | ||
1522 | - .activate = batadv_iv_iface_activate, | ||
1523 | .enable = batadv_iv_ogm_iface_enable, | ||
1524 | + .enabled = batadv_iv_iface_enabled, | ||
1525 | .disable = batadv_iv_ogm_iface_disable, | ||
1526 | .update_mac = batadv_iv_ogm_iface_update_mac, | ||
1527 | .primary_set = batadv_iv_ogm_primary_iface_set, | ||
1528 | @@ -2827,6 +2887,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { | ||
1529 | .del_if = batadv_iv_ogm_orig_del_if, | ||
1530 | }, | ||
1531 | .gw = { | ||
1532 | + .init_sel_class = batadv_iv_init_sel_class, | ||
1533 | .get_best_gw_node = batadv_iv_gw_get_best_gw_node, | ||
1534 | .is_eligible = batadv_iv_gw_is_eligible, | ||
1535 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS | ||
1536 | diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c | ||
1537 | index 4348118e7eac..18fa602e5fc6 100644 | ||
1538 | --- a/net/batman-adv/bat_v.c | ||
1539 | +++ b/net/batman-adv/bat_v.c | ||
1540 | @@ -19,7 +19,6 @@ | ||
1541 | #include "main.h" | ||
1542 | |||
1543 | #include <linux/atomic.h> | ||
1544 | -#include <linux/bug.h> | ||
1545 | #include <linux/cache.h> | ||
1546 | #include <linux/errno.h> | ||
1547 | #include <linux/if_ether.h> | ||
1548 | @@ -623,11 +622,11 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, | ||
1549 | int ret = 0; | ||
1550 | |||
1551 | ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); | ||
1552 | - if (WARN_ON(!ifinfo1)) | ||
1553 | + if (!ifinfo1) | ||
1554 | goto err_ifinfo1; | ||
1555 | |||
1556 | ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); | ||
1557 | - if (WARN_ON(!ifinfo2)) | ||
1558 | + if (!ifinfo2) | ||
1559 | goto err_ifinfo2; | ||
1560 | |||
1561 | ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; | ||
1562 | @@ -649,11 +648,11 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, | ||
1563 | bool ret = false; | ||
1564 | |||
1565 | ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); | ||
1566 | - if (WARN_ON(!ifinfo1)) | ||
1567 | + if (!ifinfo1) | ||
1568 | goto err_ifinfo1; | ||
1569 | |||
1570 | ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); | ||
1571 | - if (WARN_ON(!ifinfo2)) | ||
1572 | + if (!ifinfo2) | ||
1573 | goto err_ifinfo2; | ||
1574 | |||
1575 | threshold = ifinfo1->bat_v.throughput / 4; | ||
1576 | @@ -668,6 +667,16 @@ err_ifinfo1: | ||
1577 | return ret; | ||
1578 | } | ||
1579 | |||
1580 | +/** | ||
1581 | + * batadv_v_init_sel_class - initialize GW selection class | ||
1582 | + * @bat_priv: the bat priv with all the soft interface information | ||
1583 | + */ | ||
1584 | +static void batadv_v_init_sel_class(struct batadv_priv *bat_priv) | ||
1585 | +{ | ||
1586 | + /* set default throughput difference threshold to 5Mbps */ | ||
1587 | + atomic_set(&bat_priv->gw.sel_class, 50); | ||
1588 | +} | ||
1589 | + | ||
1590 | static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv, | ||
1591 | char *buff, size_t count) | ||
1592 | { | ||
1593 | @@ -805,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv, | ||
1594 | } | ||
1595 | |||
1596 | orig_gw = batadv_gw_node_get(bat_priv, orig_node); | ||
1597 | - if (!orig_node) | ||
1598 | + if (!orig_gw) | ||
1599 | goto out; | ||
1600 | |||
1601 | if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) | ||
1602 | @@ -1054,6 +1063,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { | ||
1603 | .dump = batadv_v_orig_dump, | ||
1604 | }, | ||
1605 | .gw = { | ||
1606 | + .init_sel_class = batadv_v_init_sel_class, | ||
1607 | .store_sel_class = batadv_v_store_sel_class, | ||
1608 | .show_sel_class = batadv_v_show_sel_class, | ||
1609 | .get_best_gw_node = batadv_v_gw_get_best_gw_node, | ||
1610 | @@ -1094,9 +1104,6 @@ int batadv_v_mesh_init(struct batadv_priv *bat_priv) | ||
1611 | if (ret < 0) | ||
1612 | return ret; | ||
1613 | |||
1614 | - /* set default throughput difference threshold to 5Mbps */ | ||
1615 | - atomic_set(&bat_priv->gw.sel_class, 50); | ||
1616 | - | ||
1617 | return 0; | ||
1618 | } | ||
1619 | |||
1620 | diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c | ||
1621 | index 5d79004de25c..62df763b2aae 100644 | ||
1622 | --- a/net/batman-adv/bat_v_elp.c | ||
1623 | +++ b/net/batman-adv/bat_v_elp.c | ||
1624 | @@ -19,6 +19,7 @@ | ||
1625 | #include "main.h" | ||
1626 | |||
1627 | #include <linux/atomic.h> | ||
1628 | +#include <linux/bitops.h> | ||
1629 | #include <linux/byteorder/generic.h> | ||
1630 | #include <linux/errno.h> | ||
1631 | #include <linux/etherdevice.h> | ||
1632 | @@ -29,6 +30,7 @@ | ||
1633 | #include <linux/kernel.h> | ||
1634 | #include <linux/kref.h> | ||
1635 | #include <linux/netdevice.h> | ||
1636 | +#include <linux/nl80211.h> | ||
1637 | #include <linux/random.h> | ||
1638 | #include <linux/rculist.h> | ||
1639 | #include <linux/rcupdate.h> | ||
1640 | @@ -100,8 +102,12 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) | ||
1641 | */ | ||
1642 | return 0; | ||
1643 | } | ||
1644 | - if (!ret) | ||
1645 | - return sinfo.expected_throughput / 100; | ||
1646 | + if (ret) | ||
1647 | + goto default_throughput; | ||
1648 | + if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))) | ||
1649 | + goto default_throughput; | ||
1650 | + | ||
1651 | + return sinfo.expected_throughput / 100; | ||
1652 | } | ||
1653 | |||
1654 | /* unsupported WiFi driver version */ | ||
1655 | @@ -185,6 +191,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) | ||
1656 | struct sk_buff *skb; | ||
1657 | int probe_len, i; | ||
1658 | int elp_skb_len; | ||
1659 | + void *tmp; | ||
1660 | |||
1661 | /* this probing routine is for Wifi neighbours only */ | ||
1662 | if (!batadv_is_wifi_netdev(hard_iface->net_dev)) | ||
1663 | @@ -216,7 +223,8 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) | ||
1664 | * the packet to be exactly of that size to make the link | ||
1665 | * throughput estimation effective. | ||
1666 | */ | ||
1667 | - skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len); | ||
1668 | + tmp = skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len); | ||
1669 | + memset(tmp, 0, probe_len - hard_iface->bat_v.elp_skb->len); | ||
1670 | |||
1671 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
1672 | "Sending unicast (probe) ELP packet on interface %s to %pM\n", | ||
1673 | @@ -327,21 +335,23 @@ out: | ||
1674 | */ | ||
1675 | int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) | ||
1676 | { | ||
1677 | + static const size_t tvlv_padding = sizeof(__be32); | ||
1678 | struct batadv_elp_packet *elp_packet; | ||
1679 | unsigned char *elp_buff; | ||
1680 | u32 random_seqno; | ||
1681 | size_t size; | ||
1682 | int res = -ENOMEM; | ||
1683 | |||
1684 | - size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN; | ||
1685 | + size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding; | ||
1686 | hard_iface->bat_v.elp_skb = dev_alloc_skb(size); | ||
1687 | if (!hard_iface->bat_v.elp_skb) | ||
1688 | goto out; | ||
1689 | |||
1690 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); | ||
1691 | - elp_buff = skb_put(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); | ||
1692 | + elp_buff = skb_put(hard_iface->bat_v.elp_skb, | ||
1693 | + BATADV_ELP_HLEN + tvlv_padding); | ||
1694 | elp_packet = (struct batadv_elp_packet *)elp_buff; | ||
1695 | - memset(elp_packet, 0, BATADV_ELP_HLEN); | ||
1696 | + memset(elp_packet, 0, BATADV_ELP_HLEN + tvlv_padding); | ||
1697 | |||
1698 | elp_packet->packet_type = BATADV_ELP; | ||
1699 | elp_packet->version = BATADV_COMPAT_VERSION; | ||
1700 | diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c | ||
1701 | index f435435b447e..b0cae59bd327 100644 | ||
1702 | --- a/net/batman-adv/bat_v_ogm.c | ||
1703 | +++ b/net/batman-adv/bat_v_ogm.c | ||
1704 | @@ -28,6 +28,8 @@ | ||
1705 | #include <linux/kernel.h> | ||
1706 | #include <linux/kref.h> | ||
1707 | #include <linux/list.h> | ||
1708 | +#include <linux/lockdep.h> | ||
1709 | +#include <linux/mutex.h> | ||
1710 | #include <linux/netdevice.h> | ||
1711 | #include <linux/random.h> | ||
1712 | #include <linux/rculist.h> | ||
1713 | @@ -127,22 +129,19 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, | ||
1714 | } | ||
1715 | |||
1716 | /** | ||
1717 | - * batadv_v_ogm_send - periodic worker broadcasting the own OGM | ||
1718 | - * @work: work queue item | ||
1719 | + * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM | ||
1720 | + * @bat_priv: the bat priv with all the soft interface information | ||
1721 | */ | ||
1722 | -static void batadv_v_ogm_send(struct work_struct *work) | ||
1723 | +static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv) | ||
1724 | { | ||
1725 | struct batadv_hard_iface *hard_iface; | ||
1726 | - struct batadv_priv_bat_v *bat_v; | ||
1727 | - struct batadv_priv *bat_priv; | ||
1728 | struct batadv_ogm2_packet *ogm_packet; | ||
1729 | struct sk_buff *skb, *skb_tmp; | ||
1730 | unsigned char *ogm_buff, *pkt_buff; | ||
1731 | int ogm_buff_len; | ||
1732 | u16 tvlv_len = 0; | ||
1733 | |||
1734 | - bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); | ||
1735 | - bat_priv = container_of(bat_v, struct batadv_priv, bat_v); | ||
1736 | + lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); | ||
1737 | |||
1738 | if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) | ||
1739 | goto out; | ||
1740 | @@ -209,6 +208,23 @@ out: | ||
1741 | return; | ||
1742 | } | ||
1743 | |||
1744 | +/** | ||
1745 | + * batadv_v_ogm_send() - periodic worker broadcasting the own OGM | ||
1746 | + * @work: work queue item | ||
1747 | + */ | ||
1748 | +static void batadv_v_ogm_send(struct work_struct *work) | ||
1749 | +{ | ||
1750 | + struct batadv_priv_bat_v *bat_v; | ||
1751 | + struct batadv_priv *bat_priv; | ||
1752 | + | ||
1753 | + bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); | ||
1754 | + bat_priv = container_of(bat_v, struct batadv_priv, bat_v); | ||
1755 | + | ||
1756 | + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1757 | + batadv_v_ogm_send_softif(bat_priv); | ||
1758 | + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1759 | +} | ||
1760 | + | ||
1761 | /** | ||
1762 | * batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V | ||
1763 | * @hard_iface: the interface to prepare | ||
1764 | @@ -235,11 +251,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) | ||
1765 | struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); | ||
1766 | struct batadv_ogm2_packet *ogm_packet; | ||
1767 | |||
1768 | + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1769 | if (!bat_priv->bat_v.ogm_buff) | ||
1770 | - return; | ||
1771 | + goto unlock; | ||
1772 | |||
1773 | ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff; | ||
1774 | ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr); | ||
1775 | + | ||
1776 | +unlock: | ||
1777 | + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1778 | } | ||
1779 | |||
1780 | /** | ||
1781 | @@ -827,6 +847,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) | ||
1782 | atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno); | ||
1783 | INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send); | ||
1784 | |||
1785 | + mutex_init(&bat_priv->bat_v.ogm_buff_mutex); | ||
1786 | + | ||
1787 | return 0; | ||
1788 | } | ||
1789 | |||
1790 | @@ -838,7 +860,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv) | ||
1791 | { | ||
1792 | cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq); | ||
1793 | |||
1794 | + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1795 | + | ||
1796 | kfree(bat_priv->bat_v.ogm_buff); | ||
1797 | bat_priv->bat_v.ogm_buff = NULL; | ||
1798 | bat_priv->bat_v.ogm_buff_len = 0; | ||
1799 | + | ||
1800 | + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); | ||
1801 | } | ||
1802 | diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c | ||
1803 | index b4ffba7dd583..e0ab277db503 100644 | ||
1804 | --- a/net/batman-adv/debugfs.c | ||
1805 | +++ b/net/batman-adv/debugfs.c | ||
1806 | @@ -18,6 +18,7 @@ | ||
1807 | #include "debugfs.h" | ||
1808 | #include "main.h" | ||
1809 | |||
1810 | +#include <linux/dcache.h> | ||
1811 | #include <linux/debugfs.h> | ||
1812 | #include <linux/device.h> | ||
1813 | #include <linux/errno.h> | ||
1814 | @@ -339,6 +340,25 @@ out: | ||
1815 | return -ENOMEM; | ||
1816 | } | ||
1817 | |||
1818 | +/** | ||
1819 | + * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif | ||
1820 | + * @hard_iface: hard interface which was renamed | ||
1821 | + */ | ||
1822 | +void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) | ||
1823 | +{ | ||
1824 | + const char *name = hard_iface->net_dev->name; | ||
1825 | + struct dentry *dir; | ||
1826 | + struct dentry *d; | ||
1827 | + | ||
1828 | + dir = hard_iface->debug_dir; | ||
1829 | + if (!dir) | ||
1830 | + return; | ||
1831 | + | ||
1832 | + d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); | ||
1833 | + if (!d) | ||
1834 | + pr_err("Can't rename debugfs dir to %s\n", name); | ||
1835 | +} | ||
1836 | + | ||
1837 | /** | ||
1838 | * batadv_debugfs_del_hardif - delete the base directory for a hard interface | ||
1839 | * in debugfs. | ||
1840 | @@ -403,6 +423,26 @@ out: | ||
1841 | return -ENOMEM; | ||
1842 | } | ||
1843 | |||
1844 | +/** | ||
1845 | + * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif | ||
1846 | + * @dev: net_device which was renamed | ||
1847 | + */ | ||
1848 | +void batadv_debugfs_rename_meshif(struct net_device *dev) | ||
1849 | +{ | ||
1850 | + struct batadv_priv *bat_priv = netdev_priv(dev); | ||
1851 | + const char *name = dev->name; | ||
1852 | + struct dentry *dir; | ||
1853 | + struct dentry *d; | ||
1854 | + | ||
1855 | + dir = bat_priv->debug_dir; | ||
1856 | + if (!dir) | ||
1857 | + return; | ||
1858 | + | ||
1859 | + d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); | ||
1860 | + if (!d) | ||
1861 | + pr_err("Can't rename debugfs dir to %s\n", name); | ||
1862 | +} | ||
1863 | + | ||
1864 | void batadv_debugfs_del_meshif(struct net_device *dev) | ||
1865 | { | ||
1866 | struct batadv_priv *bat_priv = netdev_priv(dev); | ||
1867 | diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h | ||
1868 | index e49121ee55f6..59a0d6d70ecd 100644 | ||
1869 | --- a/net/batman-adv/debugfs.h | ||
1870 | +++ b/net/batman-adv/debugfs.h | ||
1871 | @@ -29,8 +29,10 @@ struct net_device; | ||
1872 | void batadv_debugfs_init(void); | ||
1873 | void batadv_debugfs_destroy(void); | ||
1874 | int batadv_debugfs_add_meshif(struct net_device *dev); | ||
1875 | +void batadv_debugfs_rename_meshif(struct net_device *dev); | ||
1876 | void batadv_debugfs_del_meshif(struct net_device *dev); | ||
1877 | int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface); | ||
1878 | +void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface); | ||
1879 | void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface); | ||
1880 | |||
1881 | #else | ||
1882 | @@ -48,6 +50,10 @@ static inline int batadv_debugfs_add_meshif(struct net_device *dev) | ||
1883 | return 0; | ||
1884 | } | ||
1885 | |||
1886 | +static inline void batadv_debugfs_rename_meshif(struct net_device *dev) | ||
1887 | +{ | ||
1888 | +} | ||
1889 | + | ||
1890 | static inline void batadv_debugfs_del_meshif(struct net_device *dev) | ||
1891 | { | ||
1892 | } | ||
1893 | @@ -58,6 +64,11 @@ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) | ||
1894 | return 0; | ||
1895 | } | ||
1896 | |||
1897 | +static inline | ||
1898 | +void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) | ||
1899 | +{ | ||
1900 | +} | ||
1901 | + | ||
1902 | static inline | ||
1903 | void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) | ||
1904 | { | ||
1905 | diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c | ||
1906 | index 3b440b8d7c05..83c7009b0da1 100644 | ||
1907 | --- a/net/batman-adv/distributed-arp-table.c | ||
1908 | +++ b/net/batman-adv/distributed-arp-table.c | ||
1909 | @@ -1025,8 +1025,9 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | ||
1910 | skb_reset_mac_header(skb_new); | ||
1911 | skb_new->protocol = eth_type_trans(skb_new, | ||
1912 | bat_priv->soft_iface); | ||
1913 | - bat_priv->stats.rx_packets++; | ||
1914 | - bat_priv->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size; | ||
1915 | + batadv_inc_counter(bat_priv, BATADV_CNT_RX); | ||
1916 | + batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, | ||
1917 | + skb->len + ETH_HLEN + hdr_size); | ||
1918 | bat_priv->soft_iface->last_rx = jiffies; | ||
1919 | |||
1920 | netif_rx(skb_new); | ||
1921 | diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c | ||
1922 | index a06b6041f3e0..fef21f75892e 100644 | ||
1923 | --- a/net/batman-adv/fragmentation.c | ||
1924 | +++ b/net/batman-adv/fragmentation.c | ||
1925 | @@ -232,8 +232,10 @@ err_unlock: | ||
1926 | spin_unlock_bh(&chain->lock); | ||
1927 | |||
1928 | err: | ||
1929 | - if (!ret) | ||
1930 | + if (!ret) { | ||
1931 | kfree(frag_entry_new); | ||
1932 | + kfree_skb(skb); | ||
1933 | + } | ||
1934 | |||
1935 | return ret; | ||
1936 | } | ||
1937 | @@ -305,7 +307,7 @@ free: | ||
1938 | * | ||
1939 | * There are three possible outcomes: 1) Packet is merged: Return true and | ||
1940 | * set *skb to merged packet; 2) Packet is buffered: Return true and set *skb | ||
1941 | - * to NULL; 3) Error: Return false and leave skb as is. | ||
1942 | + * to NULL; 3) Error: Return false and free skb. | ||
1943 | * | ||
1944 | * Return: true when packet is merged or buffered, false when skb is not not | ||
1945 | * used. | ||
1946 | @@ -330,9 +332,9 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb, | ||
1947 | goto out_err; | ||
1948 | |||
1949 | out: | ||
1950 | - *skb = skb_out; | ||
1951 | ret = true; | ||
1952 | out_err: | ||
1953 | + *skb = skb_out; | ||
1954 | return ret; | ||
1955 | } | ||
1956 | |||
1957 | @@ -482,12 +484,20 @@ int batadv_frag_send_packet(struct sk_buff *skb, | ||
1958 | */ | ||
1959 | if (skb->priority >= 256 && skb->priority <= 263) | ||
1960 | frag_header.priority = skb->priority - 256; | ||
1961 | + else | ||
1962 | + frag_header.priority = 0; | ||
1963 | |||
1964 | ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); | ||
1965 | ether_addr_copy(frag_header.dest, orig_node->orig); | ||
1966 | |||
1967 | /* Eat and send fragments from the tail of skb */ | ||
1968 | while (skb->len > max_fragment_size) { | ||
1969 | + /* The initial check in this function should cover this case */ | ||
1970 | + if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) { | ||
1971 | + ret = -1; | ||
1972 | + goto out; | ||
1973 | + } | ||
1974 | + | ||
1975 | skb_fragment = batadv_frag_create(skb, &frag_header, mtu); | ||
1976 | if (!skb_fragment) | ||
1977 | goto out; | ||
1978 | @@ -505,12 +515,6 @@ int batadv_frag_send_packet(struct sk_buff *skb, | ||
1979 | } | ||
1980 | |||
1981 | frag_header.no++; | ||
1982 | - | ||
1983 | - /* The initial check in this function should cover this case */ | ||
1984 | - if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) { | ||
1985 | - ret = -1; | ||
1986 | - goto out; | ||
1987 | - } | ||
1988 | } | ||
1989 | |||
1990 | /* Make room for the fragment header. */ | ||
1991 | diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c | ||
1992 | index ed9aaf30fbcf..3bd7ed6b6b3e 100644 | ||
1993 | --- a/net/batman-adv/gateway_client.c | ||
1994 | +++ b/net/batman-adv/gateway_client.c | ||
1995 | @@ -31,6 +31,7 @@ | ||
1996 | #include <linux/kernel.h> | ||
1997 | #include <linux/kref.h> | ||
1998 | #include <linux/list.h> | ||
1999 | +#include <linux/lockdep.h> | ||
2000 | #include <linux/netdevice.h> | ||
2001 | #include <linux/netlink.h> | ||
2002 | #include <linux/rculist.h> | ||
2003 | @@ -325,6 +326,9 @@ out: | ||
2004 | * @bat_priv: the bat priv with all the soft interface information | ||
2005 | * @orig_node: originator announcing gateway capabilities | ||
2006 | * @gateway: announced bandwidth information | ||
2007 | + * | ||
2008 | + * Has to be called with the appropriate locks being acquired | ||
2009 | + * (gw.list_lock). | ||
2010 | */ | ||
2011 | static void batadv_gw_node_add(struct batadv_priv *bat_priv, | ||
2012 | struct batadv_orig_node *orig_node, | ||
2013 | @@ -332,6 +336,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, | ||
2014 | { | ||
2015 | struct batadv_gw_node *gw_node; | ||
2016 | |||
2017 | + lockdep_assert_held(&bat_priv->gw.list_lock); | ||
2018 | + | ||
2019 | if (gateway->bandwidth_down == 0) | ||
2020 | return; | ||
2021 | |||
2022 | @@ -346,10 +352,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, | ||
2023 | gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); | ||
2024 | gw_node->bandwidth_up = ntohl(gateway->bandwidth_up); | ||
2025 | |||
2026 | - spin_lock_bh(&bat_priv->gw.list_lock); | ||
2027 | kref_get(&gw_node->refcount); | ||
2028 | hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list); | ||
2029 | - spin_unlock_bh(&bat_priv->gw.list_lock); | ||
2030 | |||
2031 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
2032 | "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n", | ||
2033 | @@ -404,11 +408,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv, | ||
2034 | { | ||
2035 | struct batadv_gw_node *gw_node, *curr_gw = NULL; | ||
2036 | |||
2037 | + spin_lock_bh(&bat_priv->gw.list_lock); | ||
2038 | gw_node = batadv_gw_node_get(bat_priv, orig_node); | ||
2039 | if (!gw_node) { | ||
2040 | batadv_gw_node_add(bat_priv, orig_node, gateway); | ||
2041 | + spin_unlock_bh(&bat_priv->gw.list_lock); | ||
2042 | goto out; | ||
2043 | } | ||
2044 | + spin_unlock_bh(&bat_priv->gw.list_lock); | ||
2045 | |||
2046 | if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) && | ||
2047 | (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))) | ||
2048 | diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c | ||
2049 | index 21184810d89f..3e3f91ab694f 100644 | ||
2050 | --- a/net/batman-adv/gateway_common.c | ||
2051 | +++ b/net/batman-adv/gateway_common.c | ||
2052 | @@ -253,6 +253,11 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, | ||
2053 | */ | ||
2054 | void batadv_gw_init(struct batadv_priv *bat_priv) | ||
2055 | { | ||
2056 | + if (bat_priv->algo_ops->gw.init_sel_class) | ||
2057 | + bat_priv->algo_ops->gw.init_sel_class(bat_priv); | ||
2058 | + else | ||
2059 | + atomic_set(&bat_priv->gw.sel_class, 1); | ||
2060 | + | ||
2061 | batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, | ||
2062 | NULL, BATADV_TVLV_GW, 1, | ||
2063 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); | ||
2064 | diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c | ||
2065 | index 8f7883b7d717..f528761674df 100644 | ||
2066 | --- a/net/batman-adv/hard-interface.c | ||
2067 | +++ b/net/batman-adv/hard-interface.c | ||
2068 | @@ -28,6 +28,7 @@ | ||
2069 | #include <linux/kernel.h> | ||
2070 | #include <linux/kref.h> | ||
2071 | #include <linux/list.h> | ||
2072 | +#include <linux/mutex.h> | ||
2073 | #include <linux/netdevice.h> | ||
2074 | #include <linux/printk.h> | ||
2075 | #include <linux/rculist.h> | ||
2076 | @@ -539,6 +540,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | ||
2077 | hard_iface->soft_iface = soft_iface; | ||
2078 | bat_priv = netdev_priv(hard_iface->soft_iface); | ||
2079 | |||
2080 | + if (bat_priv->num_ifaces >= UINT_MAX) { | ||
2081 | + ret = -ENOSPC; | ||
2082 | + goto err_dev; | ||
2083 | + } | ||
2084 | + | ||
2085 | ret = netdev_master_upper_dev_link(hard_iface->net_dev, | ||
2086 | soft_iface, NULL, NULL); | ||
2087 | if (ret) | ||
2088 | @@ -591,6 +597,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | ||
2089 | |||
2090 | batadv_hardif_recalc_extra_skbroom(soft_iface); | ||
2091 | |||
2092 | + if (bat_priv->algo_ops->iface.enabled) | ||
2093 | + bat_priv->algo_ops->iface.enabled(hard_iface); | ||
2094 | + | ||
2095 | out: | ||
2096 | return 0; | ||
2097 | |||
2098 | @@ -646,7 +655,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, | ||
2099 | batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface); | ||
2100 | |||
2101 | /* nobody uses this interface anymore */ | ||
2102 | - if (!bat_priv->num_ifaces) { | ||
2103 | + if (bat_priv->num_ifaces == 0) { | ||
2104 | batadv_gw_check_client_stop(bat_priv); | ||
2105 | |||
2106 | if (autodel == BATADV_IF_CLEANUP_AUTO) | ||
2107 | @@ -682,7 +691,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) | ||
2108 | if (ret) | ||
2109 | goto free_if; | ||
2110 | |||
2111 | - hard_iface->if_num = -1; | ||
2112 | + hard_iface->if_num = 0; | ||
2113 | hard_iface->net_dev = net_dev; | ||
2114 | hard_iface->soft_iface = NULL; | ||
2115 | hard_iface->if_status = BATADV_IF_NOT_IN_USE; | ||
2116 | @@ -694,6 +703,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) | ||
2117 | INIT_LIST_HEAD(&hard_iface->list); | ||
2118 | INIT_HLIST_HEAD(&hard_iface->neigh_list); | ||
2119 | |||
2120 | + mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); | ||
2121 | spin_lock_init(&hard_iface->neigh_list_lock); | ||
2122 | kref_init(&hard_iface->refcount); | ||
2123 | |||
2124 | @@ -750,6 +760,32 @@ void batadv_hardif_remove_interfaces(void) | ||
2125 | rtnl_unlock(); | ||
2126 | } | ||
2127 | |||
2128 | +/** | ||
2129 | + * batadv_hard_if_event_softif() - Handle events for soft interfaces | ||
2130 | + * @event: NETDEV_* event to handle | ||
2131 | + * @net_dev: net_device which generated an event | ||
2132 | + * | ||
2133 | + * Return: NOTIFY_* result | ||
2134 | + */ | ||
2135 | +static int batadv_hard_if_event_softif(unsigned long event, | ||
2136 | + struct net_device *net_dev) | ||
2137 | +{ | ||
2138 | + struct batadv_priv *bat_priv; | ||
2139 | + | ||
2140 | + switch (event) { | ||
2141 | + case NETDEV_REGISTER: | ||
2142 | + batadv_sysfs_add_meshif(net_dev); | ||
2143 | + bat_priv = netdev_priv(net_dev); | ||
2144 | + batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); | ||
2145 | + break; | ||
2146 | + case NETDEV_CHANGENAME: | ||
2147 | + batadv_debugfs_rename_meshif(net_dev); | ||
2148 | + break; | ||
2149 | + } | ||
2150 | + | ||
2151 | + return NOTIFY_DONE; | ||
2152 | +} | ||
2153 | + | ||
2154 | static int batadv_hard_if_event(struct notifier_block *this, | ||
2155 | unsigned long event, void *ptr) | ||
2156 | { | ||
2157 | @@ -758,12 +794,8 @@ static int batadv_hard_if_event(struct notifier_block *this, | ||
2158 | struct batadv_hard_iface *primary_if = NULL; | ||
2159 | struct batadv_priv *bat_priv; | ||
2160 | |||
2161 | - if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { | ||
2162 | - batadv_sysfs_add_meshif(net_dev); | ||
2163 | - bat_priv = netdev_priv(net_dev); | ||
2164 | - batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); | ||
2165 | - return NOTIFY_DONE; | ||
2166 | - } | ||
2167 | + if (batadv_softif_is_valid(net_dev)) | ||
2168 | + return batadv_hard_if_event_softif(event, net_dev); | ||
2169 | |||
2170 | hard_iface = batadv_hardif_get_by_netdev(net_dev); | ||
2171 | if (!hard_iface && (event == NETDEV_REGISTER || | ||
2172 | @@ -807,6 +839,9 @@ static int batadv_hard_if_event(struct notifier_block *this, | ||
2173 | if (hard_iface == primary_if) | ||
2174 | batadv_primary_if_update_addr(bat_priv, NULL); | ||
2175 | break; | ||
2176 | + case NETDEV_CHANGENAME: | ||
2177 | + batadv_debugfs_rename_hardif(hard_iface); | ||
2178 | + break; | ||
2179 | default: | ||
2180 | break; | ||
2181 | } | ||
2182 | diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c | ||
2183 | index 7c8d16086f0f..8466f83fc32f 100644 | ||
2184 | --- a/net/batman-adv/originator.c | ||
2185 | +++ b/net/batman-adv/originator.c | ||
2186 | @@ -1495,7 +1495,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb) | ||
2187 | } | ||
2188 | |||
2189 | int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, | ||
2190 | - int max_if_num) | ||
2191 | + unsigned int max_if_num) | ||
2192 | { | ||
2193 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | ||
2194 | struct batadv_algo_ops *bao = bat_priv->algo_ops; | ||
2195 | @@ -1530,7 +1530,7 @@ err: | ||
2196 | } | ||
2197 | |||
2198 | int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, | ||
2199 | - int max_if_num) | ||
2200 | + unsigned int max_if_num) | ||
2201 | { | ||
2202 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | ||
2203 | struct batadv_hashtable *hash = bat_priv->orig_hash; | ||
2204 | diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h | ||
2205 | index ebc56183f358..fab0b2cc141d 100644 | ||
2206 | --- a/net/batman-adv/originator.h | ||
2207 | +++ b/net/batman-adv/originator.h | ||
2208 | @@ -78,9 +78,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset); | ||
2209 | int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb); | ||
2210 | int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset); | ||
2211 | int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, | ||
2212 | - int max_if_num); | ||
2213 | + unsigned int max_if_num); | ||
2214 | int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, | ||
2215 | - int max_if_num); | ||
2216 | + unsigned int max_if_num); | ||
2217 | struct batadv_orig_node_vlan * | ||
2218 | batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node, | ||
2219 | unsigned short vid); | ||
2220 | diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c | ||
2221 | index 8b98609ebc1e..19059ae26e51 100644 | ||
2222 | --- a/net/batman-adv/routing.c | ||
2223 | +++ b/net/batman-adv/routing.c | ||
2224 | @@ -930,7 +930,6 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | ||
2225 | bool is4addr; | ||
2226 | |||
2227 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
2228 | - unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | ||
2229 | |||
2230 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; | ||
2231 | /* the caller function should have already pulled 2 bytes */ | ||
2232 | @@ -951,9 +950,13 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | ||
2233 | if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) | ||
2234 | return NET_RX_DROP; | ||
2235 | |||
2236 | + unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
2237 | + | ||
2238 | /* packet for me */ | ||
2239 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { | ||
2240 | if (is4addr) { | ||
2241 | + unicast_4addr_packet = | ||
2242 | + (struct batadv_unicast_4addr_packet *)skb->data; | ||
2243 | subtype = unicast_4addr_packet->subtype; | ||
2244 | batadv_dat_inc_counter(bat_priv, subtype); | ||
2245 | |||
2246 | @@ -1080,6 +1083,12 @@ int batadv_recv_frag_packet(struct sk_buff *skb, | ||
2247 | batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX); | ||
2248 | batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len); | ||
2249 | |||
2250 | + /* batadv_frag_skb_buffer will always consume the skb and | ||
2251 | + * the caller should therefore never try to free the | ||
2252 | + * skb after this point | ||
2253 | + */ | ||
2254 | + ret = NET_RX_SUCCESS; | ||
2255 | + | ||
2256 | /* Add fragment to buffer and merge if possible. */ | ||
2257 | if (!batadv_frag_skb_buffer(&skb, orig_node_src)) | ||
2258 | goto out; | ||
2259 | diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c | ||
2260 | index a92512a46e91..99d2c453c872 100644 | ||
2261 | --- a/net/batman-adv/soft-interface.c | ||
2262 | +++ b/net/batman-adv/soft-interface.c | ||
2263 | @@ -808,7 +808,6 @@ static int batadv_softif_init_late(struct net_device *dev) | ||
2264 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); | ||
2265 | #endif | ||
2266 | atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); | ||
2267 | - atomic_set(&bat_priv->gw.sel_class, 20); | ||
2268 | atomic_set(&bat_priv->gw.bandwidth_down, 100); | ||
2269 | atomic_set(&bat_priv->gw.bandwidth_up, 20); | ||
2270 | atomic_set(&bat_priv->orig_interval, 1000); | ||
2271 | diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c | ||
2272 | index 1fab9bcf535d..d40d83949b00 100644 | ||
2273 | --- a/net/batman-adv/translation-table.c | ||
2274 | +++ b/net/batman-adv/translation-table.c | ||
2275 | @@ -867,7 +867,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, | ||
2276 | struct batadv_orig_node_vlan *vlan; | ||
2277 | u8 *tt_change_ptr; | ||
2278 | |||
2279 | - rcu_read_lock(); | ||
2280 | + spin_lock_bh(&orig_node->vlan_list_lock); | ||
2281 | hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { | ||
2282 | num_vlan++; | ||
2283 | num_entries += atomic_read(&vlan->tt.num_entries); | ||
2284 | @@ -905,7 +905,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, | ||
2285 | *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; | ||
2286 | |||
2287 | out: | ||
2288 | - rcu_read_unlock(); | ||
2289 | + spin_unlock_bh(&orig_node->vlan_list_lock); | ||
2290 | return tvlv_len; | ||
2291 | } | ||
2292 | |||
2293 | @@ -936,15 +936,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, | ||
2294 | struct batadv_tvlv_tt_vlan_data *tt_vlan; | ||
2295 | struct batadv_softif_vlan *vlan; | ||
2296 | u16 num_vlan = 0; | ||
2297 | - u16 num_entries = 0; | ||
2298 | + u16 vlan_entries = 0; | ||
2299 | + u16 total_entries = 0; | ||
2300 | u16 tvlv_len; | ||
2301 | u8 *tt_change_ptr; | ||
2302 | int change_offset; | ||
2303 | |||
2304 | - rcu_read_lock(); | ||
2305 | + spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
2306 | hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { | ||
2307 | + vlan_entries = atomic_read(&vlan->tt.num_entries); | ||
2308 | + if (vlan_entries < 1) | ||
2309 | + continue; | ||
2310 | + | ||
2311 | num_vlan++; | ||
2312 | - num_entries += atomic_read(&vlan->tt.num_entries); | ||
2313 | + total_entries += vlan_entries; | ||
2314 | } | ||
2315 | |||
2316 | change_offset = sizeof(**tt_data); | ||
2317 | @@ -952,7 +957,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, | ||
2318 | |||
2319 | /* if tt_len is negative, allocate the space needed by the full table */ | ||
2320 | if (*tt_len < 0) | ||
2321 | - *tt_len = batadv_tt_len(num_entries); | ||
2322 | + *tt_len = batadv_tt_len(total_entries); | ||
2323 | |||
2324 | tvlv_len = *tt_len; | ||
2325 | tvlv_len += change_offset; | ||
2326 | @@ -969,6 +974,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, | ||
2327 | |||
2328 | tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1); | ||
2329 | hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { | ||
2330 | + vlan_entries = atomic_read(&vlan->tt.num_entries); | ||
2331 | + if (vlan_entries < 1) | ||
2332 | + continue; | ||
2333 | + | ||
2334 | tt_vlan->vid = htons(vlan->vid); | ||
2335 | tt_vlan->crc = htonl(vlan->tt.crc); | ||
2336 | |||
2337 | @@ -979,7 +988,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, | ||
2338 | *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; | ||
2339 | |||
2340 | out: | ||
2341 | - rcu_read_unlock(); | ||
2342 | + spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
2343 | return tvlv_len; | ||
2344 | } | ||
2345 | |||
2346 | @@ -1539,6 +1548,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, | ||
2347 | * by a given originator | ||
2348 | * @entry: the TT global entry to check | ||
2349 | * @orig_node: the originator to search in the list | ||
2350 | + * @flags: a pointer to store TT flags for the given @entry received | ||
2351 | + * from @orig_node | ||
2352 | * | ||
2353 | * find out if an orig_node is already in the list of a tt_global_entry. | ||
2354 | * | ||
2355 | @@ -1546,7 +1557,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, | ||
2356 | */ | ||
2357 | static bool | ||
2358 | batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, | ||
2359 | - const struct batadv_orig_node *orig_node) | ||
2360 | + const struct batadv_orig_node *orig_node, | ||
2361 | + u8 *flags) | ||
2362 | { | ||
2363 | struct batadv_tt_orig_list_entry *orig_entry; | ||
2364 | bool found = false; | ||
2365 | @@ -1554,15 +1566,51 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, | ||
2366 | orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); | ||
2367 | if (orig_entry) { | ||
2368 | found = true; | ||
2369 | + | ||
2370 | + if (flags) | ||
2371 | + *flags = orig_entry->flags; | ||
2372 | + | ||
2373 | batadv_tt_orig_list_entry_put(orig_entry); | ||
2374 | } | ||
2375 | |||
2376 | return found; | ||
2377 | } | ||
2378 | |||
2379 | +/** | ||
2380 | + * batadv_tt_global_sync_flags - update TT sync flags | ||
2381 | + * @tt_global: the TT global entry to update sync flags in | ||
2382 | + * | ||
2383 | + * Updates the sync flag bits in the tt_global flag attribute with a logical | ||
2384 | + * OR of all sync flags from any of its TT orig entries. | ||
2385 | + */ | ||
2386 | +static void | ||
2387 | +batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global) | ||
2388 | +{ | ||
2389 | + struct batadv_tt_orig_list_entry *orig_entry; | ||
2390 | + const struct hlist_head *head; | ||
2391 | + u16 flags = BATADV_NO_FLAGS; | ||
2392 | + | ||
2393 | + rcu_read_lock(); | ||
2394 | + head = &tt_global->orig_list; | ||
2395 | + hlist_for_each_entry_rcu(orig_entry, head, list) | ||
2396 | + flags |= orig_entry->flags; | ||
2397 | + rcu_read_unlock(); | ||
2398 | + | ||
2399 | + flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); | ||
2400 | + tt_global->common.flags = flags; | ||
2401 | +} | ||
2402 | + | ||
2403 | +/** | ||
2404 | + * batadv_tt_global_orig_entry_add - add or update a TT orig entry | ||
2405 | + * @tt_global: the TT global entry to add an orig entry in | ||
2406 | + * @orig_node: the originator to add an orig entry for | ||
2407 | + * @ttvn: translation table version number of this changeset | ||
2408 | + * @flags: TT sync flags | ||
2409 | + */ | ||
2410 | static void | ||
2411 | batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, | ||
2412 | - struct batadv_orig_node *orig_node, int ttvn) | ||
2413 | + struct batadv_orig_node *orig_node, int ttvn, | ||
2414 | + u8 flags) | ||
2415 | { | ||
2416 | struct batadv_tt_orig_list_entry *orig_entry; | ||
2417 | |||
2418 | @@ -1574,7 +1622,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, | ||
2419 | * was added during a "temporary client detection" | ||
2420 | */ | ||
2421 | orig_entry->ttvn = ttvn; | ||
2422 | - goto out; | ||
2423 | + orig_entry->flags = flags; | ||
2424 | + goto sync_flags; | ||
2425 | } | ||
2426 | |||
2427 | orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC); | ||
2428 | @@ -1586,6 +1635,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, | ||
2429 | batadv_tt_global_size_inc(orig_node, tt_global->common.vid); | ||
2430 | orig_entry->orig_node = orig_node; | ||
2431 | orig_entry->ttvn = ttvn; | ||
2432 | + orig_entry->flags = flags; | ||
2433 | kref_init(&orig_entry->refcount); | ||
2434 | |||
2435 | kref_get(&orig_entry->refcount); | ||
2436 | @@ -1593,6 +1643,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, | ||
2437 | &tt_global->orig_list); | ||
2438 | atomic_inc(&tt_global->orig_list_count); | ||
2439 | |||
2440 | +sync_flags: | ||
2441 | + batadv_tt_global_sync_flags(tt_global); | ||
2442 | out: | ||
2443 | if (orig_entry) | ||
2444 | batadv_tt_orig_list_entry_put(orig_entry); | ||
2445 | @@ -1656,7 +1708,9 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, | ||
2446 | ether_addr_copy(common->addr, tt_addr); | ||
2447 | common->vid = vid; | ||
2448 | |||
2449 | - common->flags = flags; | ||
2450 | + if (!is_multicast_ether_addr(common->addr)) | ||
2451 | + common->flags = flags & (~BATADV_TT_SYNC_MASK); | ||
2452 | + | ||
2453 | tt_global_entry->roam_at = 0; | ||
2454 | /* node must store current time in case of roaming. This is | ||
2455 | * needed to purge this entry out on timeout (if nobody claims | ||
2456 | @@ -1698,7 +1752,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, | ||
2457 | if (!(common->flags & BATADV_TT_CLIENT_TEMP)) | ||
2458 | goto out; | ||
2459 | if (batadv_tt_global_entry_has_orig(tt_global_entry, | ||
2460 | - orig_node)) | ||
2461 | + orig_node, NULL)) | ||
2462 | goto out_remove; | ||
2463 | batadv_tt_global_del_orig_list(tt_global_entry); | ||
2464 | goto add_orig_entry; | ||
2465 | @@ -1716,10 +1770,11 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, | ||
2466 | } | ||
2467 | |||
2468 | /* the change can carry possible "attribute" flags like the | ||
2469 | - * TT_CLIENT_WIFI, therefore they have to be copied in the | ||
2470 | + * TT_CLIENT_TEMP, therefore they have to be copied in the | ||
2471 | * client entry | ||
2472 | */ | ||
2473 | - common->flags |= flags; | ||
2474 | + if (!is_multicast_ether_addr(common->addr)) | ||
2475 | + common->flags |= flags & (~BATADV_TT_SYNC_MASK); | ||
2476 | |||
2477 | /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only | ||
2478 | * one originator left in the list and we previously received a | ||
2479 | @@ -1736,7 +1791,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, | ||
2480 | } | ||
2481 | add_orig_entry: | ||
2482 | /* add the new orig_entry (if needed) or update it */ | ||
2483 | - batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); | ||
2484 | + batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn, | ||
2485 | + flags & BATADV_TT_SYNC_MASK); | ||
2486 | |||
2487 | batadv_dbg(BATADV_DBG_TT, bat_priv, | ||
2488 | "Creating new global tt entry: %pM (vid: %d, via %pM)\n", | ||
2489 | @@ -1959,6 +2015,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, | ||
2490 | struct batadv_tt_orig_list_entry *orig, | ||
2491 | bool best) | ||
2492 | { | ||
2493 | + u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; | ||
2494 | void *hdr; | ||
2495 | struct batadv_orig_node_vlan *vlan; | ||
2496 | u8 last_ttvn; | ||
2497 | @@ -1988,7 +2045,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, | ||
2498 | nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) || | ||
2499 | nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) || | ||
2500 | nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || | ||
2501 | - nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) | ||
2502 | + nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags)) | ||
2503 | goto nla_put_failure; | ||
2504 | |||
2505 | if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) | ||
2506 | @@ -2602,6 +2659,7 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, | ||
2507 | unsigned short vid) | ||
2508 | { | ||
2509 | struct batadv_hashtable *hash = bat_priv->tt.global_hash; | ||
2510 | + struct batadv_tt_orig_list_entry *tt_orig; | ||
2511 | struct batadv_tt_common_entry *tt_common; | ||
2512 | struct batadv_tt_global_entry *tt_global; | ||
2513 | struct hlist_head *head; | ||
2514 | @@ -2640,8 +2698,9 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, | ||
2515 | /* find out if this global entry is announced by this | ||
2516 | * originator | ||
2517 | */ | ||
2518 | - if (!batadv_tt_global_entry_has_orig(tt_global, | ||
2519 | - orig_node)) | ||
2520 | + tt_orig = batadv_tt_global_orig_entry_find(tt_global, | ||
2521 | + orig_node); | ||
2522 | + if (!tt_orig) | ||
2523 | continue; | ||
2524 | |||
2525 | /* use network order to read the VID: this ensures that | ||
2526 | @@ -2653,10 +2712,12 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, | ||
2527 | /* compute the CRC on flags that have to be kept in sync | ||
2528 | * among nodes | ||
2529 | */ | ||
2530 | - flags = tt_common->flags & BATADV_TT_SYNC_MASK; | ||
2531 | + flags = tt_orig->flags; | ||
2532 | crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags)); | ||
2533 | |||
2534 | crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); | ||
2535 | + | ||
2536 | + batadv_tt_orig_list_entry_put(tt_orig); | ||
2537 | } | ||
2538 | rcu_read_unlock(); | ||
2539 | } | ||
2540 | @@ -2834,23 +2895,46 @@ unlock: | ||
2541 | } | ||
2542 | |||
2543 | /** | ||
2544 | - * batadv_tt_local_valid - verify that given tt entry is a valid one | ||
2545 | + * batadv_tt_local_valid() - verify local tt entry and get flags | ||
2546 | * @entry_ptr: to be checked local tt entry | ||
2547 | * @data_ptr: not used but definition required to satisfy the callback prototype | ||
2548 | + * @flags: a pointer to store TT flags for this client to | ||
2549 | + * | ||
2550 | + * Checks the validity of the given local TT entry. If it is, then the provided | ||
2551 | + * flags pointer is updated. | ||
2552 | * | ||
2553 | * Return: true if the entry is a valid, false otherwise. | ||
2554 | */ | ||
2555 | -static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) | ||
2556 | +static bool batadv_tt_local_valid(const void *entry_ptr, | ||
2557 | + const void *data_ptr, | ||
2558 | + u8 *flags) | ||
2559 | { | ||
2560 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; | ||
2561 | |||
2562 | if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) | ||
2563 | return false; | ||
2564 | + | ||
2565 | + if (flags) | ||
2566 | + *flags = tt_common_entry->flags; | ||
2567 | + | ||
2568 | return true; | ||
2569 | } | ||
2570 | |||
2571 | +/** | ||
2572 | + * batadv_tt_global_valid() - verify global tt entry and get flags | ||
2573 | + * @entry_ptr: to be checked global tt entry | ||
2574 | + * @data_ptr: an orig_node object (may be NULL) | ||
2575 | + * @flags: a pointer to store TT flags for this client to | ||
2576 | + * | ||
2577 | + * Checks the validity of the given global TT entry. If it is, then the provided | ||
2578 | + * flags pointer is updated either with the common (summed) TT flags if data_ptr | ||
2579 | + * is NULL or the specific, per originator TT flags otherwise. | ||
2580 | + * | ||
2581 | + * Return: true if the entry is a valid, false otherwise. | ||
2582 | + */ | ||
2583 | static bool batadv_tt_global_valid(const void *entry_ptr, | ||
2584 | - const void *data_ptr) | ||
2585 | + const void *data_ptr, | ||
2586 | + u8 *flags) | ||
2587 | { | ||
2588 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; | ||
2589 | const struct batadv_tt_global_entry *tt_global_entry; | ||
2590 | @@ -2864,7 +2948,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr, | ||
2591 | struct batadv_tt_global_entry, | ||
2592 | common); | ||
2593 | |||
2594 | - return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); | ||
2595 | + return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node, | ||
2596 | + flags); | ||
2597 | } | ||
2598 | |||
2599 | /** | ||
2600 | @@ -2874,25 +2959,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr, | ||
2601 | * @hash: hash table containing the tt entries | ||
2602 | * @tt_len: expected tvlv tt data buffer length in number of bytes | ||
2603 | * @tvlv_buff: pointer to the buffer to fill with the TT data | ||
2604 | - * @valid_cb: function to filter tt change entries | ||
2605 | + * @valid_cb: function to filter tt change entries and to return TT flags | ||
2606 | * @cb_data: data passed to the filter function as argument | ||
2607 | + * | ||
2608 | + * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb | ||
2609 | + * is not provided then this becomes a no-op. | ||
2610 | */ | ||
2611 | static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, | ||
2612 | struct batadv_hashtable *hash, | ||
2613 | void *tvlv_buff, u16 tt_len, | ||
2614 | bool (*valid_cb)(const void *, | ||
2615 | - const void *), | ||
2616 | + const void *, | ||
2617 | + u8 *flags), | ||
2618 | void *cb_data) | ||
2619 | { | ||
2620 | struct batadv_tt_common_entry *tt_common_entry; | ||
2621 | struct batadv_tvlv_tt_change *tt_change; | ||
2622 | struct hlist_head *head; | ||
2623 | u16 tt_tot, tt_num_entries = 0; | ||
2624 | + u8 flags; | ||
2625 | + bool ret; | ||
2626 | u32 i; | ||
2627 | |||
2628 | tt_tot = batadv_tt_entries(tt_len); | ||
2629 | tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff; | ||
2630 | |||
2631 | + if (!valid_cb) | ||
2632 | + return; | ||
2633 | + | ||
2634 | rcu_read_lock(); | ||
2635 | for (i = 0; i < hash->size; i++) { | ||
2636 | head = &hash->table[i]; | ||
2637 | @@ -2902,11 +2996,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, | ||
2638 | if (tt_tot == tt_num_entries) | ||
2639 | break; | ||
2640 | |||
2641 | - if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) | ||
2642 | + ret = valid_cb(tt_common_entry, cb_data, &flags); | ||
2643 | + if (!ret) | ||
2644 | continue; | ||
2645 | |||
2646 | ether_addr_copy(tt_change->addr, tt_common_entry->addr); | ||
2647 | - tt_change->flags = tt_common_entry->flags; | ||
2648 | + tt_change->flags = flags; | ||
2649 | tt_change->vid = htons(tt_common_entry->vid); | ||
2650 | memset(tt_change->reserved, 0, | ||
2651 | sizeof(tt_change->reserved)); | ||
2652 | diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h | ||
2653 | index b3dd1a381aad..c17b74e51fe9 100644 | ||
2654 | --- a/net/batman-adv/types.h | ||
2655 | +++ b/net/batman-adv/types.h | ||
2656 | @@ -27,6 +27,7 @@ | ||
2657 | #include <linux/compiler.h> | ||
2658 | #include <linux/if_ether.h> | ||
2659 | #include <linux/kref.h> | ||
2660 | +#include <linux/mutex.h> | ||
2661 | #include <linux/netdevice.h> | ||
2662 | #include <linux/netlink.h> | ||
2663 | #include <linux/sched.h> /* for linux/wait.h */ | ||
2664 | @@ -81,11 +82,13 @@ enum batadv_dhcp_recipient { | ||
2665 | * @ogm_buff: buffer holding the OGM packet | ||
2666 | * @ogm_buff_len: length of the OGM packet buffer | ||
2667 | * @ogm_seqno: OGM sequence number - used to identify each OGM | ||
2668 | + * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len | ||
2669 | */ | ||
2670 | struct batadv_hard_iface_bat_iv { | ||
2671 | unsigned char *ogm_buff; | ||
2672 | int ogm_buff_len; | ||
2673 | atomic_t ogm_seqno; | ||
2674 | + struct mutex ogm_buff_mutex; | ||
2675 | }; | ||
2676 | |||
2677 | /** | ||
2678 | @@ -139,7 +142,7 @@ struct batadv_hard_iface_bat_v { | ||
2679 | */ | ||
2680 | struct batadv_hard_iface { | ||
2681 | struct list_head list; | ||
2682 | - s16 if_num; | ||
2683 | + unsigned int if_num; | ||
2684 | char if_status; | ||
2685 | struct net_device *net_dev; | ||
2686 | u8 num_bcasts; | ||
2687 | @@ -966,12 +969,14 @@ struct batadv_softif_vlan { | ||
2688 | * @ogm_buff: buffer holding the OGM packet | ||
2689 | * @ogm_buff_len: length of the OGM packet buffer | ||
2690 | * @ogm_seqno: OGM sequence number - used to identify each OGM | ||
2691 | + * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len | ||
2692 | * @ogm_wq: workqueue used to schedule OGM transmissions | ||
2693 | */ | ||
2694 | struct batadv_priv_bat_v { | ||
2695 | unsigned char *ogm_buff; | ||
2696 | int ogm_buff_len; | ||
2697 | atomic_t ogm_seqno; | ||
2698 | + struct mutex ogm_buff_mutex; | ||
2699 | struct delayed_work ogm_wq; | ||
2700 | }; | ||
2701 | |||
2702 | @@ -1060,7 +1065,7 @@ struct batadv_priv { | ||
2703 | atomic_t bcast_seqno; | ||
2704 | atomic_t bcast_queue_left; | ||
2705 | atomic_t batman_queue_left; | ||
2706 | - char num_ifaces; | ||
2707 | + unsigned int num_ifaces; | ||
2708 | struct kobject *mesh_obj; | ||
2709 | struct dentry *debug_dir; | ||
2710 | struct hlist_head forw_bat_list; | ||
2711 | @@ -1241,6 +1246,7 @@ struct batadv_tt_global_entry { | ||
2712 | * struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client | ||
2713 | * @orig_node: pointer to orig node announcing this non-mesh client | ||
2714 | * @ttvn: translation table version number which added the non-mesh client | ||
2715 | + * @flags: per orig entry TT sync flags | ||
2716 | * @list: list node for batadv_tt_global_entry::orig_list | ||
2717 | * @refcount: number of contexts the object is used | ||
2718 | * @rcu: struct used for freeing in an RCU-safe manner | ||
2719 | @@ -1248,6 +1254,7 @@ struct batadv_tt_global_entry { | ||
2720 | struct batadv_tt_orig_list_entry { | ||
2721 | struct batadv_orig_node *orig_node; | ||
2722 | u8 ttvn; | ||
2723 | + u8 flags; | ||
2724 | struct hlist_node list; | ||
2725 | struct kref refcount; | ||
2726 | struct rcu_head rcu; | ||
2727 | @@ -1397,6 +1404,7 @@ struct batadv_forw_packet { | ||
2728 | * @activate: start routing mechanisms when hard-interface is brought up | ||
2729 | * (optional) | ||
2730 | * @enable: init routing info when hard-interface is enabled | ||
2731 | + * @enabled: notification when hard-interface was enabled (optional) | ||
2732 | * @disable: de-init routing info when hard-interface is disabled | ||
2733 | * @update_mac: (re-)init mac addresses of the protocol information | ||
2734 | * belonging to this hard-interface | ||
2735 | @@ -1405,6 +1413,7 @@ struct batadv_forw_packet { | ||
2736 | struct batadv_algo_iface_ops { | ||
2737 | void (*activate)(struct batadv_hard_iface *hard_iface); | ||
2738 | int (*enable)(struct batadv_hard_iface *hard_iface); | ||
2739 | + void (*enabled)(struct batadv_hard_iface *hard_iface); | ||
2740 | void (*disable)(struct batadv_hard_iface *hard_iface); | ||
2741 | void (*update_mac)(struct batadv_hard_iface *hard_iface); | ||
2742 | void (*primary_set)(struct batadv_hard_iface *hard_iface); | ||
2743 | @@ -1452,9 +1461,10 @@ struct batadv_algo_neigh_ops { | ||
2744 | */ | ||
2745 | struct batadv_algo_orig_ops { | ||
2746 | void (*free)(struct batadv_orig_node *orig_node); | ||
2747 | - int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num); | ||
2748 | - int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num, | ||
2749 | - int del_if_num); | ||
2750 | + int (*add_if)(struct batadv_orig_node *orig_node, | ||
2751 | + unsigned int max_if_num); | ||
2752 | + int (*del_if)(struct batadv_orig_node *orig_node, | ||
2753 | + unsigned int max_if_num, unsigned int del_if_num); | ||
2754 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS | ||
2755 | void (*print)(struct batadv_priv *priv, struct seq_file *seq, | ||
2756 | struct batadv_hard_iface *hard_iface); | ||
2757 | @@ -1466,6 +1476,7 @@ struct batadv_algo_orig_ops { | ||
2758 | |||
2759 | /** | ||
2760 | * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific) | ||
2761 | + * @init_sel_class: initialize GW selection class (optional) | ||
2762 | * @store_sel_class: parse and stores a new GW selection class (optional) | ||
2763 | * @show_sel_class: prints the current GW selection class (optional) | ||
2764 | * @get_best_gw_node: select the best GW from the list of available nodes | ||
2765 | @@ -1476,6 +1487,7 @@ struct batadv_algo_orig_ops { | ||
2766 | * @dump: dump gateways to a netlink socket (optional) | ||
2767 | */ | ||
2768 | struct batadv_algo_gw_ops { | ||
2769 | + void (*init_sel_class)(struct batadv_priv *bat_priv); | ||
2770 | ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff, | ||
2771 | size_t count); | ||
2772 | ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff); | ||
2773 | diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c | ||
2774 | index 2e4eef71471d..db65b0cdfc4c 100644 | ||
2775 | --- a/net/core/netclassid_cgroup.c | ||
2776 | +++ b/net/core/netclassid_cgroup.c | ||
2777 | @@ -55,30 +55,60 @@ static void cgrp_css_free(struct cgroup_subsys_state *css) | ||
2778 | kfree(css_cls_state(css)); | ||
2779 | } | ||
2780 | |||
2781 | +/* | ||
2782 | + * To avoid freezing of sockets creation for tasks with big number of threads | ||
2783 | + * and opened sockets lets release file_lock every 1000 iterated descriptors. | ||
2784 | + * New sockets will already have been created with new classid. | ||
2785 | + */ | ||
2786 | + | ||
2787 | +struct update_classid_context { | ||
2788 | + u32 classid; | ||
2789 | + unsigned int batch; | ||
2790 | +}; | ||
2791 | + | ||
2792 | +#define UPDATE_CLASSID_BATCH 1000 | ||
2793 | + | ||
2794 | static int update_classid_sock(const void *v, struct file *file, unsigned n) | ||
2795 | { | ||
2796 | int err; | ||
2797 | + struct update_classid_context *ctx = (void *)v; | ||
2798 | struct socket *sock = sock_from_file(file, &err); | ||
2799 | |||
2800 | if (sock) { | ||
2801 | spin_lock(&cgroup_sk_update_lock); | ||
2802 | - sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, | ||
2803 | - (unsigned long)v); | ||
2804 | + sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid); | ||
2805 | spin_unlock(&cgroup_sk_update_lock); | ||
2806 | } | ||
2807 | + if (--ctx->batch == 0) { | ||
2808 | + ctx->batch = UPDATE_CLASSID_BATCH; | ||
2809 | + return n + 1; | ||
2810 | + } | ||
2811 | return 0; | ||
2812 | } | ||
2813 | |||
2814 | +static void update_classid_task(struct task_struct *p, u32 classid) | ||
2815 | +{ | ||
2816 | + struct update_classid_context ctx = { | ||
2817 | + .classid = classid, | ||
2818 | + .batch = UPDATE_CLASSID_BATCH | ||
2819 | + }; | ||
2820 | + unsigned int fd = 0; | ||
2821 | + | ||
2822 | + do { | ||
2823 | + task_lock(p); | ||
2824 | + fd = iterate_fd(p->files, fd, update_classid_sock, &ctx); | ||
2825 | + task_unlock(p); | ||
2826 | + cond_resched(); | ||
2827 | + } while (fd); | ||
2828 | +} | ||
2829 | + | ||
2830 | static void cgrp_attach(struct cgroup_taskset *tset) | ||
2831 | { | ||
2832 | struct cgroup_subsys_state *css; | ||
2833 | struct task_struct *p; | ||
2834 | |||
2835 | cgroup_taskset_for_each(p, css, tset) { | ||
2836 | - task_lock(p); | ||
2837 | - iterate_fd(p->files, 0, update_classid_sock, | ||
2838 | - (void *)(unsigned long)css_cls_state(css)->classid); | ||
2839 | - task_unlock(p); | ||
2840 | + update_classid_task(p, css_cls_state(css)->classid); | ||
2841 | } | ||
2842 | } | ||
2843 | |||
2844 | @@ -100,10 +130,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, | ||
2845 | |||
2846 | css_task_iter_start(css, &it); | ||
2847 | while ((p = css_task_iter_next(&it))) { | ||
2848 | - task_lock(p); | ||
2849 | - iterate_fd(p->files, 0, update_classid_sock, | ||
2850 | - (void *)(unsigned long)cs->classid); | ||
2851 | - task_unlock(p); | ||
2852 | + update_classid_task(p, cs->classid); | ||
2853 | cond_resched(); | ||
2854 | } | ||
2855 | css_task_iter_end(&it); | ||
2856 | diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c | ||
2857 | index 35c432668454..040983fc15da 100644 | ||
2858 | --- a/net/ieee802154/nl_policy.c | ||
2859 | +++ b/net/ieee802154/nl_policy.c | ||
2860 | @@ -30,7 +30,13 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { | ||
2861 | [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
2862 | [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, | ||
2863 | [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, | ||
2864 | + [IEEE802154_ATTR_BCN_ORD] = { .type = NLA_U8, }, | ||
2865 | + [IEEE802154_ATTR_SF_ORD] = { .type = NLA_U8, }, | ||
2866 | + [IEEE802154_ATTR_PAN_COORD] = { .type = NLA_U8, }, | ||
2867 | + [IEEE802154_ATTR_BAT_EXT] = { .type = NLA_U8, }, | ||
2868 | + [IEEE802154_ATTR_COORD_REALIGN] = { .type = NLA_U8, }, | ||
2869 | [IEEE802154_ATTR_PAGE] = { .type = NLA_U8, }, | ||
2870 | + [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, }, | ||
2871 | [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, | ||
2872 | [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
2873 | [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, | ||
2874 | diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c | ||
2875 | index 71bcab94c5c7..0a6f72763beb 100644 | ||
2876 | --- a/net/ipv4/cipso_ipv4.c | ||
2877 | +++ b/net/ipv4/cipso_ipv4.c | ||
2878 | @@ -1738,6 +1738,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) | ||
2879 | { | ||
2880 | unsigned char optbuf[sizeof(struct ip_options) + 40]; | ||
2881 | struct ip_options *opt = (struct ip_options *)optbuf; | ||
2882 | + int res; | ||
2883 | |||
2884 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) | ||
2885 | return; | ||
2886 | @@ -1749,7 +1750,11 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) | ||
2887 | |||
2888 | memset(opt, 0, sizeof(struct ip_options)); | ||
2889 | opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); | ||
2890 | - if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL)) | ||
2891 | + rcu_read_lock(); | ||
2892 | + res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL); | ||
2893 | + rcu_read_unlock(); | ||
2894 | + | ||
2895 | + if (res) | ||
2896 | return; | ||
2897 | |||
2898 | if (gateway) | ||
2899 | diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c | ||
2900 | index 7efe740c06eb..4a5e55e94a9e 100644 | ||
2901 | --- a/net/ipv4/gre_demux.c | ||
2902 | +++ b/net/ipv4/gre_demux.c | ||
2903 | @@ -60,7 +60,9 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) | ||
2904 | } | ||
2905 | EXPORT_SYMBOL_GPL(gre_del_protocol); | ||
2906 | |||
2907 | -/* Fills in tpi and returns header length to be pulled. */ | ||
2908 | +/* Fills in tpi and returns header length to be pulled. | ||
2909 | + * Note that caller must use pskb_may_pull() before pulling GRE header. | ||
2910 | + */ | ||
2911 | int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, | ||
2912 | bool *csum_err, __be16 proto, int nhs) | ||
2913 | { | ||
2914 | @@ -114,8 +116,14 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, | ||
2915 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header | ||
2916 | */ | ||
2917 | if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) { | ||
2918 | + u8 _val, *val; | ||
2919 | + | ||
2920 | + val = skb_header_pointer(skb, nhs + hdr_len, | ||
2921 | + sizeof(_val), &_val); | ||
2922 | + if (!val) | ||
2923 | + return -EINVAL; | ||
2924 | tpi->proto = proto; | ||
2925 | - if ((*(u8 *)options & 0xF0) != 0x40) | ||
2926 | + if ((*val & 0xF0) != 0x40) | ||
2927 | hdr_len += 4; | ||
2928 | } | ||
2929 | tpi->hdr_len = hdr_len; | ||
2930 | diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c | ||
2931 | index 6b1310d5e808..a4c00242a90b 100644 | ||
2932 | --- a/net/ipv6/addrconf.c | ||
2933 | +++ b/net/ipv6/addrconf.c | ||
2934 | @@ -3189,6 +3189,10 @@ static void addrconf_dev_config(struct net_device *dev) | ||
2935 | (dev->type != ARPHRD_6LOWPAN) && | ||
2936 | (dev->type != ARPHRD_NONE)) { | ||
2937 | /* Alas, we support only Ethernet autoconfiguration. */ | ||
2938 | + idev = __in6_dev_get(dev); | ||
2939 | + if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP && | ||
2940 | + dev->flags & IFF_MULTICAST) | ||
2941 | + ipv6_mc_up(idev); | ||
2942 | return; | ||
2943 | } | ||
2944 | |||
2945 | diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c | ||
2946 | index 81fd35ed8732..1080770b5eaf 100644 | ||
2947 | --- a/net/ipv6/ipv6_sockglue.c | ||
2948 | +++ b/net/ipv6/ipv6_sockglue.c | ||
2949 | @@ -184,9 +184,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | ||
2950 | retv = -EBUSY; | ||
2951 | break; | ||
2952 | } | ||
2953 | - } else if (sk->sk_protocol != IPPROTO_TCP) | ||
2954 | + } else if (sk->sk_protocol == IPPROTO_TCP) { | ||
2955 | + if (sk->sk_prot != &tcpv6_prot) { | ||
2956 | + retv = -EBUSY; | ||
2957 | + break; | ||
2958 | + } | ||
2959 | break; | ||
2960 | - | ||
2961 | + } else { | ||
2962 | + break; | ||
2963 | + } | ||
2964 | if (sk->sk_state != TCP_ESTABLISHED) { | ||
2965 | retv = -ENOTCONN; | ||
2966 | break; | ||
2967 | diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c | ||
2968 | index 74652eb2f90f..a6f265262f15 100644 | ||
2969 | --- a/net/mac80211/rx.c | ||
2970 | +++ b/net/mac80211/rx.c | ||
2971 | @@ -3841,7 +3841,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata) | ||
2972 | |||
2973 | lockdep_assert_held(&local->sta_mtx); | ||
2974 | |||
2975 | - list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||
2976 | + list_for_each_entry(sta, &local->sta_list, list) { | ||
2977 | if (sdata != sta->sdata && | ||
2978 | (!sta->sdata->bss || sta->sdata->bss != sdata->bss)) | ||
2979 | continue; | ||
2980 | diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c | ||
2981 | index 3f499126727c..8396dc8ee247 100644 | ||
2982 | --- a/net/netfilter/nfnetlink_cthelper.c | ||
2983 | +++ b/net/netfilter/nfnetlink_cthelper.c | ||
2984 | @@ -711,6 +711,8 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = { | ||
2985 | [NFCTH_NAME] = { .type = NLA_NUL_STRING, | ||
2986 | .len = NF_CT_HELPER_NAME_LEN-1 }, | ||
2987 | [NFCTH_QUEUE_NUM] = { .type = NLA_U32, }, | ||
2988 | + [NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, }, | ||
2989 | + [NFCTH_STATUS] = { .type = NLA_U32, }, | ||
2990 | }; | ||
2991 | |||
2992 | static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = { | ||
2993 | diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c | ||
2994 | index 5a58f9f38095..291f24fef19a 100644 | ||
2995 | --- a/net/nfc/hci/core.c | ||
2996 | +++ b/net/nfc/hci/core.c | ||
2997 | @@ -193,13 +193,20 @@ exit: | ||
2998 | void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | ||
2999 | struct sk_buff *skb) | ||
3000 | { | ||
3001 | - u8 gate = hdev->pipes[pipe].gate; | ||
3002 | u8 status = NFC_HCI_ANY_OK; | ||
3003 | struct hci_create_pipe_resp *create_info; | ||
3004 | struct hci_delete_pipe_noti *delete_info; | ||
3005 | struct hci_all_pipe_cleared_noti *cleared_info; | ||
3006 | + u8 gate; | ||
3007 | |||
3008 | - pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); | ||
3009 | + pr_debug("from pipe %x cmd %x\n", pipe, cmd); | ||
3010 | + | ||
3011 | + if (pipe >= NFC_HCI_MAX_PIPES) { | ||
3012 | + status = NFC_HCI_ANY_E_NOK; | ||
3013 | + goto exit; | ||
3014 | + } | ||
3015 | + | ||
3016 | + gate = hdev->pipes[pipe].gate; | ||
3017 | |||
3018 | switch (cmd) { | ||
3019 | case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: | ||
3020 | @@ -387,8 +394,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | ||
3021 | struct sk_buff *skb) | ||
3022 | { | ||
3023 | int r = 0; | ||
3024 | - u8 gate = hdev->pipes[pipe].gate; | ||
3025 | + u8 gate; | ||
3026 | + | ||
3027 | + if (pipe >= NFC_HCI_MAX_PIPES) { | ||
3028 | + pr_err("Discarded event %x to invalid pipe %x\n", event, pipe); | ||
3029 | + goto exit; | ||
3030 | + } | ||
3031 | |||
3032 | + gate = hdev->pipes[pipe].gate; | ||
3033 | if (gate == NFC_HCI_INVALID_GATE) { | ||
3034 | pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); | ||
3035 | goto exit; | ||
3036 | diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c | ||
3037 | index d3c8dd5dc817..e79a49fe61e8 100644 | ||
3038 | --- a/net/nfc/netlink.c | ||
3039 | +++ b/net/nfc/netlink.c | ||
3040 | @@ -62,7 +62,10 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { | ||
3041 | [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED }, | ||
3042 | [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING, | ||
3043 | .len = NFC_FIRMWARE_NAME_MAXSIZE }, | ||
3044 | + [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 }, | ||
3045 | [NFC_ATTR_SE_APDU] = { .type = NLA_BINARY }, | ||
3046 | + [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 }, | ||
3047 | + [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, | ||
3048 | [NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, | ||
3049 | |||
3050 | }; | ||
3051 | diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c | ||
3052 | index 7e7eba33bbdb..9f53d4ec0e37 100644 | ||
3053 | --- a/net/sched/sch_fq.c | ||
3054 | +++ b/net/sched/sch_fq.c | ||
3055 | @@ -697,6 +697,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { | ||
3056 | [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 }, | ||
3057 | [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 }, | ||
3058 | [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 }, | ||
3059 | + [TCA_FQ_ORPHAN_MASK] = { .type = NLA_U32 }, | ||
3060 | [TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NLA_U32 }, | ||
3061 | }; | ||
3062 | |||
3063 | diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c | ||
3064 | index 9823bef65e5e..0048f90944dd 100644 | ||
3065 | --- a/net/wireless/nl80211.c | ||
3066 | +++ b/net/wireless/nl80211.c | ||
3067 | @@ -359,6 +359,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | ||
3068 | [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, | ||
3069 | [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, | ||
3070 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, | ||
3071 | + [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 }, | ||
3072 | + [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG }, | ||
3073 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, | ||
3074 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, | ||
3075 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, | ||
3076 | @@ -407,6 +409,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | ||
3077 | [NL80211_ATTR_MDID] = { .type = NLA_U16 }, | ||
3078 | [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, | ||
3079 | .len = IEEE80211_MAX_DATA_LEN }, | ||
3080 | + [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 }, | ||
3081 | + [NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 }, | ||
3082 | [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 }, | ||
3083 | [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, | ||
3084 | [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, | ||
3085 | @@ -432,6 +436,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | ||
3086 | [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, | ||
3087 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, | ||
3088 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, | ||
3089 | + [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 }, | ||
3090 | [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, | ||
3091 | [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, | ||
3092 | [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, | ||
3093 | diff --git a/net/wireless/reg.c b/net/wireless/reg.c | ||
3094 | index 0e66768427ba..6d5f3f737207 100644 | ||
3095 | --- a/net/wireless/reg.c | ||
3096 | +++ b/net/wireless/reg.c | ||
3097 | @@ -1730,7 +1730,7 @@ static void handle_channel_custom(struct wiphy *wiphy, | ||
3098 | break; | ||
3099 | } | ||
3100 | |||
3101 | - if (IS_ERR(reg_rule)) { | ||
3102 | + if (IS_ERR_OR_NULL(reg_rule)) { | ||
3103 | pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", | ||
3104 | chan->center_freq); | ||
3105 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { |