* [PATCH 1/7] fore200e: simplify fore200e_bus usage
From: Christoph Hellwig @ 2018-10-09 14:57 UTC (permalink / raw)
To: Chas Williams, netdev; +Cc: linux-atm-general, linux-kernel
In-Reply-To: <20181009145720.32578-1-hch@lst.de>
There is no need to have a global array of the ops, instead PCI and sbus
can have their own instances assigned in *_probe. Also switch to C99
initializers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/atm/fore200e.c | 121 +++++++++++++++++++----------------------
1 file changed, 56 insertions(+), 65 deletions(-)
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 99a38115b0a8..008bd8541c61 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -106,7 +106,6 @@
static const struct atmdev_ops fore200e_ops;
-static const struct fore200e_bus fore200e_bus[];
static LIST_HEAD(fore200e_boards);
@@ -664,9 +663,31 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
}
+static const struct fore200e_bus fore200e_pci_ops = {
+ .model_name = "PCA-200E",
+ .proc_name = "pca200e",
+ .descr_alignment = 32,
+ .buffer_alignment = 4,
+ .status_alignment = 32,
+ .read = fore200e_pca_read,
+ .write = fore200e_pca_write,
+ .dma_map = fore200e_pca_dma_map,
+ .dma_unmap = fore200e_pca_dma_unmap,
+ .dma_sync_for_cpu = fore200e_pca_dma_sync_for_cpu,
+ .dma_sync_for_device = fore200e_pca_dma_sync_for_device,
+ .dma_chunk_alloc = fore200e_pca_dma_chunk_alloc,
+ .dma_chunk_free = fore200e_pca_dma_chunk_free,
+ .configure = fore200e_pca_configure,
+ .map = fore200e_pca_map,
+ .reset = fore200e_pca_reset,
+ .prom_read = fore200e_pca_prom_read,
+ .unmap = fore200e_pca_unmap,
+ .irq_check = fore200e_pca_irq_check,
+ .irq_ack = fore200e_pca_irq_ack,
+ .proc_read = fore200e_pca_proc_read,
+};
#endif /* CONFIG_PCI */
-
#ifdef CONFIG_SBUS
static u32 fore200e_sba_read(volatile u32 __iomem *addr)
@@ -855,8 +876,32 @@ static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n",
(regs ? regs->which_io : 0), op->dev.of_node->name);
}
-#endif /* CONFIG_SBUS */
+static const struct fore200e_bus fore200e_sbus_ops = {
+ .model_name = "SBA-200E",
+ .proc_name = "sba200e",
+ .descr_alignment = 32,
+ .buffer_alignent = 64,
+ .status_alignment = 32,
+ .read = fore200e_sba_read,
+ .write = fore200e_sba_write,
+ .dma_map = fore200e_sba_dma_map,
+ .dma_unap = fore200e_sba_dma_unmap,
+ .dma_sync_for_cpu = fore200e_sba_dma_sync_for_cpu,
+ .dma_sync_for_device = fore200e_sba_dma_sync_for_device,
+ .dma_chunk_alloc = fore200e_sba_dma_chunk_alloc,
+ .dma_chunk_free = fore200e_sba_dma_chunk_free,
+ .configure = fore200e_sba_configure,
+ .map = fore200e_sba_map,
+ .reset = fore200e_sba_reset,
+ .prom_read = fore200e_sba_prom_read,
+ .unmap = fore200e_sba_unmap,
+ .irq_enable = fore200e_sba_irq_enable,
+ .irq_check = fore200e_sba_irq_check,
+ .irq_ack = fore200e_sba_irq_ack,
+ .proc_read = fore200e_sba_proc_read,
+};
+#endif /* CONFIG_SBUS */
static void
fore200e_tx_irq(struct fore200e* fore200e)
@@ -2631,7 +2676,6 @@ static const struct of_device_id fore200e_sba_match[];
static int fore200e_sba_probe(struct platform_device *op)
{
const struct of_device_id *match;
- const struct fore200e_bus *bus;
struct fore200e *fore200e;
static int index = 0;
int err;
@@ -2639,18 +2683,17 @@ static int fore200e_sba_probe(struct platform_device *op)
match = of_match_device(fore200e_sba_match, &op->dev);
if (!match)
return -EINVAL;
- bus = match->data;
fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
if (!fore200e)
return -ENOMEM;
- fore200e->bus = bus;
+ fore200e->bus = &fore200e_sbus_ops;
fore200e->bus_dev = op;
fore200e->irq = op->archdata.irqs[0];
fore200e->phys_base = op->resource[0].start;
- sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+ sprintf(fore200e->name, "SBA-200E-%d", index);
err = fore200e_init(fore200e, &op->dev);
if (err < 0) {
@@ -2678,7 +2721,6 @@ static int fore200e_sba_remove(struct platform_device *op)
static const struct of_device_id fore200e_sba_match[] = {
{
.name = SBA200E_PROM_NAME,
- .data = (void *) &fore200e_bus[1],
},
{},
};
@@ -2698,7 +2740,6 @@ static struct platform_driver fore200e_sba_driver = {
static int fore200e_pca_detect(struct pci_dev *pci_dev,
const struct pci_device_id *pci_ent)
{
- const struct fore200e_bus* bus = (struct fore200e_bus*) pci_ent->driver_data;
struct fore200e* fore200e;
int err = 0;
static int index = 0;
@@ -2719,20 +2760,19 @@ static int fore200e_pca_detect(struct pci_dev *pci_dev,
goto out_disable;
}
- fore200e->bus = bus;
+ fore200e->bus = &fore200e_pci_ops;
fore200e->bus_dev = pci_dev;
fore200e->irq = pci_dev->irq;
fore200e->phys_base = pci_resource_start(pci_dev, 0);
- sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+ sprintf(fore200e->name, "PCA-200E-%d", index - 1);
pci_set_master(pci_dev);
- printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
- fore200e->bus->model_name,
+ printk(FORE200E "device PCA-200E found at 0x%lx, IRQ %s\n",
fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
- sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+ sprintf(fore200e->name, "PCA-200E-%d", index);
err = fore200e_init(fore200e, &pci_dev->dev);
if (err < 0) {
@@ -2767,8 +2807,7 @@ static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
static const struct pci_device_id fore200e_pca_tbl[] = {
- { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, (unsigned long) &fore200e_bus[0] },
+ { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID },
{ 0, }
};
@@ -3108,8 +3147,7 @@ module_init(fore200e_module_init);
module_exit(fore200e_module_cleanup);
-static const struct atmdev_ops fore200e_ops =
-{
+static const struct atmdev_ops fore200e_ops = {
.open = fore200e_open,
.close = fore200e_close,
.ioctl = fore200e_ioctl,
@@ -3121,53 +3159,6 @@ static const struct atmdev_ops fore200e_ops =
.owner = THIS_MODULE
};
-
-static const struct fore200e_bus fore200e_bus[] = {
-#ifdef CONFIG_PCI
- { "PCA-200E", "pca200e", 32, 4, 32,
- fore200e_pca_read,
- fore200e_pca_write,
- fore200e_pca_dma_map,
- fore200e_pca_dma_unmap,
- fore200e_pca_dma_sync_for_cpu,
- fore200e_pca_dma_sync_for_device,
- fore200e_pca_dma_chunk_alloc,
- fore200e_pca_dma_chunk_free,
- fore200e_pca_configure,
- fore200e_pca_map,
- fore200e_pca_reset,
- fore200e_pca_prom_read,
- fore200e_pca_unmap,
- NULL,
- fore200e_pca_irq_check,
- fore200e_pca_irq_ack,
- fore200e_pca_proc_read,
- },
-#endif
-#ifdef CONFIG_SBUS
- { "SBA-200E", "sba200e", 32, 64, 32,
- fore200e_sba_read,
- fore200e_sba_write,
- fore200e_sba_dma_map,
- fore200e_sba_dma_unmap,
- fore200e_sba_dma_sync_for_cpu,
- fore200e_sba_dma_sync_for_device,
- fore200e_sba_dma_chunk_alloc,
- fore200e_sba_dma_chunk_free,
- fore200e_sba_configure,
- fore200e_sba_map,
- fore200e_sba_reset,
- fore200e_sba_prom_read,
- fore200e_sba_unmap,
- fore200e_sba_irq_enable,
- fore200e_sba_irq_check,
- fore200e_sba_irq_ack,
- fore200e_sba_proc_read,
- },
-#endif
- {}
-};
-
MODULE_LICENSE("GPL");
#ifdef CONFIG_PCI
#ifdef __LITTLE_ENDIAN__
--
2.19.0
^ permalink raw reply related
* Re: [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Mark Brown @ 2018-10-09 15:15 UTC (permalink / raw)
To: Wolfram Sang
Cc: Silesh C V, Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel,
linux-arm-kernel, linux-i2c, linux-rdma, netdev, devicetree,
linux-spi, Mathieu Poirier, Lijun Ou, Wei Hu(Xavier),
Yisen Zhuang, Salil Mehta, Srinivas Kandagatla, Andrew Lunn,
Florian Fainelli, Rob Herring, Frank Rowand, David S. Miller
In-Reply-To: <20181009110210.i6xphyuy5jkcfaug@katana>
[-- Attachment #1: Type: text/plain, Size: 444 bytes --]
On Tue, Oct 09, 2018 at 01:02:10PM +0200, Wolfram Sang wrote:
> We recently had this discussion in I2C world about using the parent if
> the (logical) device has a NULL fw_node [1]. I don't know if the other
> subsystems you modify use logical devices as well? If no, it seems we
> need an additional check for the parent in the I2C core only. If yes,
> this might be considered in your patchset?
SPI has a logical controller device as well.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v2] net: core: change bool members of struct net_device to bitfield members
From: David Ahern @ 2018-10-09 15:20 UTC (permalink / raw)
To: Heiner Kallweit, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <e0150624-a317-eb4f-126e-92c99db8ce13@gmail.com>
On 10/8/18 2:17 PM, Heiner Kallweit wrote:
> bool is good as parameter type or function return type, but if used
> for struct members it consumes more memory than needed.
> Changing the bool members of struct net_device to bitfield members
> allows to decrease the memory footprint of this struct.
What does pahole show for the size of the struct before and after? I
suspect you have not really changed the size and certainly not the
actual memory allocated.
^ permalink raw reply
* [PATCH stable 4.9 00/29] backport of IP fragmentation fixes
From: Florian Fainelli @ 2018-10-09 22:48 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin, Florian Fainelli
This is based on Stephen's v4.14 patches, with the necessary merge
conflicts, and the lack of timer_setup() on the 4.9 baseline.
Perf results on a gigabit capable system, before and after are below.
Series can also be found here:
https://github.com/ffainelli/linux/commits/fragment-stack-v4.9
PerfTop: 457 irqs/sec kernel:74.4% exact: 0.0% [4000Hz cycles], (all, 4 CPUs)
-------------------------------------------------------------------------------
29.62% [kernel] [k] ip_defrag
6.57% [kernel] [k] arch_cpu_idle
1.72% [kernel] [k] v7_dma_inv_range
1.68% [kernel] [k] __netif_receive_skb_core
1.43% [kernel] [k] fib_table_lookup
1.30% [kernel] [k] finish_task_switch
1.08% [kernel] [k] ip_rcv
1.01% [kernel] [k] skb_release_data
0.99% [kernel] [k] __slab_free
0.96% [kernel] [k] bcm_sysport_poll
0.88% [kernel] [k] __netdev_alloc_skb
0.87% [kernel] [k] tick_nohz_idle_enter
0.86% [kernel] [k] dev_gro_receive
0.85% [kernel] [k] _raw_spin_unlock_irqrestore
0.84% [kernel] [k] __memzero
0.74% [kernel] [k] tick_nohz_idle_exit
0.73% ld-2.24.so [.] do_lookup_x
0.66% [kernel] [k] kmem_cache_free
0.66% [kernel] [k] bcm_sysport_rx_refill
0.65% [kernel] [k] eth_type_trans
After patching:
PerfTop: 170 irqs/sec kernel:86.5% exact: 0.0% [4000Hz cycles], (all, 4 CPUs)
-------------------------------------------------------------------------------
7.79% [kernel] [k] arch_cpu_idle
5.14% [kernel] [k] v7_dma_inv_range
4.20% [kernel] [k] ip_defrag
3.89% [kernel] [k] __netif_receive_skb_core
3.65% [kernel] [k] fib_table_lookup
2.16% [kernel] [k] finish_task_switch
1.93% [kernel] [k] _raw_spin_unlock_irqrestore
1.90% [kernel] [k] ip_rcv
1.84% [kernel] [k] bcm_sysport_poll
1.83% [kernel] [k] __memzero
1.65% [kernel] [k] __netdev_alloc_skb
1.60% [kernel] [k] __slab_free
1.49% [kernel] [k] __do_softirq
1.49% [kernel] [k] bcm_sysport_rx_refill
1.31% [kernel] [k] dma_cache_maint_page
1.25% [kernel] [k] tick_nohz_idle_enter
1.24% [kernel] [k] ip_route_input_noref
1.17% [kernel] [k] eth_type_trans
1.06% [kernel] [k] fib_validate_source
1.03% [kernel] [k] inet_frag_find
Dan Carpenter (1):
ipv4: frags: precedence bug in ip_expire()
Eric Dumazet (22):
inet: frags: change inet_frags_init_net() return value
inet: frags: add a pointer to struct netns_frags
inet: frags: refactor ipfrag_init()
inet: frags: refactor ipv6_frag_init()
inet: frags: refactor lowpan_net_frag_init()
ipv6: export ip6 fragments sysctl to unprivileged users
rhashtable: add schedule points
inet: frags: use rhashtables for reassembly units
inet: frags: remove some helpers
inet: frags: get rif of inet_frag_evicting()
inet: frags: remove inet_frag_maybe_warn_overflow()
inet: frags: break the 2GB limit for frags storage
inet: frags: do not clone skb in ip_expire()
ipv6: frags: rewrite ip6_expire_frag_queue()
rhashtable: reorganize struct rhashtable layout
inet: frags: reorganize struct netns_frags
inet: frags: get rid of ipfrag_skb_cb/FRAG_CB
inet: frags: fix ip6frag_low_thresh boundary
net: speed up skb_rbtree_purge()
net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends
net: add rb_to_skb() and other rb tree helpers
net: sk_buff rbnode reorg
Florian Westphal (1):
ipv6: defrag: drop non-last frags smaller than min mtu
Peter Oskolkov (4):
ip: discard IPv4 datagrams with overlapping segments.
net: modify skb_rbtree_purge to return the truesize of all purged
skbs.
ip: add helpers to process in-order fragments faster.
ip: process in-order fragments efficiently
Taehee Yoo (1):
ip: frags: fix crash in ip_do_fragment()
Documentation/networking/ip-sysctl.txt | 13 +-
include/linux/rhashtable.h | 4 +-
include/linux/skbuff.h | 48 +-
include/net/inet_frag.h | 133 +++---
include/net/ip.h | 1 -
include/net/ipv6.h | 26 +-
include/uapi/linux/snmp.h | 1 +
lib/rhashtable.c | 5 +-
net/core/skbuff.c | 31 +-
net/ieee802154/6lowpan/6lowpan_i.h | 26 +-
net/ieee802154/6lowpan/reassembly.c | 148 +++---
net/ipv4/inet_fragment.c | 379 ++++------------
net/ipv4/ip_fragment.c | 573 +++++++++++++-----------
net/ipv4/proc.c | 7 +-
net/ipv4/tcp_input.c | 33 +-
net/ipv6/netfilter/nf_conntrack_reasm.c | 100 ++---
net/ipv6/proc.c | 5 +-
net/ipv6/reassembly.c | 212 ++++-----
18 files changed, 785 insertions(+), 960 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH stable 4.9 04/29] inet: frags: refactor ipv6_frag_init()
From: Florian Fainelli @ 2018-10-09 22:48 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
We want to call inet_frags_init() earlier.
This is a prereq to "inet: frags: use rhashtables for reassembly units"
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 5b975bab23615cd0fdf67af6c9298eb01c4b9f61)
---
net/ipv6/reassembly.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 436e6d594f25..9440bb9bdab7 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -740,10 +740,21 @@ int __init ipv6_frag_init(void)
{
int ret;
- ret = inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT);
+ ip6_frags.hashfn = ip6_hashfn;
+ ip6_frags.constructor = ip6_frag_init;
+ ip6_frags.destructor = NULL;
+ ip6_frags.qsize = sizeof(struct frag_queue);
+ ip6_frags.match = ip6_frag_match;
+ ip6_frags.frag_expire = ip6_frag_expire;
+ ip6_frags.frags_cache_name = ip6_frag_cache_name;
+ ret = inet_frags_init(&ip6_frags);
if (ret)
goto out;
+ ret = inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT);
+ if (ret)
+ goto err_protocol;
+
ret = ip6_frags_sysctl_register();
if (ret)
goto err_sysctl;
@@ -752,16 +763,6 @@ int __init ipv6_frag_init(void)
if (ret)
goto err_pernet;
- ip6_frags.hashfn = ip6_hashfn;
- ip6_frags.constructor = ip6_frag_init;
- ip6_frags.destructor = NULL;
- ip6_frags.qsize = sizeof(struct frag_queue);
- ip6_frags.match = ip6_frag_match;
- ip6_frags.frag_expire = ip6_frag_expire;
- ip6_frags.frags_cache_name = ip6_frag_cache_name;
- ret = inet_frags_init(&ip6_frags);
- if (ret)
- goto err_pernet;
out:
return ret;
@@ -769,6 +770,8 @@ int __init ipv6_frag_init(void)
ip6_frags_sysctl_unregister();
err_sysctl:
inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
+err_protocol:
+ inet_frags_fini(&ip6_frags);
goto out;
}
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 05/29] inet: frags: refactor lowpan_net_frag_init()
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
We want to call lowpan_net_frag_init() earlier.
Similar to commit "inet: frags: refactor ipv6_frag_init()"
This is a prereq to "inet: frags: use rhashtables for reassembly units"
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 807f1844df4ac23594268fa9f41902d0549e92aa)
---
net/ieee802154/6lowpan/reassembly.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index 9ccb8458b5c3..977b4ed58112 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -614,14 +614,6 @@ int __init lowpan_net_frag_init(void)
{
int ret;
- ret = lowpan_frags_sysctl_register();
- if (ret)
- return ret;
-
- ret = register_pernet_subsys(&lowpan_frags_ops);
- if (ret)
- goto err_pernet;
-
lowpan_frags.hashfn = lowpan_hashfn;
lowpan_frags.constructor = lowpan_frag_init;
lowpan_frags.destructor = NULL;
@@ -631,11 +623,21 @@ int __init lowpan_net_frag_init(void)
lowpan_frags.frags_cache_name = lowpan_frags_cache_name;
ret = inet_frags_init(&lowpan_frags);
if (ret)
- goto err_pernet;
+ goto out;
+ ret = lowpan_frags_sysctl_register();
+ if (ret)
+ goto err_sysctl;
+
+ ret = register_pernet_subsys(&lowpan_frags_ops);
+ if (ret)
+ goto err_pernet;
+out:
return ret;
err_pernet:
lowpan_frags_sysctl_unregister();
+err_sysctl:
+ inet_frags_fini(&lowpan_frags);
return ret;
}
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 11/29] inet: frags: remove inet_frag_maybe_warn_overflow()
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
This function is obsolete, after rhashtable addition to inet defrag.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 2d44ed22e607f9a285b049de2263e3840673a260)
---
include/net/inet_frag.h | 2 --
net/ieee802154/6lowpan/reassembly.c | 5 ++---
net/ipv4/inet_fragment.c | 11 -----------
net/ipv4/ip_fragment.c | 5 ++---
net/ipv6/netfilter/nf_conntrack_reasm.c | 5 ++---
net/ipv6/reassembly.c | 5 ++---
6 files changed, 8 insertions(+), 25 deletions(-)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 7e984045b2b7..23161bf5d899 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -109,8 +109,6 @@ void inet_frags_exit_net(struct netns_frags *nf);
void inet_frag_kill(struct inet_frag_queue *q);
void inet_frag_destroy(struct inet_frag_queue *q);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key);
-void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
- const char *prefix);
static inline void inet_frag_put(struct inet_frag_queue *q)
{
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index a63360a05108..b54015981af9 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -83,10 +83,9 @@ fq_find(struct net *net, const struct lowpan_802154_cb *cb,
struct inet_frag_queue *q;
q = inet_frag_find(&ieee802154_lowpan->frags, &key);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
+ if (!q)
return NULL;
- }
+
return container_of(q, struct lowpan_frag_queue, q);
}
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index a50ac25878aa..47c240f50b99 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -217,14 +217,3 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key)
return inet_frag_create(nf, key);
}
EXPORT_SYMBOL(inet_frag_find);
-
-void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
- const char *prefix)
-{
- static const char msg[] = "inet_frag_find: Fragment hash bucket"
- " list length grew over limit. Dropping fragment.\n";
-
- if (PTR_ERR(q) == -ENOBUFS)
- net_dbg_ratelimited("%s%s", prefix, msg);
-}
-EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 308592a8ba97..696bfef06caa 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -219,10 +219,9 @@ static struct ipq *ip_find(struct net *net, struct iphdr *iph,
struct inet_frag_queue *q;
q = inet_frag_find(&net->ipv4.frags, &key);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
+ if (!q)
return NULL;
- }
+
return container_of(q, struct ipq, q);
}
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 314568d8b84a..267f2ae2d05c 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -177,10 +177,9 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
struct inet_frag_queue *q;
q = inet_frag_find(&net->nf_frag.frags, &key);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
+ if (!q)
return NULL;
- }
+
return container_of(q, struct frag_queue, q);
}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 629a45a4c79f..6de4cec69054 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -154,10 +154,9 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif)
key.iif = 0;
q = inet_frag_find(&net->ipv6.frags, &key);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
+ if (!q)
return NULL;
- }
+
return container_of(q, struct frag_queue, q);
}
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 13/29] inet: frags: do not clone skb in ip_expire()
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
An skb_clone() was added in commit ec4fbd64751d ("inet: frag: release
spinlock before calling icmp_send()")
While fixing the bug at that time, it also added a very high cost
for DDOS frags, as the ICMP rate limit is applied after this
expensive operation (skb_clone() + consume_skb(), implying memory
allocations, copy, and freeing)
We can use skb_get(head) here, all we want is to make sure skb wont
be freed by another cpu.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 1eec5d5670084ee644597bd26c25e22c69b9f748)
---
net/ipv4/ip_fragment.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 3dd19bebeb55..e235f62dab58 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -141,8 +141,8 @@ static bool frag_expire_skip_icmp(u32 user)
*/
static void ip_expire(unsigned long arg)
{
- struct sk_buff *clone, *head;
const struct iphdr *iph;
+ struct sk_buff *head;
struct net *net;
struct ipq *qp;
int err;
@@ -185,16 +185,12 @@ static void ip_expire(unsigned long arg)
(skb_rtable(head)->rt_type != RTN_LOCAL))
goto out;
- clone = skb_clone(head, GFP_ATOMIC);
+ skb_get(head);
+ spin_unlock(&qp->q.lock);
+ icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
+ kfree_skb(head);
+ goto out_rcu_unlock;
- /* Send an ICMP "Fragment Reassembly Timeout" message. */
- if (clone) {
- spin_unlock(&qp->q.lock);
- icmp_send(clone, ICMP_TIME_EXCEEDED,
- ICMP_EXC_FRAGTIME, 0);
- consume_skb(clone);
- goto out_rcu_unlock;
- }
out:
spin_unlock(&qp->q.lock);
out_rcu_unlock:
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 16/29] inet: frags: reorganize struct netns_frags
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
Put the read-mostly fields in a separate cache line
at the beginning of struct netns_frags, to reduce
false sharing noticed in inet_frag_kill()
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit c2615cf5a761b32bf74e85bddc223dfff3d9b9f0)
---
include/net/inet_frag.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index dea175f3418a..f47678d2ccc2 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -4,16 +4,17 @@
#include <linux/rhashtable.h>
struct netns_frags {
- struct rhashtable rhashtable ____cacheline_aligned_in_smp;
-
- /* Keep atomic mem on separate cachelines in structs that include it */
- atomic_long_t mem ____cacheline_aligned_in_smp;
/* sysctls */
long high_thresh;
long low_thresh;
int timeout;
int max_dist;
struct inet_frags *f;
+
+ struct rhashtable rhashtable ____cacheline_aligned_in_smp;
+
+ /* Keep atomic mem on separate cachelines in structs that include it */
+ atomic_long_t mem ____cacheline_aligned_in_smp;
};
/**
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 19/29] ip: discard IPv4 datagrams with overlapping segments.
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev
Cc: davem, gregkh, stable, edumazet, sthemmin, Peter Oskolkov,
Florian Westphal
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Peter Oskolkov <posk@google.com>
This behavior is required in IPv6, and there is little need
to tolerate overlapping fragments in IPv4. This change
simplifies the code and eliminates potential DDoS attack vectors.
Tested: ran ip_defrag selftest (not yet available uptream).
Suggested-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Peter Oskolkov <posk@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Florian Westphal <fw@strlen.de>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 7969e5c40dfd04799d4341f1b7cd266b6e47f227)
---
include/uapi/linux/snmp.h | 1 +
net/ipv4/ip_fragment.c | 75 ++++++++++-----------------------------
net/ipv4/proc.c | 1 +
3 files changed, 21 insertions(+), 56 deletions(-)
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index e7a31f830690..3442a26d36d9 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -55,6 +55,7 @@ enum
IPSTATS_MIB_ECT1PKTS, /* InECT1Pkts */
IPSTATS_MIB_ECT0PKTS, /* InECT0Pkts */
IPSTATS_MIB_CEPKTS, /* InCEPkts */
+ IPSTATS_MIB_REASM_OVERLAPS, /* ReasmOverlaps */
__IPSTATS_MIB_MAX
};
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 73c0adc61a65..8bfb34e9ea32 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -275,6 +275,7 @@ static int ip_frag_reinit(struct ipq *qp)
/* Add new segment to existing queue. */
static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
{
+ struct net *net = container_of(qp->q.net, struct net, ipv4.frags);
struct sk_buff *prev, *next;
struct net_device *dev;
unsigned int fragsize;
@@ -355,65 +356,23 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
}
found:
- /* We found where to put this one. Check for overlap with
- * preceding fragment, and, if needed, align things so that
- * any overlaps are eliminated.
+ /* RFC5722, Section 4, amended by Errata ID : 3089
+ * When reassembling an IPv6 datagram, if
+ * one or more its constituent fragments is determined to be an
+ * overlapping fragment, the entire datagram (and any constituent
+ * fragments) MUST be silently discarded.
+ *
+ * We do the same here for IPv4.
*/
- if (prev) {
- int i = (prev->ip_defrag_offset + prev->len) - offset;
- if (i > 0) {
- offset += i;
- err = -EINVAL;
- if (end <= offset)
- goto err;
- err = -ENOMEM;
- if (!pskb_pull(skb, i))
- goto err;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY)
- skb->ip_summed = CHECKSUM_NONE;
- }
- }
+ /* Is there an overlap with the previous fragment? */
+ if (prev &&
+ (prev->ip_defrag_offset + prev->len) > offset)
+ goto discard_qp;
- err = -ENOMEM;
-
- while (next && next->ip_defrag_offset < end) {
- int i = end - next->ip_defrag_offset; /* overlap is 'i' bytes */
-
- if (i < next->len) {
- int delta = -next->truesize;
-
- /* Eat head of the next overlapped fragment
- * and leave the loop. The next ones cannot overlap.
- */
- if (!pskb_pull(next, i))
- goto err;
- delta += next->truesize;
- if (delta)
- add_frag_mem_limit(qp->q.net, delta);
- next->ip_defrag_offset += i;
- qp->q.meat -= i;
- if (next->ip_summed != CHECKSUM_UNNECESSARY)
- next->ip_summed = CHECKSUM_NONE;
- break;
- } else {
- struct sk_buff *free_it = next;
-
- /* Old fragment is completely overridden with
- * new one drop it.
- */
- next = next->next;
-
- if (prev)
- prev->next = next;
- else
- qp->q.fragments = next;
-
- qp->q.meat -= free_it->len;
- sub_frag_mem_limit(qp->q.net, free_it->truesize);
- kfree_skb(free_it);
- }
- }
+ /* Is there an overlap with the next fragment? */
+ if (next && next->ip_defrag_offset < end)
+ goto discard_qp;
/* Note : skb->ip_defrag_offset and skb->dev share the same location */
dev = skb->dev;
@@ -461,6 +420,10 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
skb_dst_drop(skb);
return -EINPROGRESS;
+discard_qp:
+ inet_frag_kill(&qp->q);
+ err = -EINVAL;
+ __IP_INC_STATS(net, IPSTATS_MIB_REASM_OVERLAPS);
err:
kfree_skb(skb);
return err;
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index aa1e52587bf5..ec48d8eafc7e 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -134,6 +134,7 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
SNMP_MIB_ITEM("InECT1Pkts", IPSTATS_MIB_ECT1PKTS),
SNMP_MIB_ITEM("InECT0Pkts", IPSTATS_MIB_ECT0PKTS),
SNMP_MIB_ITEM("InCEPkts", IPSTATS_MIB_CEPKTS),
+ SNMP_MIB_ITEM("ReasmOverlaps", IPSTATS_MIB_REASM_OVERLAPS),
SNMP_MIB_SENTINEL
};
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 21/29] net: modify skb_rbtree_purge to return the truesize of all purged skbs.
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev
Cc: davem, gregkh, stable, edumazet, sthemmin, Peter Oskolkov,
Florian Westphal
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Peter Oskolkov <posk@google.com>
Tested: see the next patch is the series.
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 385114dec8a49b5e5945e77ba7de6356106713f4)
---
include/linux/skbuff.h | 2 +-
net/core/skbuff.c | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c7cca35fcf6d..724c6abdb9e6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2418,7 +2418,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
kfree_skb(skb);
}
-void skb_rbtree_purge(struct rb_root *root);
+unsigned int skb_rbtree_purge(struct rb_root *root);
void *netdev_alloc_frag(unsigned int fragsz);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 96a553da1518..4e545e4432eb 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2425,23 +2425,27 @@ EXPORT_SYMBOL(skb_queue_purge);
/**
* skb_rbtree_purge - empty a skb rbtree
* @root: root of the rbtree to empty
+ * Return value: the sum of truesizes of all purged skbs.
*
* Delete all buffers on an &sk_buff rbtree. Each buffer is removed from
* the list and one reference dropped. This function does not take
* any lock. Synchronization should be handled by the caller (e.g., TCP
* out-of-order queue is protected by the socket lock).
*/
-void skb_rbtree_purge(struct rb_root *root)
+unsigned int skb_rbtree_purge(struct rb_root *root)
{
struct rb_node *p = rb_first(root);
+ unsigned int sum = 0;
while (p) {
struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode);
p = rb_next(p);
rb_erase(&skb->rbnode, root);
+ sum += skb->truesize;
kfree_skb(skb);
}
+ return sum;
}
/**
--
2.17.1
^ permalink raw reply related
* [PATCH stable 4.9 23/29] net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends
From: Florian Fainelli @ 2018-10-09 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem, gregkh, stable, edumazet, sthemmin
In-Reply-To: <20181009224924.30151-1-f.fainelli@gmail.com>
From: Eric Dumazet <edumazet@google.com>
After working on IP defragmentation lately, I found that some large
packets defeat CHECKSUM_COMPLETE optimization because of NIC adding
zero paddings on the last (small) fragment.
While removing the padding with pskb_trim_rcsum(), we set skb->ip_summed
to CHECKSUM_NONE, forcing a full csum validation, even if all prior
fragments had CHECKSUM_COMPLETE set.
We can instead compute the checksum of the part we are trimming,
usually smaller than the part we keep.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 88078d98d1bb085d72af8437707279e203524fa5)
---
include/linux/skbuff.h | 5 ++---
net/core/skbuff.c | 14 ++++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 724c6abdb9e6..11974e63a41d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2954,6 +2954,7 @@ static inline unsigned char *skb_push_rcsum(struct sk_buff *skb,
return skb->data;
}
+int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len);
/**
* pskb_trim_rcsum - trim received skb and update checksum
* @skb: buffer to trim
@@ -2967,9 +2968,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
{
if (likely(len >= skb->len))
return 0;
- if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
- return __pskb_trim(skb, len);
+ return pskb_trim_rcsum_slow(skb, len);
}
static inline int __skb_trim_rcsum(struct sk_buff *skb, unsigned int len)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4e545e4432eb..038ec74fa131 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1578,6 +1578,20 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
}
EXPORT_SYMBOL(___pskb_trim);
+/* Note : use pskb_trim_rcsum() instead of calling this directly
+ */
+int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len)
+{
+ if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ int delta = skb->len - len;
+
+ skb->csum = csum_sub(skb->csum,
+ skb_checksum(skb, len, delta, 0));
+ }
+ return __pskb_trim(skb, len);
+}
+EXPORT_SYMBOL(pskb_trim_rcsum_slow);
+
/**
* __pskb_pull_tail - advance tail of skb header
* @skb: buffer to reallocate
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2] rxrpc: use correct kvec num while send response packet in rxrpc_reject_packets
From: Sergei Shtylyov @ 2018-10-09 15:34 UTC (permalink / raw)
To: YueHaibing, David Howells, davem; +Cc: linux-afs, netdev, kernel-janitors
In-Reply-To: <1539094525-174123-1-git-send-email-yuehaibing@huawei.com>
On 10/09/2018 05:15 PM, YueHaibing wrote:
> Fixes gcc '-Wunused-but-set-variable' warning:
>
> net/rxrpc/output.c: In function 'rxrpc_reject_packets':
> net/rxrpc/output.c:527:11: warning:
> variable 'ioc' set but not used [-Wunused-but-set-variable]
>
> 'ioc' is the correct kvec num while send response packet.
>
> Fixes: commit ece64fec164f ("rxrpc: Emit BUSY packets when supposed to rather than
ABORTs")
"commit" not needed here.
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH bpf-next 1/6] bpf: rename stack trace map operations
From: Mauricio Vasquez @ 2018-10-09 15:34 UTC (permalink / raw)
To: Song Liu; +Cc: Alexei Starovoitov, Daniel Borkmann, Networking
In-Reply-To: <CAPhsuW5jKw1cWyZBFMuOpwY1NFcR+kjauovQbY2yx4JJWW4qJA@mail.gmail.com>
On 10/08/2018 08:40 PM, Song Liu wrote:
> Actually, does it make sense to implement a list_map that supports
> both pop_head()
> and pop_tail()? Maybe gate one of the pop operations with options?
The main issue with this approach is the mapping to the system calls.
Adding a flag would complicate things a bit because lookup nor
lookup_and_delete have a flag argument.
> I am asking because mixing stack with stack trace is still confusing
> after this patch.
>
> Thanks,
> Song
>
> On Mon, Oct 8, 2018 at 12:11 PM Mauricio Vasquez B
> <mauricio.vasquez@polito.it> wrote:
>> In the following patches queue and stack maps (FIFO and LIFO
>> datastructures) will be implemented. In order to avoid confusion and
>> a possible name clash rename stack_map_ops to stack_trace_map_ops
>>
>> Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
>> ---
>> include/linux/bpf_types.h | 2 +-
>> kernel/bpf/stackmap.c | 2 +-
>> 2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
>> index 5432f4c9f50e..658509daacd4 100644
>> --- a/include/linux/bpf_types.h
>> +++ b/include/linux/bpf_types.h
>> @@ -51,7 +51,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_LRU_HASH, htab_lru_map_ops)
>> BPF_MAP_TYPE(BPF_MAP_TYPE_LRU_PERCPU_HASH, htab_lru_percpu_map_ops)
>> BPF_MAP_TYPE(BPF_MAP_TYPE_LPM_TRIE, trie_map_ops)
>> #ifdef CONFIG_PERF_EVENTS
>> -BPF_MAP_TYPE(BPF_MAP_TYPE_STACK_TRACE, stack_map_ops)
>> +BPF_MAP_TYPE(BPF_MAP_TYPE_STACK_TRACE, stack_trace_map_ops)
>> #endif
>> BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops)
>> BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops)
>> diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
>> index 8061a439ef18..bb41e293418d 100644
>> --- a/kernel/bpf/stackmap.c
>> +++ b/kernel/bpf/stackmap.c
>> @@ -600,7 +600,7 @@ static void stack_map_free(struct bpf_map *map)
>> put_callchain_buffers();
>> }
>>
>> -const struct bpf_map_ops stack_map_ops = {
>> +const struct bpf_map_ops stack_trace_map_ops = {
>> .map_alloc = stack_map_alloc,
>> .map_free = stack_map_free,
>> .map_get_next_key = stack_map_get_next_key,
>>
^ permalink raw reply
* Re: [RFC PATCH net 0/3] net/smc: move some definitions to UAPI
From: Ursula Braun @ 2018-10-09 15:43 UTC (permalink / raw)
To: Eugene Syromiatnikov, netdev
Cc: David S. Miller, linux-kernel, Karsten Graul, Hans Wippel,
linux-s390
In-Reply-To: <cover.1538929504.git.esyr@redhat.com>
On 10/07/2018 06:34 PM, Eugene Syromiatnikov wrote:
> Hello.
>
> As of now, it's a bit difficult to use SMC protocol, as significant part
> of definitions related to it are defined in private headers and are not
> part of UAPI. The following commits move some definitions to UAPI,
> making them readily available to user space.
>
>
> Eugene Syromiatnikov (3):
> uapi, net/smc: move protocol constant definitions to UAPI
> uapi, net/smc: provide fallback diagnosis codes in UAPI
> uapi, net/smc: provide socket state constants in UAPI
>
> include/uapi/linux/smc.h | 26 +++++++++++++++++++++++++-
> include/uapi/linux/smc_diag.h | 17 +++++++++++++++++
> net/smc/smc.h | 22 ++--------------------
> net/smc/smc_clc.h | 16 ----------------
> 4 files changed, 44 insertions(+), 37 deletions(-)
>
Hello Eugene,
I am OK with your 3 patches.
Thanks, Ursula
^ permalink raw reply
* [PATCH net v2 0/2] net: ipv4: fixes for PMTU when link MTU changes
From: Sabrina Dubroca @ 2018-10-09 15:48 UTC (permalink / raw)
To: netdev; +Cc: David Ahern, Stefano Brivio, Sabrina Dubroca
The first patch adapts the changes that commit e9fa1495d738 ("ipv6:
Reflect MTU changes on PMTU of exceptions for MTU-less routes") did in
IPv6 to IPv4: lower PMTU when the first hop's MTU drops below it, and
raise PMTU when the first hop was limiting PMTU discovery and its MTU
is increased.
The second patch fixes bugs introduced in commit d52e5a7e7ca4 ("ipv4:
lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu") that
only appear once the first patch is applied.
Selftests for these cases were introduced in net-next commit
e44e428f59e4 ("selftests: pmtu: add basic IPv4 and IPv6 PMTU tests")
v2: add cover letter, and fix a few small things in patch 1
Sabrina Dubroca (2):
net: ipv4: update fnhe_pmtu when first hop's MTU changes
net: ipv4: don't let PMTU updates increase route MTU
include/linux/netdevice.h | 7 ++++++
include/net/ip_fib.h | 1 +
net/core/dev.c | 28 ++++++++++++++++++++--
net/ipv4/fib_frontend.c | 12 ++++++----
net/ipv4/fib_semantics.c | 50 +++++++++++++++++++++++++++++++++++++++
net/ipv4/route.c | 7 +++---
6 files changed, 96 insertions(+), 9 deletions(-)
--
2.19.0
^ permalink raw reply
* [PATCH net v2 1/2] net: ipv4: update fnhe_pmtu when first hop's MTU changes
From: Sabrina Dubroca @ 2018-10-09 15:48 UTC (permalink / raw)
To: netdev; +Cc: David Ahern, Stefano Brivio, Sabrina Dubroca
In-Reply-To: <cover.1539073548.git.sd@queasysnail.net>
Since commit 5aad1de5ea2c ("ipv4: use separate genid for next hop
exceptions"), exceptions get deprecated separately from cached
routes. In particular, administrative changes don't clear PMTU anymore.
As Stefano described in commit e9fa1495d738 ("ipv6: Reflect MTU changes
on PMTU of exceptions for MTU-less routes"), the PMTU discovered before
the local MTU change can become stale:
- if the local MTU is now lower than the PMTU, that PMTU is now
incorrect
- if the local MTU was the lowest value in the path, and is increased,
we might discover a higher PMTU
Similarly to what commit e9fa1495d738 did for IPv6, update PMTU in those
cases.
If the exception was locked, the discovered PMTU was smaller than the
minimal accepted PMTU. In that case, if the new local MTU is smaller
than the current PMTU, let PMTU discovery figure out if locking of the
exception is still needed.
To do this, we need to know the old link MTU in the NETDEV_CHANGEMTU
notifier. By the time the notifier is called, dev->mtu has been
changed. This patch adds the old MTU as additional information in the
notifier structure, and a new call_netdevice_notifiers_u32() function.
Fixes: 5aad1de5ea2c ("ipv4: use separate genid for next hop exceptions")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
---
v2:
- s/u32/mtu/ in netdev_notifier_info_ext and call_netdevice_notifiers_
helper, suggested by David Ahern
- don't EXPORT_SYMBOL the helper, it's only used in net/core/dev.c
- fix typo in commit message
- fix kerneldoc comment, spotted by kbuild bot
include/linux/netdevice.h | 7 ++++++
include/net/ip_fib.h | 1 +
net/core/dev.c | 28 ++++++++++++++++++++--
net/ipv4/fib_frontend.c | 12 ++++++----
net/ipv4/fib_semantics.c | 50 +++++++++++++++++++++++++++++++++++++++
5 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c7861e4b402c..d837dad24b4c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2458,6 +2458,13 @@ struct netdev_notifier_info {
struct netlink_ext_ack *extack;
};
+struct netdev_notifier_info_ext {
+ struct netdev_notifier_info info; /* must be first */
+ union {
+ u32 mtu;
+ } ext;
+};
+
struct netdev_notifier_change_info {
struct netdev_notifier_info info; /* must be first */
unsigned int flags_changed;
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 69c91d1934c1..c9b7b136939d 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -394,6 +394,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev);
int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
int fib_sync_down_addr(struct net_device *dev, __be32 local);
int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
+void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
diff --git a/net/core/dev.c b/net/core/dev.c
index 82114e1111e6..93243479085f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1752,6 +1752,28 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
}
EXPORT_SYMBOL(call_netdevice_notifiers);
+/**
+ * call_netdevice_notifiers_mtu - call all network notifier blocks
+ * @val: value passed unmodified to notifier function
+ * @dev: net_device pointer passed unmodified to notifier function
+ * @arg: additional u32 argument passed to the notifier function
+ *
+ * Call all network notifier blocks. Parameters and return value
+ * are as for raw_notifier_call_chain().
+ */
+static int call_netdevice_notifiers_mtu(unsigned long val,
+ struct net_device *dev, u32 arg)
+{
+ struct netdev_notifier_info_ext info = {
+ .info.dev = dev,
+ .ext.mtu = arg,
+ };
+
+ BUILD_BUG_ON(offsetof(struct netdev_notifier_info_ext, info) != 0);
+
+ return call_netdevice_notifiers_info(val, &info.info);
+}
+
#ifdef CONFIG_NET_INGRESS
static DEFINE_STATIC_KEY_FALSE(ingress_needed_key);
@@ -7574,14 +7596,16 @@ int dev_set_mtu_ext(struct net_device *dev, int new_mtu,
err = __dev_set_mtu(dev, new_mtu);
if (!err) {
- err = call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+ err = call_netdevice_notifiers_mtu(NETDEV_CHANGEMTU, dev,
+ orig_mtu);
err = notifier_to_errno(err);
if (err) {
/* setting mtu back and notifying everyone again,
* so that they have a chance to revert changes.
*/
__dev_set_mtu(dev, orig_mtu);
- call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+ call_netdevice_notifiers_mtu(NETDEV_CHANGEMTU, dev,
+ new_mtu);
}
}
return err;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 2998b0e47d4b..0113993e9b2c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1243,7 +1243,8 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct netdev_notifier_changeupper_info *info;
+ struct netdev_notifier_changeupper_info *upper_info = ptr;
+ struct netdev_notifier_info_ext *info_ext = ptr;
struct in_device *in_dev;
struct net *net = dev_net(dev);
unsigned int flags;
@@ -1278,16 +1279,19 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
fib_sync_up(dev, RTNH_F_LINKDOWN);
else
fib_sync_down_dev(dev, event, false);
- /* fall through */
+ rt_cache_flush(net);
+ break;
case NETDEV_CHANGEMTU:
+ fib_sync_mtu(dev, info_ext->ext.mtu);
rt_cache_flush(net);
break;
case NETDEV_CHANGEUPPER:
- info = ptr;
+ upper_info = ptr;
/* flush all routes if dev is linked to or unlinked from
* an L3 master device (e.g., VRF)
*/
- if (info->upper_dev && netif_is_l3_master(info->upper_dev))
+ if (upper_info->upper_dev &&
+ netif_is_l3_master(upper_info->upper_dev))
fib_disable_ip(dev, NETDEV_DOWN, true);
break;
}
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index f3c89ccf14c5..446204ca7406 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1470,6 +1470,56 @@ static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
return NOTIFY_DONE;
}
+/* Update the PMTU of exceptions when:
+ * - the new MTU of the first hop becomes smaller than the PMTU
+ * - the old MTU was the same as the PMTU, and it limited discovery of
+ * larger MTUs on the path. With that limit raised, we can now
+ * discover larger MTUs
+ * A special case is locked exceptions, for which the PMTU is smaller
+ * than the minimal accepted PMTU:
+ * - if the new MTU is greater than the PMTU, don't make any change
+ * - otherwise, unlock and set PMTU
+ */
+static void nh_update_mtu(struct fib_nh *nh, u32 new, u32 orig)
+{
+ struct fnhe_hash_bucket *bucket;
+ int i;
+
+ bucket = rcu_dereference_protected(nh->nh_exceptions, 1);
+ if (!bucket)
+ return;
+
+ for (i = 0; i < FNHE_HASH_SIZE; i++) {
+ struct fib_nh_exception *fnhe;
+
+ for (fnhe = rcu_dereference_protected(bucket[i].chain, 1);
+ fnhe;
+ fnhe = rcu_dereference_protected(fnhe->fnhe_next, 1)) {
+ if (fnhe->fnhe_mtu_locked) {
+ if (new <= fnhe->fnhe_pmtu) {
+ fnhe->fnhe_pmtu = new;
+ fnhe->fnhe_mtu_locked = false;
+ }
+ } else if (new < fnhe->fnhe_pmtu ||
+ orig == fnhe->fnhe_pmtu) {
+ fnhe->fnhe_pmtu = new;
+ }
+ }
+ }
+}
+
+void fib_sync_mtu(struct net_device *dev, u32 orig_mtu)
+{
+ unsigned int hash = fib_devindex_hashfn(dev->ifindex);
+ struct hlist_head *head = &fib_info_devhash[hash];
+ struct fib_nh *nh;
+
+ hlist_for_each_entry(nh, head, nh_hash) {
+ if (nh->nh_dev == dev)
+ nh_update_mtu(nh, dev->mtu, orig_mtu);
+ }
+}
+
/* Event force Flags Description
* NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host
* NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host
--
2.19.0
^ permalink raw reply related
* [PATCH net v2 2/2] net: ipv4: don't let PMTU updates increase route MTU
From: Sabrina Dubroca @ 2018-10-09 15:48 UTC (permalink / raw)
To: netdev; +Cc: David Ahern, Stefano Brivio, Sabrina Dubroca
In-Reply-To: <cover.1539073548.git.sd@queasysnail.net>
When an MTU update with PMTU smaller than net.ipv4.route.min_pmtu is
received, we must clamp its value. However, we can receive a PMTU
exception with PMTU < old_mtu < ip_rt_min_pmtu, which would lead to an
increase in PMTU.
To fix this, take the smallest of the old MTU and ip_rt_min_pmtu.
Before this patch, in case of an update, the exception's MTU would
always change. Now, an exception can have only its lock flag updated,
but not the MTU, so we need to add a check on locking to the following
"is this exception getting updated, or close to expiring?" test.
Fixes: d52e5a7e7ca4 ("ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
---
v2: unchanged
net/ipv4/route.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b678466da451..8501554e96a4 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1001,21 +1001,22 @@ out: kfree_skb(skb);
static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
{
struct dst_entry *dst = &rt->dst;
+ u32 old_mtu = ipv4_mtu(dst);
struct fib_result res;
bool lock = false;
if (ip_mtu_locked(dst))
return;
- if (ipv4_mtu(dst) < mtu)
+ if (old_mtu < mtu)
return;
if (mtu < ip_rt_min_pmtu) {
lock = true;
- mtu = ip_rt_min_pmtu;
+ mtu = min(old_mtu, ip_rt_min_pmtu);
}
- if (rt->rt_pmtu == mtu &&
+ if (rt->rt_pmtu == mtu && !lock &&
time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
return;
--
2.19.0
^ permalink raw reply related
* (unknown),
From: Oliver Carter @ 2018-10-09 15:55 UTC (permalink / raw)
To: netdev
Netdev https://goo.gl/Gf1b7B Oliver
^ permalink raw reply
* Possible bug in traffic control?
From: Josh Coombs @ 2018-10-09 15:58 UTC (permalink / raw)
To: netdev
Hello all, I'm looking for some guidance in chasing what I believe to
be a bug in kernel traffic control filters. If I'm pinging the wrong
list let me know.
I have a homebrew MACSec bridge setup using two pairs of PCs. I
establish a MACSec link between them, and then use TC to bridge a
second ethernet interface over the MACSec link. The second interface
is connected to a Juniper switch at each end, and I'm using LACP over
the links to bond them up for redundancy. It turns out I need that
redundancy as after awhile one pair of bridges will stop flowing
packets in one direction. I've since replicated this failure with a
group of VMs as well.
My test setup to replicate the failure inside ESXi:
- Two MACSec bridge VMs, A and Z
- Two IPerf VMs, A and Z
My VMs are currently built using Ubuntu Server 18.04 to be quick, no
additional packages are required outside of iperf3. Kernel ver as
shipped currently is 4.15.0-36. I highly advise using a CPU with AES
instruction support as MACSec eats CPU without it and will take longer
to reproduce the symptoms.
- A 'MACSec Bridge' network
- A 'A Side link' network
- A 'Z Side link' network
In ESXi I used a dedicated vSwitch, 9000 MTU (to allow full 1500 eth
packets + MACSec to pass on the bridge) and the security policy is
full open (allow promiscuous, allow forged, allow mac changes) as
we're abusing the networks as direct point to point links. If using
physical machines, just cable up, my example script bumps the MTU as
required.
The MACSec boxes have two ethernet interfaces each. One pair is on
the MACSec Bridge network. The other interfaces go to the A and Z
IPerf boxes respectively via their dedicated networks. A and Z need
their interfaces configured with IPs in a common subnet, such as
192.168.0.1/30 and 192.168.0.2/30.
My script sets up MACSec, tweaks MTUs, and touches a few sysctls to
turn the involved interfaces into silent actors. It then uses TC to
start the actual bridging. From there I've been firing up iperf 3
sessions in both directions between A and Z to hammer the bridge until
it fails. When it does, I can see packets stop being bridged in one
direction on one MACSec host, but not the other. The second host
continues to flow packets in both directions. Nothing is logged to
dmesg when this fault occurs. The fault seems to occur at roughly the
same packet / traffic amount each time. On my main application it's
after approximately 2.5TB of traffic (random mix of sizes) and with my
test bed it was after 5.5TB of 1500 byte packets.
On the impacted MACSec node, watching interface packet counters via
ifconfig and actual traffic with tcpdump I can see packets coming in
MACSec and going out the host interface, the host reply coming in but
not showing up on the MACSec interface to cross the bridge. Clearing
out the tc filter and qdisc and re-adding does not restore traffic
flow.
There is a PPA with 4.18 available for Ubuntu that I'm going to test
with next to see if that makes a difference in behavior. In the mean
time I'd appreciate any suggestions on how to diagnose this.
My MACSec bridge setup script, update sif, dif, the keys and rxmac to
match your setup. The rxmac is the mac addy of the remote bridge
interface. Keys need to be flipped between systems.
-----------------------
#!/bin/bash
# Interfaces:
# sif = Ingress physical interface (Source)
# dif = Egress physical interface (Dest)
# eif = Encrypted interface
sif=eno2
dif=enp1s0f0
eif=macsec0
# MACSec Keys:
# txkey = Transmit (Local) key
# rxkey = Receive (Remote) key
# rxmac = Receive (Remote) MAC addy
txkey=00000000000000000000000000000000
rxkey=99999999999999999999999999999999
rxmac=00:11:22:33:44:55
# Use jumbo frames for macsec to allow full 1500 MTU passthrough:
echo "* MTU update"
ip link set "$sif" mtu 9000
ip link set "$dif" mtu 9000
# Bring up macsec:
echo "* Enable MACSec"
modprobe macsec
ip link add link "$dif" "$eif" type macsec
ip macsec add "$eif" tx sa 0 pn 1 on key 02 "$txkey"
ip macsec add "$eif" rx address "$rxmac" port 1
ip macsec add "$eif" rx address "$rxmac" port 1 sa 0 pn 1 on key 01 "$rxkey"
ip link set "$eif" type macsec encrypt on
#ip link set "$eif" type macsec replay on window 64
# Keep system from trying to respond to observed traffic:
echo "* Clamp the system so bridge ports NEVER respond to traffic"
sysctl -w net.ipv4.conf.default.arp_filter=1
sysctl -w net.ipv4.conf.all.arp_filter=1
ip link set "$sif" down promisc on arp off multicast off
sysctl -w net.ipv6.conf."$sif".autoconf=0
sysctl -w net.ipv6.conf."$sif".accept_ra=0
sysctl -w net.ipv4.conf."$sif".arp_ignore=8
sysctl -w net.ipv4.conf."$sif".rp_filter=0
ip link set "$dif" down promisc on arp off multicast off
sysctl -w net.ipv6.conf."$dif".autoconf=0
sysctl -w net.ipv6.conf."$dif".accept_ra=0
sysctl -w net.ipv4.conf."$dif".arp_ignore=8
sysctl -w net.ipv4.conf."$dif".rp_filter=0
ip link set "$eif" down promisc on arp off multicast off
sysctl -w net.ipv6.conf."$eif".autoconf=0
sysctl -w net.ipv6.conf."$eif".accept_ra=0
sysctl -w net.ipv4.conf."$eif".arp_ignore=8
sysctl -w net.ipv4.conf."$eif".rp_filter=0
# Set up traffic mirroring:
echo "* Start Port Mirror"
# sif to eif
tc qdisc add dev "$sif" ingress
tc filter add dev "$sif" parent ffff: \
protocol all \
u32 match u8 0 0 \
action mirred egress mirror dev "$eif"
# eif to sif
tc qdisc add dev "$eif" ingress
tc filter add dev "$eif" parent ffff: \
protocol all \
u32 match u8 0 0 \
action mirred egress mirror dev "$sif"
# Bring up the interfaces:
echo "* Light tunnel NICS"
ip link set "$sif" up
ip link set "$dif" up
ip link set "$eif" up
echo " --=[ MACSec Up ]=--"
-----------------------
Josh Coombs
^ permalink raw reply
* Re: [PATCH net] net/sched: cls_api: add missing validation of netlink attributes
From: Davide Caratti @ 2018-10-09 16:12 UTC (permalink / raw)
To: David Ahern, David S. Miller, Jamal Hadi Salim; +Cc: netdev
In-Reply-To: <72e8eeea-a4e7-e80d-217d-7ccf4cd71e0d@gmail.com>
On Tue, 2018-10-09 at 08:46 -0600, David Ahern wrote:
> On 10/9/18 7:10 AM, Davide Caratti wrote:
> > Similarly to what has been done in 8b4c3cdd9dd8 ("net: sched: Add policy
> > validation for tc attributes"), add validation for TCA_CHAIN and TCA_KIND
> > netlink attributes.
> >
> > tested with:
> > # ./tdc.py -c filter
> >
> > Fixes: 5bc1701881e39 ("net: sched: introduce multichain support for filters")
> > Signed-off-by: Davide Caratti <dcaratti@redhat.com>
> > ---
> > net/sched/cls_api.c | 16 +++++++++++-----
> > 1 file changed, 11 insertions(+), 5 deletions(-)
> >
> > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> > index 0a75cb2e5e7b..fb1afc0e130d 100644
hi David,
thanks for looking at this.
> > --- a/net/sched/cls_api.c
> > +++ b/net/sched/cls_api.c
> > @@ -37,6 +37,11 @@ static LIST_HEAD(tcf_proto_base);
> > /* Protects list of registered TC modules. It is pure SMP lock. */
> > static DEFINE_RWLOCK(cls_mod_lock);
> >
> > +const struct nla_policy cls_tca_policy[TCA_MAX + 1] = {
> > + [TCA_KIND] = { .type = NLA_STRING },
> > + [TCA_CHAIN] = { .type = NLA_U32 },
> > +};
> > +
>
> it be nice to have a tc_common module so this stuff does not have to be
> defined multiple times.
it makes sense to avoid duplicating the declaration of that array. But I
don't think we can put it in a module, because CONFIG_NET_SCHED is 'bool'
and
obj-$(CONFIG_NET_SCHED) += sch_api.o
I can try a v2 where 'rtm_tca_policy' symbol in sch_api is exported and
used by cls_api.c code. WDYT?
thanks,
--
davide
^ permalink raw reply
* Re: PMTU discovery broken in Linux for UDP/raw application if the socket is not bound to a device
From: David Ahern @ 2018-10-09 16:23 UTC (permalink / raw)
To: Preethi Ramachandra; +Cc: Reji Thomas, Yogesh Ankolekar, netdev@vger.kernel.org
In-Reply-To: <4138E416-D846-47B2-AA9F-593313041E6F@juniper.net>
[ adding netdev so others know ]
On 10/9/18 3:38 AM, Preethi Ramachandra wrote:
> Hi David,
>
> I tested your fix, Linux is updating PMTU successfully.
ok, I'll send a formal patch
>
> Thanks,
> Preethi
>
> On 10/7/18, 8:59 AM, "David Ahern" <dsahern@gmail.com> wrote:
>
> The correct mailing list is netdev@vger.kernel.org (added)
>
> non-text emails will be rejected.
>
>
> On 10/3/18 10:15 PM, Preethi Ramachandra wrote:
> > Hi,
> >
> >
> >
> > While testing the PMTU discovery for UDP/raw applications, Linux is not
> > doing PMTU discovery if the UDP server socket is not bound to a device.
> > In the scenario we are testing there could be multiple VRF devices
> > created and an application like UDP/RAW can use a common socket for all
> > vrf devices. While sending packet IP_PKTINFO socket option can be used
> > to specify the vrf interface through which packet will be sent out. In
> > this case, when packet too big icmp6 error message comes back to Linux
> > on a vrf device, a route lookup is done on default routing-table(0) for
> > src/dst address which case, the route will not be found and packet is
> > dropped. If the route lookup happened with proper VRF device (packet’s
> > incoming index), the route lookup succeeds, PMTU discovery is successful.
> >
> >
> >
> > This might need a fix, please take a look.
> >
> >
> >
> > *Linux version *
> >
> >
> >
> > Linux 4.8.24
> >
> >
> >
> > *Code flow *
> >
> >
> >
> > Linux code where it expects socket’s bound device in order for PMTU
> > discovery to happen.
> >
> > *void ip6_sk_update_pmtu*(struct sk_buff *skb, struct sock *sk, __be32 mtu)
> >
> > {
> >
> > struct dst_entry *dst;
> >
> >
> >
> > ip6_update_pmtu(skb, sock_net(sk), mtu,
> >
> >
> > sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid);*<<<<< This is the point
> > where it expects socket’s sk_bound_dev_if to be set. In our testing this
> > is actually 0, since the socket is not really bound to a vrf device.*
>
> Try this based on top of tree for 4.19-next (whitespace damaged on paste
> so you'll need to manually apply and handle differences with 4.8):
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 6c1d817151ca..50b95b48b911 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -2360,10 +2360,13 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu);
>
> void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
> {
> + int oif = sk->sk_bound_dev_if;
> struct dst_entry *dst;
>
> - ip6_update_pmtu(skb, sock_net(sk), mtu,
> - sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid);
> + if (!oif && skb->dev)
> + oif = l3mdev_master_ifindex(skb->dev);
> +
> + ip6_update_pmtu(skb, sock_net(sk), mtu, oif, sk->sk_mark,
> sk->sk_uid);
>
> dst = __sk_dst_get(sk);
> if (!dst || !dst->obsolete ||
>
>
>
>
^ permalink raw reply
* BBR and TCP internal pacing causing interrupt storm with pfifo_fast
From: Gasper Zejn @ 2018-10-09 16:38 UTC (permalink / raw)
To: Kevin Yang, Eric Dumazet, netdev
Hello,
I am seeing interrupt storms of over 100k-900k local timer interrupts
when changing between network devices or networks with open TCP
connections when not using sch_fq (I was using pfifo_fast). Using sch_fq
makes the bug with interrupt storm go away.
The interrupts all called tcp_pace_kick (according to perf), which seems
to return HRTIMER_NORESTART, but apparently somewhere calls another
function, that does restart the timer.
The bug is fairly easy to reproduce. Congestion control needs to be BBR,
network scheduler was pfifo_fast, and there need to be open TCP
connections when changing network in such a way that TCP connections
cannot continue to work (eg. different client IP addresses). The more
connections the more interrupts. The connection handling code will cause
interrupt storm, which eventually sets down as the connections time out.
It is a bit annoying as high interrupt rate does not show as load. I
successfully reproduced this with 4.18.12, but this has been happening
for some time, with previous versions of kernel too.
I'd like to thank you for the comment regarding use of sch_fq with BBR
above the tcp_needs_internal_pacing function. It has pointed me in the
direction to find the workaround.
Kind regards,
Gasper Zejn
^ permalink raw reply
* enquiry 09-10-2018
From: Daniel Murray @ 2018-10-09 16:09 UTC (permalink / raw)
To: netdev
Hi,friend,
This is Daniel Murray and i am from Sinara Group Co.Ltd Group Co.,LTD in Russia.
We are glad to know about your company from the web and we are interested in your products.
Could you kindly send us your Latest catalog and price list for our trial order.
Best Regards,
Daniel Murray
Purchasing Manager
^ permalink raw reply
* [PATCH net] net/xfrm: fix out-of-bounds packet access
From: Alexei Starovoitov @ 2018-10-09 16:59 UTC (permalink / raw)
To: David S . Miller; +Cc: daniel, edumazet, netdev, kernel-team
BUG: KASAN: slab-out-of-bounds in _decode_session6+0x1331/0x14e0
net/ipv6/xfrm6_policy.c:161
Read of size 1 at addr ffff8801d882eec7 by task syz-executor1/6667
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113
print_address_description+0x6c/0x20b mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report.cold.7+0x242/0x30d mm/kasan/report.c:412
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430
_decode_session6+0x1331/0x14e0 net/ipv6/xfrm6_policy.c:161
__xfrm_decode_session+0x71/0x140 net/xfrm/xfrm_policy.c:2299
xfrm_decode_session include/net/xfrm.h:1232 [inline]
vti6_tnl_xmit+0x3c3/0x1bc1 net/ipv6/ip6_vti.c:542
__netdev_start_xmit include/linux/netdevice.h:4313 [inline]
netdev_start_xmit include/linux/netdevice.h:4322 [inline]
xmit_one net/core/dev.c:3217 [inline]
dev_hard_start_xmit+0x272/0xc10 net/core/dev.c:3233
__dev_queue_xmit+0x2ab2/0x3870 net/core/dev.c:3803
dev_queue_xmit+0x17/0x20 net/core/dev.c:3836
Reported-by: syzbot+acffccec848dc13fe459@syzkaller.appspotmail.com
Reported-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
net/ipv6/xfrm6_policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index ef3defaf43b9..d35bcf92969c 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -146,8 +146,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
- while (nh + offset + 1 < skb->data ||
- pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
+ while (nh + offset + sizeof(*exthdr) < skb->data ||
+ pskb_may_pull(skb, nh + offset + sizeof(*exthdr) - skb->data)) {
nh = skb_network_header(skb);
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox