Revision 9e2b7fa2df4365e99934901da4fb4af52d81e820 authored by Martin Willi on 06 November 2020, 07:30:30 UTC, committed by Jakub Kicinski on 12 November 2020, 15:47:06 UTC
VRF devices use an optimized direct path on output if a default qdisc
is involved, calling Netfilter hooks directly. This path, however, does
not consider Netfilter rules completing asynchronously, such as with
NFQUEUE. The Netfilter okfn() is called for asynchronously accepted
packets, but the VRF never passes that packet down the stack to send
it out over the slave device. Using the slower redirect path for this
seems not feasible, as we do not know beforehand if a Netfilter hook
has asynchronously completing rules.

Fix the use of asynchronously completing Netfilter rules in OUTPUT and
POSTROUTING by using a special completion function that additionally
calls dst_output() to pass the packet down the stack. Also, slightly
adjust the use of nf_reset_ct() so that is called in the asynchronous
case, too.

Fixes: dcdd43c41e60 ("net: vrf: performance improvements for IPv4")
Fixes: a9ec54d1b0cd ("net: vrf: performance improvements for IPv6")
Signed-off-by: Martin Willi <martin@strongswan.org>
Link: https://lore.kernel.org/r/20201106073030.3974927-1-martin@strongswan.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 52755b6
Raw File
ide-scan-pci.c
/*
 * support for probing IDE PCI devices in the PCI bus order
 *
 * Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
 * Copyright (c) 1995-1998  Mark Lord
 *
 * May be copied or modified under the terms of the GNU General Public License
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>

/*
 *	Module interfaces
 */

static int pre_init = 1;		/* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);

/*
 *	__ide_pci_register_driver	-	attach IDE driver
 *	@driver: pci driver
 *	@module: owner module of the driver
 *
 *	Registers a driver with the IDE layer. The IDE layer arranges that
 *	boot time setup is done in the expected device order and then
 *	hands the controllers off to the core PCI code to do the rest of
 *	the work.
 *
 *	Returns are the same as for pci_register_driver
 */

int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
			      const char *mod_name)
{
	if (!pre_init)
		return __pci_register_driver(driver, module, mod_name);
	driver->driver.owner = module;
	list_add_tail(&driver->node, &ide_pci_drivers);
	return 0;
}
EXPORT_SYMBOL_GPL(__ide_pci_register_driver);

/**
 *	ide_scan_pcidev		-	find an IDE driver for a device
 *	@dev: PCI device to check
 *
 *	Look for an IDE driver to handle the device we are considering.
 *	This is only used during boot up to get the ordering correct. After
 *	boot up the pci layer takes over the job.
 */

static int __init ide_scan_pcidev(struct pci_dev *dev)
{
	struct list_head *l;
	struct pci_driver *d;
	int ret;

	list_for_each(l, &ide_pci_drivers) {
		d = list_entry(l, struct pci_driver, node);
		if (d->id_table) {
			const struct pci_device_id *id =
				pci_match_id(d->id_table, dev);

			if (id != NULL) {
				pci_assign_irq(dev);
				ret = d->probe(dev, id);
				if (ret >= 0) {
					dev->driver = d;
					pci_dev_get(dev);
					return 1;
				}
			}
		}
	}
	return 0;
}

/**
 *	ide_scan_pcibus		-	perform the initial IDE driver scan
 *
 *	Perform the initial bus rather than driver ordered scan of the
 *	PCI drivers. After this all IDE pci handling becomes standard
 *	module ordering not traditionally ordered.
 */

static int __init ide_scan_pcibus(void)
{
	struct pci_dev *dev = NULL;
	struct pci_driver *d, *tmp;

	pre_init = 0;
	for_each_pci_dev(dev)
		ide_scan_pcidev(dev);

	/*
	 *	Hand the drivers over to the PCI layer now we
	 *	are post init.
	 */

	list_for_each_entry_safe(d, tmp, &ide_pci_drivers, node) {
		list_del(&d->node);
		if (__pci_register_driver(d, d->driver.owner,
					  d->driver.mod_name))
			printk(KERN_ERR "%s: failed to register %s driver\n",
					__func__, d->driver.mod_name);
	}

	return 0;
}
device_initcall(ide_scan_pcibus);
back to top