mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-15 18:03:30 +00:00
kernel: fix conntrack leak for flow_offload connections and timeout
This commit is contained in:
parent
bce04f5924
commit
6eab209732
@ -1,7 +1,7 @@
|
||||
#src-git packages https://git.openwrt.org/feed/packages.git^1b73f267eae2dedc18969b70ed7c5d9b02288bac
|
||||
src-git packages https://github.com/openwrt/packages.git
|
||||
#src-git luci https://git.openwrt.org/project/luci.git^7d55be315d758b2a40494e732d7bdc300ee15c00
|
||||
src-git luci https://github.com/openwrt/luci.git^80cb4fef8c7db0dadc373fef122d7abb092a7191
|
||||
src-git luci https://github.com/openwrt/luci.git
|
||||
#src-git luci https://github.com/openwrt/luci.git^80cb4fef8c7db0dadc373fef122d7abb092a7191
|
||||
#src-git luci https://github.com/openwrt/luci.git;openwrt-18.06
|
||||
src-git routing https://git.openwrt.org/feed/routing.git;openwrt-18.06
|
||||
src-git telephony https://github.com/openwrt/telephony.git;openwrt-18.06
|
||||
|
@ -21,7 +21,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
static struct pernet_operations clusterip_net_ops = {
|
||||
--- a/net/netfilter/nf_tables_api.c
|
||||
+++ b/net/netfilter/nf_tables_api.c
|
||||
@@ -6477,6 +6477,12 @@ static int __net_init nf_tables_init_net(struct net *net)
|
||||
@@ -6477,6 +6477,12 @@ static int __net_init nf_tables_init_net
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule, *nr;
|
||||
@@ -6554,6 +6560,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
|
||||
@@ -6554,6 +6560,7 @@ static void __nft_release_afinfo(struct
|
||||
|
||||
static struct pernet_operations nf_tables_net_ops = {
|
||||
.init = nf_tables_init_net,
|
||||
@ -44,7 +44,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
static int __init nf_tables_module_init(void)
|
||||
--- a/net/netfilter/nfnetlink_log.c
|
||||
+++ b/net/netfilter/nfnetlink_log.c
|
||||
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(struct net *net)
|
||||
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(
|
||||
|
||||
static void __net_exit nfnl_log_net_exit(struct net *net)
|
||||
{
|
||||
@ -62,7 +62,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
static struct pernet_operations nfnl_log_net_ops = {
|
||||
--- a/net/netfilter/nfnetlink_queue.c
|
||||
+++ b/net/netfilter/nfnetlink_queue.c
|
||||
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_init(struct net *net)
|
||||
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_ini
|
||||
|
||||
static void __net_exit nfnl_queue_net_exit(struct net *net)
|
||||
{
|
||||
@ -80,7 +80,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list)
|
||||
--- a/net/netfilter/x_tables.c
|
||||
+++ b/net/netfilter/x_tables.c
|
||||
@@ -1785,8 +1785,17 @@ static int __net_init xt_net_init(struct net *net)
|
||||
@@ -1785,8 +1785,17 @@ static int __net_init xt_net_init(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 13 Jun 2018 12:33:39 +0200
|
||||
Subject: [PATCH] netfilter: nf_flow_table: fix offloaded connection timeout
|
||||
corner case
|
||||
|
||||
The full teardown of offloaded flows is deferred to a gc work item,
|
||||
however processing of packets by netfilter needs to happen immediately
|
||||
after a teardown is requested, because the conntrack state needs to be
|
||||
fixed up.
|
||||
|
||||
Since the IPS_OFFLOAD_BIT is still kept until the teardown is complete,
|
||||
the netfilter conntrack gc can accidentally bump the timeout of a
|
||||
connection where offload was just stopped, causing a conntrack entry
|
||||
leak.
|
||||
|
||||
Fix this by moving the conntrack timeout bumping from conntrack core to
|
||||
the nf_flow_offload and add a check to prevent bogus timeout bumps.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -978,18 +978,6 @@ static bool gc_worker_can_early_drop(con
|
||||
return false;
|
||||
}
|
||||
|
||||
-#define DAY (86400 * HZ)
|
||||
-
|
||||
-/* Set an arbitrary timeout large enough not to ever expire, this save
|
||||
- * us a check for the IPS_OFFLOAD_BIT from the packet path via
|
||||
- * nf_ct_is_expired().
|
||||
- */
|
||||
-static void nf_ct_offload_timeout(struct nf_conn *ct)
|
||||
-{
|
||||
- if (nf_ct_expires(ct) < DAY / 2)
|
||||
- ct->timeout = nfct_time_stamp + DAY;
|
||||
-}
|
||||
-
|
||||
static void gc_worker(struct work_struct *work)
|
||||
{
|
||||
unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u);
|
||||
@@ -1026,10 +1014,8 @@ static void gc_worker(struct work_struct
|
||||
tmp = nf_ct_tuplehash_to_ctrack(h);
|
||||
|
||||
scanned++;
|
||||
- if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) {
|
||||
- nf_ct_offload_timeout(tmp);
|
||||
+ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status))
|
||||
continue;
|
||||
- }
|
||||
|
||||
if (nf_ct_is_expired(tmp)) {
|
||||
nf_ct_gc_expired(tmp);
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -185,8 +185,27 @@ static const struct rhashtable_params nf
|
||||
.automatic_shrinking = true,
|
||||
};
|
||||
|
||||
+#define DAY (86400 * HZ)
|
||||
+
|
||||
+/* Set an arbitrary timeout large enough not to ever expire, this save
|
||||
+ * us a check for the IPS_OFFLOAD_BIT from the packet path via
|
||||
+ * nf_ct_is_expired().
|
||||
+ */
|
||||
+static void nf_ct_offload_timeout(struct flow_offload *flow)
|
||||
+{
|
||||
+ struct flow_offload_entry *entry;
|
||||
+ struct nf_conn *ct;
|
||||
+
|
||||
+ entry = container_of(flow, struct flow_offload_entry, flow);
|
||||
+ ct = entry->ct;
|
||||
+
|
||||
+ if (nf_ct_expires(ct) < DAY / 2)
|
||||
+ ct->timeout = nfct_time_stamp + DAY;
|
||||
+}
|
||||
+
|
||||
int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
|
||||
{
|
||||
+ nf_ct_offload_timeout(flow);
|
||||
flow->timeout = (u32)jiffies;
|
||||
|
||||
rhashtable_insert_fast(&flow_table->rhashtable,
|
||||
@@ -307,6 +326,8 @@ static int nf_flow_offload_gc_step(struc
|
||||
rhashtable_walk_start(&hti);
|
||||
|
||||
while ((tuplehash = rhashtable_walk_next(&hti))) {
|
||||
+ bool teardown;
|
||||
+
|
||||
if (IS_ERR(tuplehash)) {
|
||||
err = PTR_ERR(tuplehash);
|
||||
if (err != -EAGAIN)
|
||||
@@ -319,9 +340,13 @@ static int nf_flow_offload_gc_step(struc
|
||||
|
||||
flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);
|
||||
|
||||
- if (nf_flow_has_expired(flow) ||
|
||||
- (flow->flags & (FLOW_OFFLOAD_DYING |
|
||||
- FLOW_OFFLOAD_TEARDOWN)))
|
||||
+ teardown = flow->flags & (FLOW_OFFLOAD_DYING |
|
||||
+ FLOW_OFFLOAD_TEARDOWN);
|
||||
+
|
||||
+ if (!teardown)
|
||||
+ nf_ct_offload_timeout(flow);
|
||||
+
|
||||
+ if (nf_flow_has_expired(flow) || teardown)
|
||||
flow_offload_del(flow_table, flow);
|
||||
}
|
||||
out:
|
@ -0,0 +1,24 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 14 Jun 2018 11:20:09 +0200
|
||||
Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after
|
||||
timeout
|
||||
|
||||
If a connection simply times out instead of being torn down, it is left
|
||||
active with a long timeout. Fix this by calling flow_offload_fixup_ct_state
|
||||
here as well.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -233,6 +233,9 @@ static void flow_offload_del(struct nf_f
|
||||
e = container_of(flow, struct flow_offload_entry, flow);
|
||||
clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);
|
||||
|
||||
+ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
|
||||
+ flow_offload_fixup_ct_state(e->ct);
|
||||
+
|
||||
flow_offload_free(flow);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||
--- /dev/null
|
||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||
@@ -0,0 +1,365 @@
|
||||
@@ -0,0 +1,368 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
||||
+ *
|
||||
@ -326,6 +326,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ if (!this_dst || !other_dst)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ route->tuple[dir].dst = this_dst;
|
||||
+ route->tuple[dir].ifindex = xt_in(par)->ifindex;
|
||||
+ route->tuple[!dir].dst = other_dst;
|
||||
|
@ -1,80 +0,0 @@
|
||||
--- a/drivers/net/phy/mdio-boardinfo.c
|
||||
+++ b/drivers/net/phy/mdio-boardinfo.c
|
||||
@@ -15,8 +15,10 @@
|
||||
|
||||
#include "mdio-boardinfo.h"
|
||||
|
||||
-static LIST_HEAD(mdio_board_list);
|
||||
-static DEFINE_MUTEX(mdio_board_lock);
|
||||
+LIST_HEAD(mdio_board_list);
|
||||
+EXPORT_SYMBOL_GPL(mdio_board_list);
|
||||
+DEFINE_MUTEX(mdio_board_lock);
|
||||
+EXPORT_SYMBOL_GPL(mdio_board_lock);
|
||||
|
||||
/**
|
||||
* mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
|
||||
--- a/drivers/net/phy/mdio-boardinfo.h
|
||||
+++ b/drivers/net/phy/mdio-boardinfo.h
|
||||
@@ -15,6 +15,12 @@ struct mdio_board_entry {
|
||||
struct mdio_board_info board_info;
|
||||
};
|
||||
|
||||
+/* mdio_board_lock protects mdio_board_list
|
||||
+ * only mdio_bus components are allowed to use these symbols.
|
||||
+ */
|
||||
+extern struct mutex mdio_board_lock;
|
||||
+extern struct list_head mdio_board_list;
|
||||
+
|
||||
void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
|
||||
int (*cb)
|
||||
(struct mii_bus *bus,
|
||||
--- a/drivers/net/phy/mdio_bus.c
|
||||
+++ b/drivers/net/phy/mdio_bus.c
|
||||
@@ -88,6 +88,8 @@ bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_is_registered_device);
|
||||
|
||||
+#include "mdio-boardinfo.h"
|
||||
+
|
||||
/**
|
||||
* mdiobus_alloc_size - allocate a mii_bus structure
|
||||
* @size: extra amount of memory to allocate for private storage.
|
||||
@@ -455,6 +457,17 @@ void mdiobus_free(struct mii_bus *bus)
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_free);
|
||||
|
||||
+static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus,
|
||||
+ struct phy_device *phydev,
|
||||
+ struct mdio_board_info *bi)
|
||||
+{
|
||||
+ if (strcmp(bus->id, bi->bus_id) ||
|
||||
+ bi->mdio_addr != phydev->mdio.addr)
|
||||
+ return;
|
||||
+
|
||||
+ phydev->mdio.dev.platform_data = (void *) bi->platform_data;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* mdiobus_scan - scan a bus for MDIO devices.
|
||||
* @bus: mii_bus to scan
|
||||
@@ -470,6 +483,7 @@ EXPORT_SYMBOL(mdiobus_free);
|
||||
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
+ struct mdio_board_entry *be;
|
||||
int err;
|
||||
|
||||
phydev = get_phy_device(bus, addr, false);
|
||||
@@ -482,6 +496,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
|
||||
*/
|
||||
of_mdiobus_link_mdiodev(bus, &phydev->mdio);
|
||||
|
||||
+ mutex_lock(&mdio_board_lock);
|
||||
+ list_for_each_entry(be, &mdio_board_list, list)
|
||||
+ mdiobus_setup_phydev_from_boardinfo(bus, phydev,
|
||||
+ &be->board_info);
|
||||
+ mutex_unlock(&mdio_board_lock);
|
||||
+
|
||||
err = phy_device_register(phydev);
|
||||
if (err) {
|
||||
phy_device_free(phydev);
|
@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
*/
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -2492,6 +2492,10 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
|
||||
@@ -2491,6 +2491,10 @@ static inline int pskb_trim(struct sk_bu
|
||||
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/**
|
||||
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
|
||||
* @skb: buffer to alter
|
||||
@@ -2622,16 +2626,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
|
||||
@@ -2621,16 +2625,6 @@ static inline struct sk_buff *dev_alloc_
|
||||
}
|
||||
|
||||
|
||||
@ -101,9 +101,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
help
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -2988,10 +2988,20 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
}
|
||||
@@ -2982,10 +2982,20 @@ static int xmit_one(struct sk_buff *skb,
|
||||
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
|
||||
- len = skb->len;
|
||||
- trace_net_dev_start_xmit(skb, dev);
|
||||
@ -136,7 +136,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
#include <net/protocol.h>
|
||||
#include <net/dst.h>
|
||||
@@ -499,6 +500,22 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len,
|
||||
@@ -499,6 +500,22 @@ skb_fail:
|
||||
}
|
||||
EXPORT_SYMBOL(__napi_alloc_skb);
|
||||
|
||||
@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
{
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
|
||||
@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *sk
|
||||
const struct ethhdr *eth;
|
||||
|
||||
skb->dev = dev;
|
||||
|
@ -14,7 +14,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
|
||||
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||
@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_device *core)
|
||||
@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic
|
||||
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
|
||||
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
|
||||
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
|
||||
|
@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/fs/locks.c
|
||||
+++ b/fs/locks.c
|
||||
@@ -2805,6 +2805,8 @@ static const struct file_operations proc_locks_operations = {
|
||||
@@ -2805,6 +2805,8 @@ static const struct file_operations proc
|
||||
|
||||
static int __init proc_locks_init(void)
|
||||
{
|
||||
@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ bool "Strip non-essential /proc functionality to reduce code size"
|
||||
--- a/fs/proc/consoles.c
|
||||
+++ b/fs/proc/consoles.c
|
||||
@@ -106,6 +106,9 @@ static const struct file_operations proc_consoles_operations = {
|
||||
@@ -106,6 +106,9 @@ static const struct file_operations proc
|
||||
|
||||
static int __init proc_consoles_init(void)
|
||||
{
|
||||
@ -63,7 +63,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
--- a/fs/proc/proc_tty.c
|
||||
+++ b/fs/proc/proc_tty.c
|
||||
@@ -145,7 +145,10 @@ static const struct file_operations proc_tty_drivers_operations = {
|
||||
@@ -145,7 +145,10 @@ static const struct file_operations proc
|
||||
void proc_tty_register_driver(struct tty_driver *driver)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (!driver->driver_name || driver->proc_entry ||
|
||||
!driver->ops->proc_fops)
|
||||
return;
|
||||
@@ -162,6 +165,9 @@ void proc_tty_unregister_driver(struct tty_driver *driver)
|
||||
@@ -162,6 +165,9 @@ void proc_tty_unregister_driver(struct t
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
@ -85,7 +85,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
ent = driver->proc_entry;
|
||||
if (!ent)
|
||||
return;
|
||||
@@ -176,6 +182,9 @@ void proc_tty_unregister_driver(struct tty_driver *driver)
|
||||
@@ -176,6 +182,9 @@ void proc_tty_unregister_driver(struct t
|
||||
*/
|
||||
void __init proc_tty_init(void)
|
||||
{
|
||||
@ -166,7 +166,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
" key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
|
||||
--- a/ipc/util.c
|
||||
+++ b/ipc/util.c
|
||||
@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
||||
@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons
|
||||
struct proc_dir_entry *pde;
|
||||
struct ipc_proc_iface *iface;
|
||||
|
||||
@ -178,7 +178,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
return;
|
||||
--- a/kernel/exec_domain.c
|
||||
+++ b/kernel/exec_domain.c
|
||||
@@ -42,6 +42,8 @@ static const struct file_operations execdomains_proc_fops = {
|
||||
@@ -42,6 +42,8 @@ static const struct file_operations exec
|
||||
|
||||
static int __init proc_execdomains_init(void)
|
||||
{
|
||||
@ -189,7 +189,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
--- a/kernel/irq/proc.c
|
||||
+++ b/kernel/irq/proc.c
|
||||
@@ -396,6 +396,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
|
||||
@@ -396,6 +396,9 @@ void register_irq_proc(unsigned int irq,
|
||||
void __maybe_unused *irqp = (void *)(unsigned long) irq;
|
||||
char name [MAX_NAMELEN];
|
||||
|
||||
@ -199,7 +199,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
|
||||
return;
|
||||
|
||||
@@ -449,6 +452,9 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
|
||||
@@ -449,6 +452,9 @@ void unregister_irq_proc(unsigned int ir
|
||||
{
|
||||
char name [MAX_NAMELEN];
|
||||
|
||||
@ -221,7 +221,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (!root_irq_dir)
|
||||
--- a/kernel/time/timer_list.c
|
||||
+++ b/kernel/time/timer_list.c
|
||||
@@ -389,6 +389,8 @@ static int __init init_timer_list_procfs(void)
|
||||
@@ -389,6 +389,8 @@ static int __init init_timer_list_procfs
|
||||
{
|
||||
struct proc_dir_entry *pe;
|
||||
|
||||
@ -232,7 +232,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
return -ENOMEM;
|
||||
--- a/mm/vmalloc.c
|
||||
+++ b/mm/vmalloc.c
|
||||
@@ -2769,6 +2769,8 @@ static const struct file_operations proc_vmalloc_operations = {
|
||||
@@ -2769,6 +2769,8 @@ static const struct file_operations proc
|
||||
|
||||
static int __init proc_vmalloc_init(void)
|
||||
{
|
||||
@ -271,7 +271,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (vn->proc_vlan_conf)
|
||||
remove_proc_entry(name_conf, vn->proc_vlan_dir);
|
||||
|
||||
@@ -146,6 +149,9 @@ int __net_init vlan_proc_init(struct net *net)
|
||||
@@ -146,6 +149,9 @@ int __net_init vlan_proc_init(struct net
|
||||
{
|
||||
struct vlan_net *vn = net_generic(net, vlan_net_id);
|
||||
|
||||
@ -283,7 +283,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
goto err;
|
||||
--- a/net/core/net-procfs.c
|
||||
+++ b/net/core/net-procfs.c
|
||||
@@ -320,10 +320,12 @@ static int __net_init dev_proc_net_init(struct net *net)
|
||||
@@ -320,10 +320,12 @@ static int __net_init dev_proc_net_init(
|
||||
|
||||
if (!proc_create("dev", S_IRUGO, net->proc_net, &dev_seq_fops))
|
||||
goto out;
|
||||
@ -298,7 +298,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
goto out_softnet;
|
||||
|
||||
if (wext_proc_init(net))
|
||||
@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init(struct net *net)
|
||||
@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init(
|
||||
out:
|
||||
return rc;
|
||||
out_ptype:
|
||||
@ -312,7 +312,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
out_dev:
|
||||
remove_proc_entry("dev", net->proc_net);
|
||||
goto out;
|
||||
@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit(struct net *net)
|
||||
@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit
|
||||
{
|
||||
wext_proc_exit(net);
|
||||
|
||||
@ -327,7 +327,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -3378,6 +3378,8 @@ static __net_initdata struct pernet_operations proto_net_ops = {
|
||||
@@ -3378,6 +3378,8 @@ static __net_initdata struct pernet_oper
|
||||
|
||||
static int __init proto_init(void)
|
||||
{
|
||||
@ -338,7 +338,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/ipv4/fib_trie.c
|
||||
+++ b/net/ipv4/fib_trie.c
|
||||
@@ -2731,10 +2731,12 @@ static const struct file_operations fib_route_fops = {
|
||||
@@ -2731,10 +2731,12 @@ static const struct file_operations fib_
|
||||
|
||||
int __net_init fib_proc_init(struct net *net)
|
||||
{
|
||||
@ -353,7 +353,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
&fib_triestat_fops))
|
||||
goto out2;
|
||||
|
||||
@@ -2744,17 +2746,21 @@ int __net_init fib_proc_init(struct net *net)
|
||||
@@ -2744,17 +2746,21 @@ int __net_init fib_proc_init(struct net
|
||||
return 0;
|
||||
|
||||
out3:
|
||||
@ -381,7 +381,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/ipv4/proc.c
|
||||
+++ b/net/ipv4/proc.c
|
||||
@@ -557,6 +557,9 @@ static __net_initdata struct pernet_operations ip_proc_ops = {
|
||||
@@ -557,6 +557,9 @@ static __net_initdata struct pernet_oper
|
||||
|
||||
int __init ip_misc_proc_init(void)
|
||||
{
|
||||
@ -393,7 +393,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/ipv4/route.c
|
||||
+++ b/net/ipv4/route.c
|
||||
@@ -427,6 +427,9 @@ static struct pernet_operations ip_rt_proc_ops __net_initdata = {
|
||||
@@ -427,6 +427,9 @@ static struct pernet_operations ip_rt_pr
|
||||
|
||||
static int __init ip_rt_proc_init(void)
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -199,10 +199,16 @@ int flow_offload_add(struct nf_flowtable
|
||||
@@ -218,10 +218,16 @@ int flow_offload_add(struct nf_flowtable
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(flow_offload_add);
|
||||
|
||||
@ -173,9 +173,9 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
rhashtable_remove_fast(&flow_table->rhashtable,
|
||||
&flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
|
||||
@@ -214,6 +220,9 @@ static void flow_offload_del(struct nf_f
|
||||
e = container_of(flow, struct flow_offload_entry, flow);
|
||||
clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);
|
||||
@@ -236,6 +242,9 @@ static void flow_offload_del(struct nf_f
|
||||
if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
|
||||
flow_offload_fixup_ct_state(e->ct);
|
||||
|
||||
+ if (nf_flow_in_hw(flow))
|
||||
+ nf_flow_offload_hw_del(net, flow);
|
||||
@ -183,32 +183,17 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
flow_offload_free(flow);
|
||||
}
|
||||
|
||||
@@ -307,6 +316,7 @@ static int nf_flow_offload_gc_step(struc
|
||||
rhashtable_walk_start(&hti);
|
||||
@@ -349,6 +358,9 @@ static int nf_flow_offload_gc_step(struc
|
||||
if (!teardown)
|
||||
nf_ct_offload_timeout(flow);
|
||||
|
||||
while ((tuplehash = rhashtable_walk_next(&hti))) {
|
||||
+ bool teardown;
|
||||
if (IS_ERR(tuplehash)) {
|
||||
err = PTR_ERR(tuplehash);
|
||||
if (err != -EAGAIN)
|
||||
@@ -319,9 +329,13 @@ static int nf_flow_offload_gc_step(struc
|
||||
|
||||
flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);
|
||||
|
||||
- if (nf_flow_has_expired(flow) ||
|
||||
- (flow->flags & (FLOW_OFFLOAD_DYING |
|
||||
- FLOW_OFFLOAD_TEARDOWN)))
|
||||
+ teardown = flow->flags & (FLOW_OFFLOAD_DYING |
|
||||
+ FLOW_OFFLOAD_TEARDOWN);
|
||||
+
|
||||
+ if (nf_flow_in_hw(flow) && !teardown)
|
||||
+ continue;
|
||||
+
|
||||
+ if (nf_flow_has_expired(flow) || teardown)
|
||||
if (nf_flow_has_expired(flow) || teardown)
|
||||
flow_offload_del(flow_table, flow);
|
||||
}
|
||||
out:
|
||||
@@ -456,10 +470,43 @@ int nf_flow_dnat_port(const struct flow_
|
||||
@@ -484,10 +496,43 @@ int nf_flow_dnat_port(const struct flow_
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
|
||||
|
||||
@ -252,7 +237,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
|
||||
|
||||
err = rhashtable_init(&flowtable->rhashtable,
|
||||
@@ -497,6 +544,8 @@ static void nf_flow_table_iterate_cleanu
|
||||
@@ -525,6 +570,8 @@ static void nf_flow_table_iterate_cleanu
|
||||
{
|
||||
nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
|
||||
flush_delayed_work(&flowtable->gc_work);
|
||||
@ -261,7 +246,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
}
|
||||
|
||||
void nf_flow_table_cleanup(struct net *net, struct net_device *dev)
|
||||
@@ -510,6 +559,26 @@ void nf_flow_table_cleanup(struct net *n
|
||||
@@ -538,6 +585,26 @@ void nf_flow_table_cleanup(struct net *n
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_flow_table_cleanup);
|
||||
|
||||
@ -288,7 +273,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
void nf_flow_table_free(struct nf_flowtable *flow_table)
|
||||
{
|
||||
mutex_lock(&flowtable_lock);
|
||||
@@ -519,9 +588,58 @@ void nf_flow_table_free(struct nf_flowta
|
||||
@@ -547,9 +614,58 @@ void nf_flow_table_free(struct nf_flowta
|
||||
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
|
||||
WARN_ON(!nf_flow_offload_gc_step(flow_table));
|
||||
rhashtable_destroy(&flow_table->rhashtable);
|
||||
|
@ -26,9 +26,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX];
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -332,7 +332,7 @@ static int nf_flow_offload_gc_step(struc
|
||||
teardown = flow->flags & (FLOW_OFFLOAD_DYING |
|
||||
FLOW_OFFLOAD_TEARDOWN);
|
||||
@@ -358,7 +358,7 @@ static int nf_flow_offload_gc_step(struc
|
||||
if (!teardown)
|
||||
nf_ct_offload_timeout(flow);
|
||||
|
||||
- if (nf_flow_in_hw(flow) && !teardown)
|
||||
+ if ((flow->flags & FLOW_OFFLOAD_KEEP) && !teardown)
|
||||
|
@ -0,0 +1,25 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 27 Apr 2018 14:42:14 +0200
|
||||
Subject: [PATCH] netfilter: nf_flow_table: rework private driver data
|
||||
|
||||
Move the timeout out of the union, since it can be shared between the
|
||||
driver and the stack. Add a private pointer that the driver can use to
|
||||
point to its own data structures
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/netfilter/nf_flow_table.h
|
||||
+++ b/include/net/netfilter/nf_flow_table.h
|
||||
@@ -81,9 +81,10 @@ struct flow_offload_tuple_rhash {
|
||||
struct flow_offload {
|
||||
struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX];
|
||||
u32 flags;
|
||||
+ u32 timeout;
|
||||
union {
|
||||
/* Your private driver data here. */
|
||||
- u32 timeout;
|
||||
+ void *priv;
|
||||
};
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
|
||||
return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
|
||||
}
|
||||
@@ -141,20 +143,29 @@ static struct net_device_stats *ip6_get_stats(struct net_device *dev)
|
||||
@@ -141,20 +143,29 @@ static struct net_device_stats *ip6_get_
|
||||
static struct ip6_tnl *
|
||||
ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_addr *local)
|
||||
{
|
||||
@ -125,7 +125,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
|
||||
if (ipv6_addr_equal(local, &t->parms.laddr) &&
|
||||
ipv6_addr_any(&t->parms.raddr) &&
|
||||
@@ -162,7 +173,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
|
||||
@@ -162,7 +173,7 @@ ip6_tnl_lookup(struct net *net, const st
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
|
||||
if (ipv6_addr_equal(remote, &t->parms.raddr) &&
|
||||
ipv6_addr_any(&t->parms.laddr) &&
|
||||
@@ -202,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, const struct __ip6_tnl_parm *p)
|
||||
@@ -202,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n,
|
||||
|
||||
if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
|
||||
prio = 1;
|
||||
@ -143,7 +143,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
}
|
||||
return &ip6n->tnls[prio][h];
|
||||
}
|
||||
@@ -383,6 +394,12 @@ ip6_tnl_dev_uninit(struct net_device *dev)
|
||||
@@ -383,6 +394,12 @@ ip6_tnl_dev_uninit(struct net_device *de
|
||||
struct net *net = t->net;
|
||||
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||
|
||||
@ -264,7 +264,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
|
||||
const struct tnl_ptk_info *tpi,
|
||||
struct metadata_dst *tun_dst,
|
||||
@@ -831,6 +949,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
|
||||
@@ -831,6 +949,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl
|
||||
skb_reset_network_header(skb);
|
||||
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
|
||||
|
||||
@ -292,7 +292,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
__skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
|
||||
|
||||
err = dscp_ecn_decapsulate(tunnel, ipv6h, skb);
|
||||
@@ -962,6 +1101,7 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
|
||||
@@ -962,6 +1101,7 @@ static void init_tel_txopt(struct ipv6_t
|
||||
opt->ops.opt_nflen = 8;
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
/**
|
||||
* ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
|
||||
* @t: the outgoing tunnel device
|
||||
@@ -1303,6 +1443,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
@@ -1303,6 +1443,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
|
||||
{
|
||||
struct ip6_tnl *t = netdev_priv(dev);
|
||||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
@ -308,7 +308,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
int encap_limit = -1;
|
||||
__u16 offset;
|
||||
struct flowi6 fl6;
|
||||
@@ -1365,6 +1506,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
@@ -1365,6 +1506,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
|
||||
|
||||
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
||||
|
||||
@ -327,7 +327,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
|
||||
return -1;
|
||||
|
||||
@@ -1493,6 +1646,14 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
|
||||
@@ -1493,6 +1646,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
|
||||
t->parms.link = p->link;
|
||||
t->parms.proto = p->proto;
|
||||
t->parms.fwmark = p->fwmark;
|
||||
@ -342,7 +342,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
dst_cache_reset(&t->dst_cache);
|
||||
ip6_tnl_link_config(t);
|
||||
return 0;
|
||||
@@ -1531,6 +1692,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm *u)
|
||||
@@ -1531,6 +1692,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
|
||||
p->flowinfo = u->flowinfo;
|
||||
p->link = u->link;
|
||||
p->proto = u->proto;
|
||||
@ -350,7 +350,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
memcpy(p->name, u->name, sizeof(u->name));
|
||||
}
|
||||
|
||||
@@ -1912,6 +2074,15 @@ static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||
@@ -1912,6 +2074,15 @@ static int ip6_tnl_validate(struct nlatt
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -366,7 +366,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||
static void ip6_tnl_netlink_parms(struct nlattr *data[],
|
||||
struct __ip6_tnl_parm *parms)
|
||||
{
|
||||
@@ -1949,6 +2120,46 @@ static void ip6_tnl_netlink_parms(struct nlattr *data[],
|
||||
@@ -1949,6 +2120,46 @@ static void ip6_tnl_netlink_parms(struct
|
||||
|
||||
if (data[IFLA_IPTUN_FWMARK])
|
||||
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
|
||||
|
@ -9,11 +9,11 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -382,6 +382,74 @@ void phy_ethtool_ksettings_get(struct phy_device *phydev,
|
||||
@@ -382,6 +382,73 @@ void phy_ethtool_ksettings_get(struct ph
|
||||
}
|
||||
EXPORT_SYMBOL(phy_ethtool_ksettings_get);
|
||||
|
||||
+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
|
||||
+static int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
|
||||
+{
|
||||
+ cmd->supported = phydev->supported;
|
||||
+
|
||||
@ -35,7 +35,6 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(phy_ethtool_gset);
|
||||
+
|
||||
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
|
||||
+{
|
||||
@ -86,12 +85,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||
* @phydev: the phy_device struct
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -901,10 +901,12 @@ void phy_start_machine(struct phy_device *phydev);
|
||||
void phy_stop_machine(struct phy_device *phydev);
|
||||
void phy_trigger_machine(struct phy_device *phydev, bool sync);
|
||||
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||
+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||
void phy_ethtool_ksettings_get(struct phy_device *phydev,
|
||||
@@ -905,6 +905,7 @@ void phy_ethtool_ksettings_get(struct ph
|
||||
struct ethtool_link_ksettings *cmd);
|
||||
int phy_ethtool_ksettings_set(struct phy_device *phydev,
|
||||
const struct ethtool_link_ksettings *cmd);
|
||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
#endif /* __LINUX_USB_PCI_QUIRKS_H */
|
||||
--- a/include/linux/usb/hcd.h
|
||||
+++ b/include/linux/usb/hcd.h
|
||||
@@ -465,7 +465,14 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev,
|
||||
@@ -465,7 +465,14 @@ extern int usb_hcd_pci_probe(struct pci_
|
||||
extern void usb_hcd_pci_remove(struct pci_dev *dev);
|
||||
extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
|
||||
|
||||
|
@ -1,393 +0,0 @@
|
||||
--- a/include/linux/if_bridge.h
|
||||
+++ b/include/linux/if_bridge.h
|
||||
@@ -53,6 +53,7 @@ struct br_ip_list {
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||
+extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
|
||||
|
||||
typedef int br_should_route_hook_t(struct sk_buff *skb);
|
||||
extern br_should_route_hook_t __rcu *br_should_route_hook;
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -767,6 +767,7 @@ struct sk_buff {
|
||||
#endif
|
||||
__u8 ipvs_property:1;
|
||||
__u8 inner_protocol_type:1;
|
||||
+ __u8 fast_forwarded:1;
|
||||
__u8 remcsum_offload:1;
|
||||
#ifdef CONFIG_NET_SWITCHDEV
|
||||
__u8 offload_fwd_mark:1;
|
||||
--- a/include/net/netfilter/nf_conntrack_ecache.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_ecache.h
|
||||
@@ -71,14 +71,8 @@ struct nf_ct_event {
|
||||
int report;
|
||||
};
|
||||
|
||||
-struct nf_ct_event_notifier {
|
||||
- int (*fcn)(unsigned int events, struct nf_ct_event *item);
|
||||
-};
|
||||
-
|
||||
-int nf_conntrack_register_notifier(struct net *net,
|
||||
- struct nf_ct_event_notifier *nb);
|
||||
-void nf_conntrack_unregister_notifier(struct net *net,
|
||||
- struct nf_ct_event_notifier *nb);
|
||||
+extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
|
||||
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct);
|
||||
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
@@ -87,12 +81,8 @@ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
static inline void
|
||||
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
{
|
||||
- struct net *net = nf_ct_net(ct);
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
- if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
- return;
|
||||
-
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
return;
|
||||
@@ -104,22 +94,12 @@ static inline int
|
||||
nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
|
||||
u32 portid, int report)
|
||||
{
|
||||
- const struct net *net = nf_ct_net(ct);
|
||||
-
|
||||
- if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
- return 0;
|
||||
-
|
||||
return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
{
|
||||
- const struct net *net = nf_ct_net(ct);
|
||||
-
|
||||
- if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
- return 0;
|
||||
-
|
||||
return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
|
||||
}
|
||||
|
||||
--- a/include/net/netns/conntrack.h
|
||||
+++ b/include/net/netns/conntrack.h
|
||||
@@ -114,7 +114,7 @@ struct netns_ct {
|
||||
|
||||
struct ct_pcpu __percpu *pcpu_lists;
|
||||
struct ip_conntrack_stat __percpu *stat;
|
||||
- struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
|
||||
+ struct atomic_notifier_head nf_conntrack_chain;
|
||||
struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
|
||||
struct nf_ip_net nf_ct_proto;
|
||||
#if defined(CONFIG_NF_CONNTRACK_LABELS)
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -654,3 +654,27 @@ void br_port_flags_change(struct net_bridge_port *p, unsigned long mask)
|
||||
if (mask & BR_AUTO_MASK)
|
||||
nbp_update_port_count(br);
|
||||
}
|
||||
+
|
||||
+/* Update bridge statistics for bridge packets processed by offload engines */
|
||||
+void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
|
||||
+{
|
||||
+ struct net_bridge *br;
|
||||
+ struct pcpu_sw_netstats *stats;
|
||||
+
|
||||
+ /*
|
||||
+ * Is this a bridge?
|
||||
+ */
|
||||
+ if (!(dev->priv_flags & IFF_EBRIDGE))
|
||||
+ return;
|
||||
+
|
||||
+ br = netdev_priv(dev);
|
||||
+ stats = per_cpu_ptr(br->stats, 0);
|
||||
+
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ stats->rx_packets += nlstats->rx_packets;
|
||||
+ stats->rx_bytes += nlstats->rx_bytes;
|
||||
+ stats->tx_packets += nlstats->tx_packets;
|
||||
+ stats->tx_bytes += nlstats->tx_bytes;
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -2979,8 +2979,14 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
unsigned int len;
|
||||
int rc;
|
||||
|
||||
- if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
|
||||
- dev_queue_xmit_nit(skb, dev);
|
||||
+ /*
|
||||
+ * If this skb has been fast forwarded then we don't want it to
|
||||
+ * go to any taps (by definition we're trying to bypass them).
|
||||
+ */
|
||||
+ if (!skb->fast_forwarded) {
|
||||
+ if (!list_empty(&ptype_all))
|
||||
+ dev_queue_xmit_nit(skb, dev);
|
||||
+ }
|
||||
|
||||
len = skb->len;
|
||||
trace_net_dev_start_xmit(skb, dev);
|
||||
@@ -4282,6 +4288,9 @@ void netdev_rx_handler_unregister(struct net_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
|
||||
|
||||
+int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
|
||||
+EXPORT_SYMBOL_GPL(fast_nat_recv);
|
||||
+
|
||||
/*
|
||||
* Limit the use of PFMEMALLOC reserves to those protocols that implement
|
||||
* the special handling of PFMEMALLOC skbs.
|
||||
@@ -4329,6 +4338,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
|
||||
bool deliver_exact = false;
|
||||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
+ int (*fast_recv)(struct sk_buff *skb);
|
||||
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
|
||||
@@ -4355,6 +4365,12 @@ another_round:
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ fast_recv = rcu_dereference(fast_nat_recv);
|
||||
+ if (fast_recv && fast_recv(skb)) {
|
||||
+ ret = NET_RX_SUCCESS;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (skb_skip_tc_classify(skb))
|
||||
goto skip_classify;
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -2187,6 +2187,7 @@ int nf_conntrack_init_net(struct net *net)
|
||||
ret = nf_conntrack_proto_pernet_init(net);
|
||||
if (ret < 0)
|
||||
goto err_proto;
|
||||
+ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
|
||||
return 0;
|
||||
|
||||
err_proto:
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/percpu.h>
|
||||
+#include <linux/notifier.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -120,19 +121,13 @@ static void ecache_work(struct work_struct *work)
|
||||
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
u32 portid, int report)
|
||||
{
|
||||
- int ret = 0;
|
||||
- struct net *net = nf_ct_net(ct);
|
||||
- struct nf_ct_event_notifier *notify;
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
- rcu_read_lock();
|
||||
- notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
- if (!notify)
|
||||
- goto out_unlock;
|
||||
+ struct net *net = nf_ct_net(ct);
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
- goto out_unlock;
|
||||
+ return 0;
|
||||
|
||||
if (nf_ct_is_confirmed(ct)) {
|
||||
struct nf_ct_event item = {
|
||||
@@ -144,32 +139,11 @@ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
unsigned long missed = e->portid ? 0 : e->missed;
|
||||
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
- goto out_unlock;
|
||||
-
|
||||
- ret = notify->fcn(eventmask | missed, &item);
|
||||
- if (unlikely(ret < 0 || missed)) {
|
||||
- spin_lock_bh(&ct->lock);
|
||||
- if (ret < 0) {
|
||||
- /* This is a destroy event that has been
|
||||
- * triggered by a process, we store the PORTID
|
||||
- * to include it in the retransmission.
|
||||
- */
|
||||
- if (eventmask & (1 << IPCT_DESTROY)) {
|
||||
- if (e->portid == 0 && portid != 0)
|
||||
- e->portid = portid;
|
||||
- e->state = NFCT_ECACHE_DESTROY_FAIL;
|
||||
- } else {
|
||||
- e->missed |= eventmask;
|
||||
- }
|
||||
- } else {
|
||||
- e->missed &= ~missed;
|
||||
- }
|
||||
- spin_unlock_bh(&ct->lock);
|
||||
- }
|
||||
+ return 0;
|
||||
+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
|
||||
}
|
||||
-out_unlock:
|
||||
- rcu_read_unlock();
|
||||
- return ret;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
|
||||
|
||||
@@ -177,26 +151,19 @@ EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
|
||||
* disabled softirqs */
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
{
|
||||
- struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
- struct nf_ct_event_notifier *notify;
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
- int ret;
|
||||
-
|
||||
- rcu_read_lock();
|
||||
- notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
- if (notify == NULL)
|
||||
- goto out_unlock;
|
||||
+ struct net *net = nf_ct_net(ct);
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
- goto out_unlock;
|
||||
+ return;
|
||||
|
||||
events = xchg(&e->cache, 0);
|
||||
|
||||
if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct))
|
||||
- goto out_unlock;
|
||||
+ return;
|
||||
|
||||
/* We make a copy of the missed event cache without taking
|
||||
* the lock, thus we may send missed events twice. However,
|
||||
@@ -204,26 +171,22 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
missed = e->missed;
|
||||
|
||||
if (!((events | missed) & e->ctmask))
|
||||
- goto out_unlock;
|
||||
+ return;
|
||||
|
||||
item.ct = ct;
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
- ret = notify->fcn(events | missed, &item);
|
||||
+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
|
||||
- if (likely(ret == 0 && !missed))
|
||||
- goto out_unlock;
|
||||
+ if (likely(!missed))
|
||||
+ return;
|
||||
|
||||
spin_lock_bh(&ct->lock);
|
||||
- if (ret < 0)
|
||||
- e->missed |= events;
|
||||
- else
|
||||
- e->missed &= ~missed;
|
||||
+ e->missed &= ~missed;
|
||||
spin_unlock_bh(&ct->lock);
|
||||
-
|
||||
-out_unlock:
|
||||
- rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
|
||||
|
||||
@@ -257,40 +220,15 @@ void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
-int nf_conntrack_register_notifier(struct net *net,
|
||||
- struct nf_ct_event_notifier *new)
|
||||
+int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
- int ret;
|
||||
- struct nf_ct_event_notifier *notify;
|
||||
-
|
||||
- mutex_lock(&nf_ct_ecache_mutex);
|
||||
- notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
|
||||
- lockdep_is_held(&nf_ct_ecache_mutex));
|
||||
- if (notify != NULL) {
|
||||
- ret = -EBUSY;
|
||||
- goto out_unlock;
|
||||
- }
|
||||
- rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
|
||||
- ret = 0;
|
||||
-
|
||||
-out_unlock:
|
||||
- mutex_unlock(&nf_ct_ecache_mutex);
|
||||
- return ret;
|
||||
+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
|
||||
|
||||
-void nf_conntrack_unregister_notifier(struct net *net,
|
||||
- struct nf_ct_event_notifier *new)
|
||||
+int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
- struct nf_ct_event_notifier *notify;
|
||||
-
|
||||
- mutex_lock(&nf_ct_ecache_mutex);
|
||||
- notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
|
||||
- lockdep_is_held(&nf_ct_ecache_mutex));
|
||||
- BUG_ON(notify != new);
|
||||
- RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
|
||||
- mutex_unlock(&nf_ct_ecache_mutex);
|
||||
- /* synchronize_rcu() is called from ctnetlink_exit. */
|
||||
+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_netlink.c
|
||||
+++ b/net/netfilter/nf_conntrack_netlink.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
+#include <linux/notifier.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
@@ -618,14 +619,15 @@ static size_t ctnetlink_nlmsg_size(const struct nf_conn *ct)
|
||||
;
|
||||
}
|
||||
|
||||
-static int
|
||||
-ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
|
||||
+static int ctnetlink_conntrack_event(struct notifier_block *this,
|
||||
+ unsigned long events, void *ptr)
|
||||
{
|
||||
const struct nf_conntrack_zone *zone;
|
||||
struct net *net;
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfmsg;
|
||||
struct nlattr *nest_parms;
|
||||
+ struct nf_ct_event *item = ptr;
|
||||
struct nf_conn *ct = item->ct;
|
||||
struct sk_buff *skb;
|
||||
unsigned int type;
|
||||
@@ -3303,8 +3305,8 @@ static int ctnetlink_stat_exp_cpu(struct net *net, struct sock *ctnl,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
-static struct nf_ct_event_notifier ctnl_notifier = {
|
||||
- .fcn = ctnetlink_conntrack_event,
|
||||
+static struct notifier_block ctnl_notifier = {
|
||||
+ .notifier_call = ctnetlink_conntrack_event,
|
||||
};
|
||||
|
||||
static struct nf_exp_event_notifier ctnl_notifier_exp = {
|
@ -1,10 +0,0 @@
|
||||
--- a/net/netfilter/nf_conntrack_proto_tcp.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
/* Do not check the TCP window for incoming packets */
|
||||
static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
|
||||
|
||||
/* "Be conservative in what you do,
|
||||
be liberal in what you accept from others."
|
Loading…
Reference in New Issue
Block a user