* [PATCH 07/47] netfilter: x_tables: check standard verdicts in core
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
Userspace must provide a valid verdict to the standard target.
The verdict can be either a jump (signed int > 0), or a return code.
Allowed return codes are either RETURN (pop from stack), NF_ACCEPT, DROP
and QUEUE (latter is allowed for legacy reasons).
Jump offsets (verdict > 0) are checked in more detail later on when
loop-detection is performed.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/arp_tables.c | 5 -----
net/ipv4/netfilter/ip_tables.c | 5 -----
net/ipv6/netfilter/ip6_tables.c | 5 -----
net/netfilter/x_tables.c | 49 ++++++++++++++++++++++++++++++++++++-----
4 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index a0c7ce76879c..c9ffa884a4ee 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -334,11 +334,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
t->verdict < 0) || visited) {
unsigned int oldpos, size;
- if ((strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1)
- return 0;
-
/* Return: backtrack through the last
* big jump.
*/
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4f7153e25e0b..c9b57a6bf96a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -402,11 +402,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
t->verdict < 0) || visited) {
unsigned int oldpos, size;
- if ((strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1)
- return 0;
-
/* Return: backtrack through the last
big jump. */
do {
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 6c44033decab..f46954221933 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -420,11 +420,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
t->verdict < 0) || visited) {
unsigned int oldpos, size;
- if ((strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1)
- return 0;
-
/* Return: backtrack through the last
big jump. */
do {
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index d9deebe599ec..2e4d423e58e6 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -654,6 +654,31 @@ struct compat_xt_standard_target {
compat_uint_t verdict;
};
+static bool verdict_ok(int verdict)
+{
+ if (verdict > 0)
+ return true;
+
+ if (verdict < 0) {
+ int v = -verdict - 1;
+
+ if (verdict == XT_RETURN)
+ return true;
+
+ switch (v) {
+ case NF_ACCEPT: return true;
+ case NF_DROP: return true;
+ case NF_QUEUE: return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
int xt_compat_check_entry_offsets(const void *base, const char *elems,
unsigned int target_offset,
unsigned int next_offset)
@@ -675,9 +700,15 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
if (target_offset + t->u.target_size > next_offset)
return -EINVAL;
- if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
- COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
- return -EINVAL;
+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0) {
+ const struct compat_xt_standard_target *st = (const void *)t;
+
+ if (COMPAT_XT_ALIGN(target_offset + sizeof(*st)) != next_offset)
+ return -EINVAL;
+
+ if (!verdict_ok(st->verdict))
+ return -EINVAL;
+ }
/* compat_xt_entry match has less strict alignment requirements,
* otherwise they are identical. In case of padding differences
@@ -757,9 +788,15 @@ int xt_check_entry_offsets(const void *base,
if (target_offset + t->u.target_size > next_offset)
return -EINVAL;
- if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
- XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
- return -EINVAL;
+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0) {
+ const struct xt_standard_target *st = (const void *)t;
+
+ if (XT_ALIGN(target_offset + sizeof(*st)) != next_offset)
+ return -EINVAL;
+
+ if (!verdict_ok(st->verdict))
+ return -EINVAL;
+ }
return xt_check_entry_match(elems, base + target_offset,
__alignof__(struct xt_entry_match));
--
2.11.0
^ permalink raw reply related
* [PATCH 06/47] netfilter: unlock xt_table earlier in __do_replace
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: Xin Long <lucien.xin@gmail.com>
Now it's doing cleanup_entry for oldinfo under the xt_table lock,
but it's not really necessary. After the replacement job is done
in xt_replace_table, oldinfo is not used elsewhere any more, and
it can be freed without xt_table lock safely.
The important thing is that rtnl_lock is called in some xt_target
destroy, which means rtnl_lock, a big lock is used in xt_table
lock, a smaller one. It usually could be the reason why a dead
lock may happen.
Besides, all xt_target/match checkentry is called out of xt_table
lock. It's better also to move all cleanup_entry calling out of
xt_table lock, just as do_replace_finish does for ebtables.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/arp_tables.c | 3 ++-
net/ipv4/netfilter/ip_tables.c | 3 ++-
net/ipv6/netfilter/ip6_tables.c | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index c36ffce3c812..a0c7ce76879c 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -925,6 +925,8 @@ static int __do_replace(struct net *net, const char *name,
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
+ xt_table_unlock(t);
+
get_old_counters(oldinfo, counters);
/* Decrease module usage counts and free resource */
@@ -939,7 +941,6 @@ static int __do_replace(struct net *net, const char *name,
net_warn_ratelimited("arptables: counters copy to user failed while replacing table\n");
}
vfree(counters);
- xt_table_unlock(t);
return ret;
put_module:
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index d4f7584d2dbe..4f7153e25e0b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1087,6 +1087,8 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
+ xt_table_unlock(t);
+
get_old_counters(oldinfo, counters);
/* Decrease module usage counts and free resource */
@@ -1100,7 +1102,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
}
vfree(counters);
- xt_table_unlock(t);
return ret;
put_module:
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 4de8ac1e5af4..6c44033decab 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1105,6 +1105,8 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
+ xt_table_unlock(t);
+
get_old_counters(oldinfo, counters);
/* Decrease module usage counts and free resource */
@@ -1118,7 +1120,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
}
vfree(counters);
- xt_table_unlock(t);
return ret;
put_module:
--
2.11.0
^ permalink raw reply related
* [PATCH 05/47] netfilter: ipt_ah: return boolean instead of integer
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: "Gustavo A. R. Silva" <garsilva@embeddedor.com>
Return statements in functions returning bool should use
true/false instead of 1/0.
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/ipt_ah.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index a787d07f6cb7..7c6c20eaf4db 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -47,7 +47,7 @@ static bool ah_mt(const struct sk_buff *skb, struct xt_action_param *par)
*/
pr_debug("Dropping evil AH tinygram.\n");
par->hotdrop = true;
- return 0;
+ return false;
}
return spi_match(ahinfo->spis[0], ahinfo->spis[1],
--
2.11.0
^ permalink raw reply related
* [PATCH 04/47] netfilter: nf_conntrack_broadcast: remove useless parameter
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: Taehee Yoo <ap420073@gmail.com>
parameter protoff in nf_conntrack_broadcast_help is not used anywhere.
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack_helper.h | 3 +--
net/netfilter/nf_conntrack_broadcast.c | 1 -
net/netfilter/nf_conntrack_netbios_ns.c | 5 +++--
net/netfilter/nf_conntrack_snmp.c | 5 +++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index fc39bbaf107c..32c2a94a219d 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -132,8 +132,7 @@ void nf_conntrack_helper_pernet_fini(struct net *net);
int nf_conntrack_helper_init(void);
void nf_conntrack_helper_fini(void);
-int nf_conntrack_broadcast_help(struct sk_buff *skb, unsigned int protoff,
- struct nf_conn *ct,
+int nf_conntrack_broadcast_help(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int timeout);
diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c
index ecc3ab784633..a1086bdec242 100644
--- a/net/netfilter/nf_conntrack_broadcast.c
+++ b/net/netfilter/nf_conntrack_broadcast.c
@@ -20,7 +20,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
int nf_conntrack_broadcast_help(struct sk_buff *skb,
- unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int timeout)
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 496ce173f0c1..a4a59dc7cf17 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -41,9 +41,10 @@ static struct nf_conntrack_expect_policy exp_policy = {
};
static int netbios_ns_help(struct sk_buff *skb, unsigned int protoff,
- struct nf_conn *ct, enum ip_conntrack_info ctinfo)
+ struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo)
{
- return nf_conntrack_broadcast_help(skb, protoff, ct, ctinfo, timeout);
+ return nf_conntrack_broadcast_help(skb, ct, ctinfo, timeout);
}
static struct nf_conntrack_helper helper __read_mostly = {
diff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c
index 87b95a2c270c..2d0f8e010821 100644
--- a/net/netfilter/nf_conntrack_snmp.c
+++ b/net/netfilter/nf_conntrack_snmp.c
@@ -36,11 +36,12 @@ int (*nf_nat_snmp_hook)(struct sk_buff *skb,
EXPORT_SYMBOL_GPL(nf_nat_snmp_hook);
static int snmp_conntrack_help(struct sk_buff *skb, unsigned int protoff,
- struct nf_conn *ct, enum ip_conntrack_info ctinfo)
+ struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo)
{
typeof(nf_nat_snmp_hook) nf_nat_snmp;
- nf_conntrack_broadcast_help(skb, protoff, ct, ctinfo, timeout);
+ nf_conntrack_broadcast_help(skb, ct, ctinfo, timeout);
nf_nat_snmp = rcu_dereference(nf_nat_snmp_hook);
if (nf_nat_snmp && ct->status & IPS_NAT_MASK)
--
2.11.0
^ permalink raw reply related
* [PATCH 03/47] netfilter: xt_cluster: get rid of xt_cluster_ipv6_is_multicast
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: Taehee Yoo <ap420073@gmail.com>
If use the ipv6_addr_is_multicast instead of xt_cluster_ipv6_is_multicast,
then we can reduce code size.
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_cluster.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c
index 0068688995c8..dfbdbb2fc0ed 100644
--- a/net/netfilter/xt_cluster.c
+++ b/net/netfilter/xt_cluster.c
@@ -60,13 +60,6 @@ xt_cluster_hash(const struct nf_conn *ct,
}
static inline bool
-xt_cluster_ipv6_is_multicast(const struct in6_addr *addr)
-{
- __be32 st = addr->s6_addr32[0];
- return ((st & htonl(0xFF000000)) == htonl(0xFF000000));
-}
-
-static inline bool
xt_cluster_is_multicast_addr(const struct sk_buff *skb, u_int8_t family)
{
bool is_multicast = false;
@@ -76,8 +69,7 @@ xt_cluster_is_multicast_addr(const struct sk_buff *skb, u_int8_t family)
is_multicast = ipv4_is_multicast(ip_hdr(skb)->daddr);
break;
case NFPROTO_IPV6:
- is_multicast =
- xt_cluster_ipv6_is_multicast(&ipv6_hdr(skb)->daddr);
+ is_multicast = ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr);
break;
default:
WARN_ON(1);
--
2.11.0
^ permalink raw reply related
* [PATCH 02/47] netfilter: nfnetlink_acct: remove useless parameter
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: Taehee Yoo <ap420073@gmail.com>
parameter skb in nfnl_acct_overquota is not used anywhere.
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nfnetlink_acct.h | 3 +--
net/netfilter/nfnetlink_acct.c | 3 +--
net/netfilter/xt_nfacct.c | 2 +-
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h
index b4d741195c28..beee8bffe49e 100644
--- a/include/linux/netfilter/nfnetlink_acct.h
+++ b/include/linux/netfilter/nfnetlink_acct.h
@@ -16,6 +16,5 @@ struct nf_acct;
struct nf_acct *nfnl_acct_find_get(struct net *net, const char *filter_name);
void nfnl_acct_put(struct nf_acct *acct);
void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct);
-int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb,
- struct nf_acct *nfacct);
+int nfnl_acct_overquota(struct net *net, struct nf_acct *nfacct);
#endif /* _NFNL_ACCT_H */
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 88d427f9f9e6..b9505bcd3827 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -467,8 +467,7 @@ static void nfnl_overquota_report(struct net *net, struct nf_acct *nfacct)
GFP_ATOMIC);
}
-int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb,
- struct nf_acct *nfacct)
+int nfnl_acct_overquota(struct net *net, struct nf_acct *nfacct)
{
u64 now;
u64 *quota;
diff --git a/net/netfilter/xt_nfacct.c b/net/netfilter/xt_nfacct.c
index c8674deed4eb..6b56f4170860 100644
--- a/net/netfilter/xt_nfacct.c
+++ b/net/netfilter/xt_nfacct.c
@@ -28,7 +28,7 @@ static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par)
nfnl_acct_update(skb, info->nfacct);
- overquota = nfnl_acct_overquota(xt_net(par), skb, info->nfacct);
+ overquota = nfnl_acct_overquota(xt_net(par), info->nfacct);
return overquota == NFACCT_UNDERQUOTA ? false : true;
}
--
2.11.0
^ permalink raw reply related
* [PATCH 01/47] netfilter: nf_tables: nf_tables_obj_lookup_byhandle() can be static
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <20180330113729.18335-1-pablo@netfilter.org>
From: kbuild test robot <fengguang.wu@intel.com>
Fixes: 3ecbfd65f50e ("netfilter: nf_tables: allocate handle and delete objects via handle")
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8b9fe30de0cd..8cc7fc970f0c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4328,9 +4328,9 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
}
EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
-struct nft_object *nf_tables_obj_lookup_byhandle(const struct nft_table *table,
- const struct nlattr *nla,
- u32 objtype, u8 genmask)
+static struct nft_object *nf_tables_obj_lookup_byhandle(const struct nft_table *table,
+ const struct nlattr *nla,
+ u32 objtype, u8 genmask)
{
struct nft_object *obj;
@@ -4850,7 +4850,7 @@ struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table,
}
EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup);
-struct nft_flowtable *
+static struct nft_flowtable *
nf_tables_flowtable_lookup_byhandle(const struct nft_table *table,
const struct nlattr *nla, u8 genmask)
{
--
2.11.0
^ permalink raw reply related
* [PATCH 00/47] Netfilter/IPVS updates for net-next
From: Pablo Neira Ayuso @ 2018-03-30 11:36 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
The following patchset contains Netfilter/IPVS updates for your net-next
tree. This batch comes with more input sanitization for xtables to
address bug reports from fuzzers, preparation works to the flowtable
infrastructure and assorted updates. In no particular order, they are:
1) Make sure userspace provides a valid standard target verdict, from
Florian Westphal.
2) Sanitize error target size, also from Florian.
3) Validate that last rule in basechain matches underflow/policy since
userspace assumes this when decoding the ruleset blob that comes
from the kernel, from Florian.
4) Consolidate hook entry checks through xt_check_table_hooks(),
patch from Florian.
5) Cap ruleset allocations at 512 mbytes, 134217728 rules and reject
very large compat offset arrays, so we have a reasonable upper limit
and fuzzers don't exercise the oom-killer. Patches from Florian.
6) Several WARN_ON checks on xtables mutex helper, from Florian.
7) xt_rateest now has a hashtable per net, from Cong Wang.
8) Consolidate counter allocation in xt_counters_alloc(), from Florian.
9) Earlier xt_table_unlock() call in {ip,ip6,arp,eb}tables, patch
from Xin Long.
10) Set FLOW_OFFLOAD_DIR_* to IP_CT_DIR_* definitions, patch from
Felix Fietkau.
11) Consolidate code through flow_offload_fill_dir(), also from Felix.
12) Inline ip6_dst_mtu_forward() just like ip_dst_mtu_maybe_forward()
to remove a dependency with flowtable and ipv6.ko, from Felix.
13) Cache mtu size in flow_offload_tuple object, this is safe for
forwarding as f87c10a8aa1e describes, from Felix.
14) Rename nf_flow_table.c to nf_flow_table_core.o, to simplify too
modular infrastructure, from Felix.
15) Add rt0, rt2 and rt4 IPv6 routing extension support, patch from
Ahmed Abdelsalam.
16) Remove unused parameter in nf_conncount_count(), from Yi-Hung Wei.
17) Support for counting only to nf_conncount infrastructure, patch
from Yi-Hung Wei.
18) Add strict NFT_CT_{SRC_IP,DST_IP,SRC_IP6,DST_IP6} key datatypes
to nft_ct.
19) Use boolean as return value from ipt_ah and from IPVS too, patch
from Gustavo A. R. Silva.
20) Remove useless parameters in nfnl_acct_overquota() and
nf_conntrack_broadcast_help(), from Taehee Yoo.
21) Use ipv6_addr_is_multicast() from xt_cluster, also from Taehee Yoo.
22) Statify nf_tables_obj_lookup_byhandle, patch from Fengguang Wu.
23) Fix typo in xt_limit, from Geert Uytterhoeven.
24) Do no use VLAs in Netfilter code, again from Gustavo.
25) Use ADD_COUNTER from ebtables, from Taehee Yoo.
26) Bitshift support for CONNMARK and MARK targets, from Jack Ma.
27) Use pr_*() and add pr_fmt(), from Arushi Singhal.
28) Add synproxy support to ctnetlink.
29) ICMP type and IGMP matching support for ebtables, patches from
Matthias Schiffer.
30) Support for the revision infrastructure to ebtables, from
Bernie Harris.
31) String match support for ebtables, also from Bernie.
32) Documentation for the new flowtable infrastructure.
33) Use generic comparison functions in ebt_stp, from Joe Perches.
34) Demodularize filter chains in nftables.
35) Register conntrack hooks in case nftables NAT chain is added.
36) Merge assignments with return in a couple of spots in the
Netfilter codebase, also from Arushi.
37) Document that xtables percpu counters are stored in the same
memory area, from Ben Hutchings.
38) Revert mark_source_chains() sanity checks that break existing
rulesets, from Florian Westphal.
39) Use is_zero_ether_addr() in the ipset codebase, from Joe Perches.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks!
----------------------------------------------------------------
The following changes since commit ef3f6c256f0b4711a3ef1489797b95820be5ab01:
Merge branch 'mvpp2-jumbo-frames-support' (2018-03-05 12:55:55 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to 26c97c5d8dac6bc56d4360561a286f52543ac07e:
netfilter: ipset: Use is_zero_ether_addr instead of static and memcmp (2018-03-30 12:20:44 +0200)
----------------------------------------------------------------
Arushi Singhal (2):
netfilter: Replace printk() with pr_*() and define pr_fmt()
netfilter: Merge assignment with return
Ben Hutchings (1):
netfilter: x_tables: Add note about how to free percpu counters
Bernie Harris (2):
netfilter: ebtables: Add support for specifying match revision
netfilter: ebtables: Add string filter
Cong Wang (1):
netfilter: make xt_rateest hash table per net
Florian Westphal (13):
netfilter: x_tables: check standard verdicts in core
netfilter: x_tables: check error target size too
netfilter: x_tables: move hook entry checks into core
netfilter: x_tables: enforce unique and ascending entry points
netfilter: x_tables: cap allocations at 512 mbyte
netfilter: x_tables: limit allocation requests for blob rule heads
netfilter: x_tables: add counters allocation wrapper
netfilter: compat: prepare xt_compat_init_offsets to return errors
netfilter: compat: reject huge allocation requests
netfilter: x_tables: make sure compat af mutex is held
netfilter: x_tables: ensure last rule in base chain matches underflow/policy
netfilter: x_tables: fix build with CONFIG_COMPAT=n
Revert "netfilter: x_tables: ensure last rule in base chain matches underflow/policy"
Geert Uytterhoeven (1):
netfilter: xt_limit: Spelling s/maxmum/maximum/
Gustavo A. R. Silva (5):
netfilter: ipt_ah: return boolean instead of integer
ipvs: use true and false for boolean values
netfilter: cttimeout: remove VLA usage
netfilter: nfnetlink_cthelper: Remove VLA usage
netfilter: nf_tables: remove VLA usage
Jack Ma (1):
netfilter: xt_conntrack: Support bit-shifting for CONNMARK & MARK targets.
Joe Perches (2):
netfilter: ebt_stp: Use generic functions for comparisons
netfilter: ipset: Use is_zero_ether_addr instead of static and memcmp
Matthias Schiffer (2):
netfilter: ebtables: add support for matching ICMP type and code
netfilter: ebtables: add support for matching IGMP type
Pablo Neira Ayuso (9):
netfilter: nft_ct: add NFT_CT_{SRC,DST}_{IP,IP6}
netfilter: ctnetlink: synproxy support
netfilter: add flowtable documentation
netfilter: nf_tables: rename struct nf_chain_type
netfilter: nf_tables: nft_register_chain_type() returns void
netfilter: nf_tables: build-in filter chain type
netfilter: nf_tables: enable conntrack if NAT chain is registered
netfilter: nf_tables: rename to nft_set_lookup_global()
netfilter: nf_tables: use nft_set_lookup_global from nf_tables_newsetelem()
Taehee Yoo (4):
netfilter: nfnetlink_acct: remove useless parameter
netfilter: xt_cluster: get rid of xt_cluster_ipv6_is_multicast
netfilter: nf_conntrack_broadcast: remove useless parameter
netfilter: ebtables: use ADD_COUNTER macro
Xin Long (1):
netfilter: unlock xt_table earlier in __do_replace
Yi-Hung Wei (2):
netfilter: Refactor nf_conncount
netfilter: conncount: Support count only use case
kbuild test robot (1):
netfilter: nf_tables: nf_tables_obj_lookup_byhandle() can be static
Documentation/networking/nf_flowtable.txt | 112 ++++++
include/linux/netfilter/nfnetlink_acct.h | 3 +-
include/linux/netfilter/x_tables.h | 5 +-
include/net/netfilter/nf_conntrack_count.h | 1 -
include/net/netfilter/nf_conntrack_helper.h | 3 +-
include/net/netfilter/nf_tables.h | 33 +-
include/net/netfilter/xt_rateest.h | 4 +-
include/uapi/linux/netfilter/nf_conntrack_common.h | 1 +
include/uapi/linux/netfilter/nf_tables.h | 12 +-
include/uapi/linux/netfilter/nfnetlink_conntrack.h | 10 +
include/uapi/linux/netfilter/xt_connmark.h | 10 +
include/uapi/linux/netfilter_bridge/ebt_ip.h | 15 +-
include/uapi/linux/netfilter_bridge/ebtables.h | 16 +-
net/bridge/netfilter/Kconfig | 2 +-
net/bridge/netfilter/Makefile | 1 -
net/bridge/netfilter/ebt_ip.c | 58 ++-
net/bridge/netfilter/ebt_stp.c | 6 +-
net/bridge/netfilter/ebtables.c | 74 ++--
net/bridge/netfilter/nf_tables_bridge.c | 79 ----
net/ipv4/netfilter/Kconfig | 4 +-
net/ipv4/netfilter/Makefile | 2 -
net/ipv4/netfilter/arp_tables.c | 33 +-
net/ipv4/netfilter/ip_tables.c | 31 +-
net/ipv4/netfilter/ipt_SYNPROXY.c | 8 +-
net/ipv4/netfilter/ipt_ah.c | 2 +-
net/ipv4/netfilter/nf_tables_arp.c | 58 ---
net/ipv4/netfilter/nf_tables_ipv4.c | 67 ----
net/ipv4/netfilter/nft_chain_nat_ipv4.c | 20 +-
net/ipv4/netfilter/nft_chain_route_ipv4.c | 6 +-
net/ipv6/netfilter/Kconfig | 2 +-
net/ipv6/netfilter/Makefile | 1 -
net/ipv6/netfilter/ip6_tables.c | 33 +-
net/ipv6/netfilter/ip6t_SYNPROXY.c | 8 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 65 ----
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 20 +-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 6 +-
net/netfilter/Kconfig | 4 +-
net/netfilter/Makefile | 9 +-
net/netfilter/ipset/ip_set_hash_mac.c | 7 +-
net/netfilter/ipvs/ip_vs_lblc.c | 4 +-
net/netfilter/ipvs/ip_vs_lblcr.c | 4 +-
net/netfilter/nf_conncount.c | 14 +-
net/netfilter/nf_conntrack_acct.c | 6 +-
net/netfilter/nf_conntrack_broadcast.c | 1 -
net/netfilter/nf_conntrack_ecache.c | 6 +-
net/netfilter/nf_conntrack_netbios_ns.c | 5 +-
net/netfilter/nf_conntrack_netlink.c | 92 ++++-
net/netfilter/nf_conntrack_snmp.c | 5 +-
net/netfilter/nf_conntrack_timestamp.c | 6 +-
net/netfilter/nf_nat_core.c | 4 +-
net/netfilter/nf_nat_ftp.c | 7 +-
net/netfilter/nf_nat_irc.c | 7 +-
net/netfilter/nf_tables_api.c | 115 +++---
net/netfilter/nf_tables_inet.c | 75 ----
net/netfilter/nf_tables_netdev.c | 142 --------
net/netfilter/nfnetlink_acct.c | 3 +-
net/netfilter/nfnetlink_cthelper.c | 25 +-
net/netfilter/nfnetlink_cttimeout.c | 26 +-
net/netfilter/nfnetlink_queue.c | 14 +-
net/netfilter/nft_chain_filter.c | 398 +++++++++++++++++++++
net/netfilter/nft_ct.c | 38 ++
net/netfilter/nft_dynset.c | 5 +-
net/netfilter/nft_lookup.c | 4 +-
net/netfilter/nft_objref.c | 5 +-
net/netfilter/x_tables.c | 191 +++++++++-
net/netfilter/xt_RATEEST.c | 91 +++--
net/netfilter/xt_cluster.c | 10 +-
net/netfilter/xt_connlimit.c | 4 +-
net/netfilter/xt_connmark.c | 77 +++-
net/netfilter/xt_hashlimit.c | 3 +-
net/netfilter/xt_limit.c | 2 +-
net/netfilter/xt_nfacct.c | 2 +-
net/netfilter/xt_rateest.c | 10 +-
net/netfilter/xt_string.c | 1 +
net/netfilter/xt_time.c | 13 +-
75 files changed, 1384 insertions(+), 862 deletions(-)
create mode 100644 Documentation/networking/nf_flowtable.txt
delete mode 100644 net/bridge/netfilter/nf_tables_bridge.c
delete mode 100644 net/ipv4/netfilter/nf_tables_arp.c
delete mode 100644 net/ipv4/netfilter/nf_tables_ipv4.c
delete mode 100644 net/ipv6/netfilter/nf_tables_ipv6.c
delete mode 100644 net/netfilter/nf_tables_inet.c
delete mode 100644 net/netfilter/nf_tables_netdev.c
create mode 100644 net/netfilter/nft_chain_filter.c
^ permalink raw reply
* Re: [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
From: Alexey Kodanev @ 2018-03-30 11:36 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, netdev, Eric Dumazet, Martin KaFai Lau, David Miller
In-Reply-To: <201803301853.dWQl77c0%fengguang.wu@intel.com>
On 03/30/2018 01:14 PM, kbuild test robot wrote:
> Hi Alexey,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on net/master]
>
> url: https://github.com/0day-ci/linux/commits/Alexey-Kodanev/ipv6-move-ip6_dst_store-calls-with-flowi6-checks-to-a-wrapper/20180330-173050
> config: ia64-defconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 7.2.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=ia64
>
> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/tcp.h:23:0,
> from include/linux/ipv6.h:87,
> from include/net/ipv6.h:16,
> from include/net/inetpeer.h:16,
> from include/net/route.h:28,
> from drivers/infiniband/core/addr.c:43:
> include/net/ip6_route.h: In function 'ip6_dst_store_flow':
> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
> #define sk_v6_daddr __sk_common.skc_v6_daddr
> ^
>>> include/net/ip6_route.h:221:43: note: in expansion of macro 'sk_v6_daddr'
> ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
> ^~~~~~~~~~~
> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
> #define sk_v6_daddr __sk_common.skc_v6_daddr
> ^
> include/net/ip6_route.h:222:14: note: in expansion of macro 'sk_v6_daddr'
> &sk->sk_v6_daddr : NULL
> ^~~~~~~~~~~
This is because CONFIG_IPV6 is not enabled, no sk_v6_daddr member,
I'll fix it in the new version.
Thanks,
Alexey
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Rahul Lakkireddy @ 2018-03-30 10:51 UTC (permalink / raw)
To: Jiri Pirko
Cc: Indranil Choudhury,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Nirranjan Kirubaharan,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org,
Ganesh GR, viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org
In-Reply-To: <20180330103907.GC3313@nanopsycho>
On Friday, March 03/30/18, 2018 at 16:09:07 +0530, Jiri Pirko wrote:
> Sat, Mar 24, 2018 at 11:56:33AM CET, rahul.lakkireddy-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org wrote:
> >Add a new module crashdd that exports the /sys/kernel/crashdd/
> >directory in second kernel, containing collected hardware/firmware
> >dumps.
> >
> >The sequence of actions done by device drivers to append their device
> >specific hardware/firmware logs to /sys/kernel/crashdd/ directory are
> >as follows:
> >
> >1. During probe (before hardware is initialized), device drivers
> >register to the crashdd module (via crashdd_add_dump()), with
> >callback function, along with buffer size and log name needed for
> >firmware/hardware log collection.
> >
> >2. Crashdd creates a driver's directory under
> >/sys/kernel/crashdd/<driver>. Then, it allocates the buffer with
>
> This smells. I need to identify the exact ASIC instance that produced
> the dump. To identify by driver name does not help me if I have multiple
> instances of the same driver. This looks wrong to me. This looks like
> a job for devlink where you have 1 devlink instance per 1 ASIC instance.
>
> Please see:
> http://patchwork.ozlabs.org/project/netdev/list/?series=36524
>
> I bevieve that the solution in the patchset could be used for
> your usecase too.
>
>
The sysfs approach proposed here had been dropped in favour exporting
the dumps as ELF notes in /proc/vmcore.
Will be posting the new patches soon.
> >requested size and invokes the device driver's registered callback
> >function.
> >
> >3. Device driver collects all hardware/firmware logs into the buffer
> >and returns control back to crashdd.
> >
> >4. Crashdd exposes the buffer as a binary file via
> >/sys/kernel/crashdd/<driver>/<dump_file>.
> >
^ permalink raw reply
* [PATCH net-next 2/2] net: bridge: disable bridge MTU auto tuning if it was set manually
From: Nikolay Aleksandrov @ 2018-03-30 10:46 UTC (permalink / raw)
To: netdev
Cc: roopa, davem, makita.toshiaki, 3chas3, stephen, bridge,
Nikolay Aleksandrov
In-Reply-To: <20180330104619.31479-1-nikolay@cumulusnetworks.com>
As Roopa noted today the biggest source of problems when configuring
bridge and ports is that the bridge MTU keeps changing automatically on
port events (add/del/changemtu). That leads to inconsistent behaviour
and network config software needs to chase the MTU and fix it on each
such event. Let's improve on that situation and allow for the user to
set any MTU within ETH_MIN/MAX limits, but once manually configured it
is the user's responsibility to keep it correct afterwards.
In case the MTU isn't manually set - the behaviour reverts to the
previous and the bridge follows the minimum MTU.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
net/bridge/br.c | 2 +-
net/bridge/br_device.c | 5 ++---
net/bridge/br_if.c | 36 +++++++++++++++++++++---------------
net/bridge/br_private.h | 3 ++-
4 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 565ff055813b..671d13c10f6f 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -52,7 +52,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
switch (event) {
case NETDEV_CHANGEMTU:
- dev_set_mtu(br->dev, br_mtu(br, false));
+ br_mtu_auto_adjust(br);
break;
case NETDEV_CHANGEADDR:
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index edb9967eb165..e682a668ce57 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -225,11 +225,10 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
{
struct net_bridge *br = netdev_priv(dev);
- if (new_mtu > br_mtu(br, br_vlan_enabled(dev)))
- return -EINVAL;
-
dev->mtu = new_mtu;
+ /* this flag will be cleared if the MTU was automatically adjusted */
+ br->mtu_set_by_user = true;
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
/* remember the MTU in the rtable for PMTU */
dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 7d5dc5a91084..82c1a6f430b3 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -424,28 +424,34 @@ int br_del_bridge(struct net *net, const char *name)
return ret;
}
-/* MTU of the bridge pseudo-device: ETH_DATA_LEN if there are no ports, the
- * minimum of the ports if @max is false or the maximum if it's true
- */
-int br_mtu(const struct net_bridge *br, bool max)
+/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
+static int br_mtu_min(const struct net_bridge *br)
{
const struct net_bridge_port *p;
int ret_mtu = 0;
- ASSERT_RTNL();
-
- list_for_each_entry(p, &br->port_list, list) {
- if (!max) {
- if (!ret_mtu || ret_mtu > p->dev->mtu)
- ret_mtu = p->dev->mtu;
- } else if (p->dev->mtu > ret_mtu) {
+ list_for_each_entry(p, &br->port_list, list)
+ if (!ret_mtu || ret_mtu > p->dev->mtu)
ret_mtu = p->dev->mtu;
- }
- }
return ret_mtu ? ret_mtu : ETH_DATA_LEN;
}
+void br_mtu_auto_adjust(struct net_bridge *br)
+{
+ ASSERT_RTNL();
+
+ /* if the bridge MTU was manually configured don't mess with it */
+ if (br->mtu_set_by_user)
+ return;
+
+ /* change to the minimum MTU and clear the flag which was set by
+ * the bridge ndo_change_mtu callback
+ */
+ dev_set_mtu(br->dev, br_mtu_min(br));
+ br->mtu_set_by_user = false;
+}
+
static void br_set_gso_limits(struct net_bridge *br)
{
unsigned int gso_max_size = GSO_MAX_SIZE;
@@ -597,7 +603,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
if (changed_addr)
call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
- dev_set_mtu(br->dev, br_mtu(br, false));
+ br_mtu_auto_adjust(br);
br_set_gso_limits(br);
kobject_uevent(&p->kobj, KOBJ_ADD);
@@ -644,7 +650,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
*/
del_nbp(p);
- dev_set_mtu(br->dev, br_mtu(br, false));
+ br_mtu_auto_adjust(br);
br_set_gso_limits(br);
spin_lock_bh(&br->lock);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 586f84b9670d..a7cb3ece5031 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -410,6 +410,7 @@ struct net_bridge {
int offload_fwd_mark;
#endif
bool neigh_suppress_enabled;
+ bool mtu_set_by_user;
struct hlist_head fdb_list;
};
@@ -578,7 +579,7 @@ int br_del_bridge(struct net *net, const char *name);
int br_add_if(struct net_bridge *br, struct net_device *dev,
struct netlink_ext_ack *extack);
int br_del_if(struct net_bridge *br, struct net_device *dev);
-int br_mtu(const struct net_bridge *br, bool max);
+void br_mtu_auto_adjust(struct net_bridge *br);
netdev_features_t br_features_recompute(struct net_bridge *br,
netdev_features_t features);
void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 1/2] net: bridge: set min MTU on port events and allow user to set max
From: Nikolay Aleksandrov @ 2018-03-30 10:46 UTC (permalink / raw)
To: netdev
Cc: roopa, davem, makita.toshiaki, 3chas3, stephen, bridge,
Nikolay Aleksandrov
In-Reply-To: <20180330104619.31479-1-nikolay@cumulusnetworks.com>
Recently the bridge was changed to automatically set maximum MTU on port
events (add/del/changemtu) when vlan filtering is enabled, but that
actually changes behaviour in a way which breaks some setups and can lead
to packet drops. In order to still allow that maximum to be set while being
compatible, we add the ability for the user to tune the bridge MTU up to
the maximum when vlan filtering is enabled, but that has to be done
explicitly and all port events (add/del/changemtu) lead to resetting that
MTU to the minimum as before.
Suggested-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
net/bridge/br.c | 2 +-
net/bridge/br_device.c | 3 ++-
net/bridge/br_if.c | 43 ++++++++++++++-----------------------------
net/bridge/br_private.h | 2 +-
4 files changed, 18 insertions(+), 32 deletions(-)
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 26e1616b2c90..565ff055813b 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -52,7 +52,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
switch (event) {
case NETDEV_CHANGEMTU:
- dev_set_mtu(br->dev, br_mtu(br));
+ dev_set_mtu(br->dev, br_mtu(br, false));
break;
case NETDEV_CHANGEADDR:
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 278fc999d355..edb9967eb165 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -224,7 +224,8 @@ static void br_get_stats64(struct net_device *dev,
static int br_change_mtu(struct net_device *dev, int new_mtu)
{
struct net_bridge *br = netdev_priv(dev);
- if (new_mtu > br_mtu(br))
+
+ if (new_mtu > br_mtu(br, br_vlan_enabled(dev)))
return -EINVAL;
dev->mtu = new_mtu;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 87b2afd455c7..7d5dc5a91084 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -424,41 +424,26 @@ int br_del_bridge(struct net *net, const char *name)
return ret;
}
-static bool min_mtu(int a, int b)
-{
- return a < b ? 1 : 0;
-}
-
-static bool max_mtu(int a, int b)
-{
- return a > b ? 1 : 0;
-}
-
-/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
-static int __br_mtu(const struct net_bridge *br, bool (compare_fn)(int, int))
+/* MTU of the bridge pseudo-device: ETH_DATA_LEN if there are no ports, the
+ * minimum of the ports if @max is false or the maximum if it's true
+ */
+int br_mtu(const struct net_bridge *br, bool max)
{
const struct net_bridge_port *p;
- int mtu = 0;
+ int ret_mtu = 0;
ASSERT_RTNL();
- if (list_empty(&br->port_list))
- mtu = ETH_DATA_LEN;
- else {
- list_for_each_entry(p, &br->port_list, list) {
- if (!mtu || compare_fn(p->dev->mtu, mtu))
- mtu = p->dev->mtu;
+ list_for_each_entry(p, &br->port_list, list) {
+ if (!max) {
+ if (!ret_mtu || ret_mtu > p->dev->mtu)
+ ret_mtu = p->dev->mtu;
+ } else if (p->dev->mtu > ret_mtu) {
+ ret_mtu = p->dev->mtu;
}
}
- return mtu;
-}
-int br_mtu(const struct net_bridge *br)
-{
- if (br_vlan_enabled(br->dev))
- return __br_mtu(br, max_mtu);
- else
- return __br_mtu(br, min_mtu);
+ return ret_mtu ? ret_mtu : ETH_DATA_LEN;
}
static void br_set_gso_limits(struct net_bridge *br)
@@ -612,7 +597,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
if (changed_addr)
call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
- dev_set_mtu(br->dev, br_mtu(br));
+ dev_set_mtu(br->dev, br_mtu(br, false));
br_set_gso_limits(br);
kobject_uevent(&p->kobj, KOBJ_ADD);
@@ -659,7 +644,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
*/
del_nbp(p);
- dev_set_mtu(br->dev, br_mtu(br));
+ dev_set_mtu(br->dev, br_mtu(br, false));
br_set_gso_limits(br);
spin_lock_bh(&br->lock);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 048d5b51813b..586f84b9670d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -578,7 +578,7 @@ int br_del_bridge(struct net *net, const char *name);
int br_add_if(struct net_bridge *br, struct net_device *dev,
struct netlink_ext_ack *extack);
int br_del_if(struct net_bridge *br, struct net_device *dev);
-int br_mtu(const struct net_bridge *br);
+int br_mtu(const struct net_bridge *br, bool max);
netdev_features_t br_features_recompute(struct net_bridge *br,
netdev_features_t features);
void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 0/2] net: bridge: MTU handling changes
From: Nikolay Aleksandrov @ 2018-03-30 10:46 UTC (permalink / raw)
To: netdev; +Cc: Nikolay Aleksandrov, roopa, bridge, 3chas3, davem
Hi,
As previously discussed the recent changes break some setups and could lead
to packet drops. Thus the first patch reverts the behaviour for the bridge
to follow the minimum MTU but also keeps the ability to set the MTU to the
maximum (out of all ports) if vlan filtering is enabled. Patch 02 is the
bigger change in behaviour - we've always had trouble when configuring
bridges and their MTU which is auto tuning on port events
(add/del/changemtu), which means config software needs to chase it and fix
it after each such event, after patch 02 we allow the user to configure any
MTU (ETH_MIN/MAX limited) but once that is done the bridge stops auto
tuning and relies on the user to keep the MTU correct.
This should be compatible with cases that don't touch the MTU (or set it
to the same value), while allowing to configure the MTU and not worry
about it changing afterwards.
The patches are intentionally split like this, so that if they get accepted
and there are any complaints patch 02 can be reverted.
Thanks,
Nik
Nikolay Aleksandrov (2):
net: bridge: set min MTU on port events and allow user to set max
net: bridge: disable bridge MTU auto tuning if it was set manually
net/bridge/br.c | 2 +-
net/bridge/br_device.c | 4 ++--
net/bridge/br_if.c | 49 ++++++++++++++++++++-----------------------------
net/bridge/br_private.h | 3 ++-
4 files changed, 25 insertions(+), 33 deletions(-)
--
2.11.0
^ permalink raw reply
* Re: [PATCH v2 2/2] net: mvneta: improve suspend/resume
From: Russell King - ARM Linux @ 2018-03-30 10:43 UTC (permalink / raw)
To: Jisheng Zhang
Cc: David Miller, Thomas Petazzoni, netdev, linux-kernel,
linux-arm-kernel
In-Reply-To: <20180330183615.6b34d153@xhacker.debian>
On Fri, Mar 30, 2018 at 06:36:15PM +0800, Jisheng Zhang wrote:
> Current suspend/resume implementation reuses the mvneta_open() and
> mvneta_close(), but it could be optimized to take only necessary
> actions during suspend/resume.
>
> One obvious problem of current implementation is: after hundreds of
> system suspend/resume cycles, the resume of mvneta could fail due to
> fragmented dma coherent memory. After this patch, the non-necessary
> memory alloc/free is optimized out.
I don't think you've properly tested this. Please ensure that you test
patches with the appropriate debug options enabled.
> @@ -4586,16 +4586,43 @@ static int mvneta_remove(struct platform_device *pdev)
> #ifdef CONFIG_PM_SLEEP
> static int mvneta_suspend(struct device *device)
> {
> + int queue;
> struct net_device *dev = dev_get_drvdata(device);
> struct mvneta_port *pp = netdev_priv(dev);
>
> - rtnl_lock();
> - if (netif_running(dev))
> - mvneta_stop(dev);
> - rtnl_unlock();
...
> + mvneta_stop_dev(pp);
You're removing the rtnl_lock() that I introduced in 3b8bc67413de
("net: mvneta: ensure PM paths take the rtnl lock") which is necessary
to provide phylink with consistent locking. mvneta_stop_dev() calls
phylink_stop() which will check that the rtnl lock is held, and will
print a warning if it isn't.
Your patch will cause a regression here.
> +
> + for (queue = 0; queue < rxq_number; queue++) {
> + struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
> +
> + mvneta_rxq_drop_pkts(pp, rxq);
> + }
> +
> + for (queue = 0; queue < txq_number; queue++) {
> + struct mvneta_tx_queue *txq = &pp->txqs[queue];
> +
> + mvneta_txq_hw_deinit(pp, txq);
> + }
> +
> +clean_exit:
> netif_device_detach(dev);
> clk_disable_unprepare(pp->clk_bus);
> clk_disable_unprepare(pp->clk);
> +
> return 0;
> }
>
> @@ -4604,7 +4631,7 @@ static int mvneta_resume(struct device *device)
> struct platform_device *pdev = to_platform_device(device);
> struct net_device *dev = dev_get_drvdata(device);
> struct mvneta_port *pp = netdev_priv(dev);
> - int err;
> + int err, queue;
>
> clk_prepare_enable(pp->clk);
> if (!IS_ERR(pp->clk_bus))
> @@ -4626,12 +4653,36 @@ static int mvneta_resume(struct device *device)
> }
>
> netif_device_attach(dev);
> - rtnl_lock();
> - if (netif_running(dev)) {
> - mvneta_open(dev);
> - mvneta_set_rx_mode(dev);
...
> }
> - rtnl_unlock();
...
> + mvneta_start_dev(pp);
Same applies here.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Jiri Pirko @ 2018-03-30 10:39 UTC (permalink / raw)
To: Rahul Lakkireddy
Cc: netdev, linux-fsdevel, kexec, linux-kernel, davem, viro, ebiederm,
stephen, akpm, torvalds, ganeshgr, nirranjan, indranil
In-Reply-To: <296ffbd47fd4f30238689e636bd2480683224227.1521888444.git.rahul.lakkireddy@chelsio.com>
Sat, Mar 24, 2018 at 11:56:33AM CET, rahul.lakkireddy@chelsio.com wrote:
>Add a new module crashdd that exports the /sys/kernel/crashdd/
>directory in second kernel, containing collected hardware/firmware
>dumps.
>
>The sequence of actions done by device drivers to append their device
>specific hardware/firmware logs to /sys/kernel/crashdd/ directory are
>as follows:
>
>1. During probe (before hardware is initialized), device drivers
>register to the crashdd module (via crashdd_add_dump()), with
>callback function, along with buffer size and log name needed for
>firmware/hardware log collection.
>
>2. Crashdd creates a driver's directory under
>/sys/kernel/crashdd/<driver>. Then, it allocates the buffer with
This smells. I need to identify the exact ASIC instance that produced
the dump. To identify by driver name does not help me if I have multiple
instances of the same driver. This looks wrong to me. This looks like
a job for devlink where you have 1 devlink instance per 1 ASIC instance.
Please see:
http://patchwork.ozlabs.org/project/netdev/list/?series=36524
I bevieve that the solution in the patchset could be used for
your usecase too.
>requested size and invokes the device driver's registered callback
>function.
>
>3. Device driver collects all hardware/firmware logs into the buffer
>and returns control back to crashdd.
>
>4. Crashdd exposes the buffer as a binary file via
>/sys/kernel/crashdd/<driver>/<dump_file>.
>
^ permalink raw reply
* [PATCH v2 2/2] net: mvneta: improve suspend/resume
From: Jisheng Zhang @ 2018-03-30 10:36 UTC (permalink / raw)
To: David Miller, Thomas Petazzoni; +Cc: netdev, linux-arm-kernel, linux-kernel
In-Reply-To: <20180330183332.3e180a1a@xhacker.debian>
Current suspend/resume implementation reuses the mvneta_open() and
mvneta_close(), but it could be optimized to take only necessary
actions during suspend/resume.
One obvious problem of current implementation is: after hundreds of
system suspend/resume cycles, the resume of mvneta could fail due to
fragmented dma coherent memory. After this patch, the non-necessary
memory alloc/free is optimized out.
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
drivers/net/ethernet/marvell/mvneta.c | 71 ++++++++++++++++++++++++++++++-----
1 file changed, 61 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f96815853108..cb7fce99ed6d 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4586,16 +4586,43 @@ static int mvneta_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int mvneta_suspend(struct device *device)
{
+ int queue;
struct net_device *dev = dev_get_drvdata(device);
struct mvneta_port *pp = netdev_priv(dev);
- rtnl_lock();
- if (netif_running(dev))
- mvneta_stop(dev);
- rtnl_unlock();
+ if (!netif_running(dev))
+ goto clean_exit;
+
+ if (!pp->neta_armada3700) {
+ spin_lock(&pp->lock);
+ pp->is_stopped = true;
+ spin_unlock(&pp->lock);
+
+ cpuhp_state_remove_instance_nocalls(online_hpstate,
+ &pp->node_online);
+ cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+ &pp->node_dead);
+ }
+
+ mvneta_stop_dev(pp);
+
+ for (queue = 0; queue < rxq_number; queue++) {
+ struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+
+ mvneta_rxq_drop_pkts(pp, rxq);
+ }
+
+ for (queue = 0; queue < txq_number; queue++) {
+ struct mvneta_tx_queue *txq = &pp->txqs[queue];
+
+ mvneta_txq_hw_deinit(pp, txq);
+ }
+
+clean_exit:
netif_device_detach(dev);
clk_disable_unprepare(pp->clk_bus);
clk_disable_unprepare(pp->clk);
+
return 0;
}
@@ -4604,7 +4631,7 @@ static int mvneta_resume(struct device *device)
struct platform_device *pdev = to_platform_device(device);
struct net_device *dev = dev_get_drvdata(device);
struct mvneta_port *pp = netdev_priv(dev);
- int err;
+ int err, queue;
clk_prepare_enable(pp->clk);
if (!IS_ERR(pp->clk_bus))
@@ -4626,12 +4653,36 @@ static int mvneta_resume(struct device *device)
}
netif_device_attach(dev);
- rtnl_lock();
- if (netif_running(dev)) {
- mvneta_open(dev);
- mvneta_set_rx_mode(dev);
+
+ if (!netif_running(dev))
+ return 0;
+
+ for (queue = 0; queue < rxq_number; queue++) {
+ struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+
+ rxq->next_desc_to_proc = 0;
+ mvneta_rxq_hw_init(pp, rxq);
}
- rtnl_unlock();
+
+ for (queue = 0; queue < txq_number; queue++) {
+ struct mvneta_tx_queue *txq = &pp->txqs[queue];
+
+ txq->next_desc_to_proc = 0;
+ mvneta_txq_hw_init(pp, txq);
+ }
+
+ if (!pp->neta_armada3700) {
+ spin_lock(&pp->lock);
+ pp->is_stopped = false;
+ spin_unlock(&pp->lock);
+ cpuhp_state_add_instance_nocalls(online_hpstate,
+ &pp->node_online);
+ cpuhp_state_add_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+ &pp->node_dead);
+ }
+
+ mvneta_start_dev(pp);
+ mvneta_set_rx_mode(dev);
return 0;
}
--
2.16.3
^ permalink raw reply related
* [PATCH v2 1/2] net: mvneta: split rxq/txq init and txq deinit into SW and HW parts
From: Jisheng Zhang @ 2018-03-30 10:34 UTC (permalink / raw)
To: David Miller, Thomas Petazzoni; +Cc: netdev, linux-arm-kernel, linux-kernel
In-Reply-To: <20180330183332.3e180a1a@xhacker.debian>
This is to prepare the suspend/resume improvement in next patch. The
SW parts can be optimized out during resume.
As for rxq handling during suspend, we'd like to drop packets by
calling mvneta_rxq_drop_pkts() which is both SW and HW operation,
so we don't split rxq deinit.
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
drivers/net/ethernet/marvell/mvneta.c | 85 +++++++++++++++++++++++++++--------
1 file changed, 66 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 30aab9bf77cc..f96815853108 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2796,10 +2796,8 @@ static void mvneta_rx_reset(struct mvneta_port *pp)
/* Rx/Tx queue initialization/cleanup methods */
-/* Create a specified RX queue */
-static int mvneta_rxq_init(struct mvneta_port *pp,
- struct mvneta_rx_queue *rxq)
-
+static int mvneta_rxq_sw_init(struct mvneta_port *pp,
+ struct mvneta_rx_queue *rxq)
{
rxq->size = pp->rx_ring_size;
@@ -2812,6 +2810,12 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
rxq->last_desc = rxq->size - 1;
+ return 0;
+}
+
+static void mvneta_rxq_hw_init(struct mvneta_port *pp,
+ struct mvneta_rx_queue *rxq)
+{
/* Set Rx descriptors queue starting address */
mvreg_write(pp, MVNETA_RXQ_BASE_ADDR_REG(rxq->id), rxq->descs_phys);
mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size);
@@ -2835,6 +2839,20 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
mvneta_rxq_short_pool_set(pp, rxq);
mvneta_rxq_non_occup_desc_add(pp, rxq, rxq->size);
}
+}
+
+/* Create a specified RX queue */
+static int mvneta_rxq_init(struct mvneta_port *pp,
+ struct mvneta_rx_queue *rxq)
+
+{
+ int ret;
+
+ ret = mvneta_rxq_sw_init(pp, rxq);
+ if (ret < 0)
+ return ret;
+
+ mvneta_rxq_hw_init(pp, rxq);
return 0;
}
@@ -2857,9 +2875,8 @@ static void mvneta_rxq_deinit(struct mvneta_port *pp,
rxq->descs_phys = 0;
}
-/* Create and initialize a tx queue */
-static int mvneta_txq_init(struct mvneta_port *pp,
- struct mvneta_tx_queue *txq)
+static int mvneta_txq_sw_init(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
{
int cpu;
@@ -2872,7 +2889,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
txq->tx_stop_threshold = txq->size - MVNETA_MAX_SKB_DESCS;
txq->tx_wake_threshold = txq->tx_stop_threshold / 2;
-
/* Allocate memory for TX descriptors */
txq->descs = dma_alloc_coherent(pp->dev->dev.parent,
txq->size * MVNETA_DESC_ALIGNED_SIZE,
@@ -2882,14 +2898,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
txq->last_desc = txq->size - 1;
- /* Set maximum bandwidth for enabled TXQs */
- mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
- mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
-
- /* Set Tx descriptors queue starting address */
- mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
- mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
-
txq->tx_skb = kmalloc_array(txq->size, sizeof(*txq->tx_skb),
GFP_KERNEL);
if (!txq->tx_skb) {
@@ -2910,7 +2918,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
txq->descs, txq->descs_phys);
return -ENOMEM;
}
- mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
/* Setup XPS mapping */
if (txq_number > 1)
@@ -2923,9 +2930,38 @@ static int mvneta_txq_init(struct mvneta_port *pp,
return 0;
}
+static void mvneta_txq_hw_init(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
+{
+ /* Set maximum bandwidth for enabled TXQs */
+ mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
+ mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
+
+ /* Set Tx descriptors queue starting address */
+ mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
+ mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
+
+ mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
+}
+
+/* Create and initialize a tx queue */
+static int mvneta_txq_init(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
+{
+ int ret;
+
+ ret = mvneta_txq_sw_init(pp, txq);
+ if (ret < 0)
+ return ret;
+
+ mvneta_txq_hw_init(pp, txq);
+
+ return 0;
+}
+
/* Free allocated resources when mvneta_txq_init() fails to allocate memory*/
-static void mvneta_txq_deinit(struct mvneta_port *pp,
- struct mvneta_tx_queue *txq)
+static void mvneta_txq_sw_deinit(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
{
struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
@@ -2946,7 +2982,11 @@ static void mvneta_txq_deinit(struct mvneta_port *pp,
txq->last_desc = 0;
txq->next_desc_to_proc = 0;
txq->descs_phys = 0;
+}
+static void mvneta_txq_hw_deinit(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
+{
/* Set minimum bandwidth for disabled TXQs */
mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0);
mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0);
@@ -2956,6 +2996,13 @@ static void mvneta_txq_deinit(struct mvneta_port *pp,
mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), 0);
}
+static void mvneta_txq_deinit(struct mvneta_port *pp,
+ struct mvneta_tx_queue *txq)
+{
+ mvneta_txq_sw_deinit(pp, txq);
+ mvneta_txq_hw_deinit(pp, txq);
+}
+
/* Cleanup all Tx queues */
static void mvneta_cleanup_txqs(struct mvneta_port *pp)
{
--
2.16.3
^ permalink raw reply related
* [PATCH v2 0/2] net: mvneta: improve suspend/resume
From: Jisheng Zhang @ 2018-03-30 10:33 UTC (permalink / raw)
To: David Miller, Thomas Petazzoni; +Cc: netdev, linux-arm-kernel, linux-kernel
This series tries to optimize the mvneta's suspend/resume
implementation by only taking necessary actions.
Since v1:
- unify ret check
- try best to keep the suspend/resume behavior
- split txq deinit into sw/hw parts as well
- adjust mvneta_stop_dev() location
I didn't add Thomas's Ack tag to patch1, because in v2, I added new code
to split the txq deinit into two parts.
Jisheng Zhang (2):
net: mvneta: split rxq/txq init and txq deinit into SW and HW parts
net: mvneta: improve suspend/resume
drivers/net/ethernet/marvell/mvneta.c | 156 +++++++++++++++++++++++++++-------
1 file changed, 127 insertions(+), 29 deletions(-)
--
2.16.3
^ permalink raw reply
* Re: [PATCH net-next 0/9] devlink: Add support for region access
From: Jiri Pirko @ 2018-03-30 10:24 UTC (permalink / raw)
To: Rahul Lakkireddy
Cc: Andrew Lunn, Alex Vesker, David S. Miller, netdev@vger.kernel.org,
Tariq Toukan, Jiri Pirko
In-Reply-To: <20180330095156.GA24242@chelsio.com>
Fri, Mar 30, 2018 at 11:51:57AM CEST, rahul.lakkireddy@chelsio.com wrote:
>On Thursday, March 03/29/18, 2018 at 23:53:43 +0530, Andrew Lunn wrote:
>> On Thu, Mar 29, 2018 at 07:07:43PM +0300, Alex Vesker wrote:
>> > This is a proposal which will allow access to driver defined address
>> > regions using devlink. Each device can create its supported address
>> > regions and register them. A device which exposes a region will allow
>> > access to it using devlink.
>>
>> Hi Alex
>>
>> Did you see the work Rahul Lakkireddy has been doing?
>>
>> https://patchwork.kernel.org/patch/10305935/
>>
>> It seems like these are similar, or at least overlapping. We probably
>> want one solution for both.
>>
>
>We're already collecting hardware snapshots when system is live with
>ethtool --getdump (which devlink tool is now trying to do).
Ethtool is definitelly a wrong tool for this. It uses netdev as a
handle, but the dumps happen on a parent device - represented by a
devlink instance.
Also, in devlink we have notifications so a deamon can actually listen
on a socket to see if there is new dump available due to a critical
event etc.
>
>We are now in the process of adding support to collect hardware
>snapshots during kernel panic.
>
>Thanks,
>Rahul
^ permalink raw reply
* Re: [PATCH] net: mvneta: fix enable of all initialized RXQs
From: Thomas Petazzoni @ 2018-03-30 10:22 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: David S. Miller, linux-kernel, netdev, Antoine Tenart,
Miquèl Raynal, Maxime Chevallier, stefanc, ymarkman,
Yelena Krivosheev
In-Reply-To: <20180330100531.5995-1-gregory.clement@bootlin.com>
Hello,
On Fri, 30 Mar 2018 12:05:31 +0200, Gregory CLEMENT wrote:
> From: Yelena Krivosheev <yelena@marvell.com>
>
> In mvneta_port_up() we enable relevant RX and TX port queues by write
> queues bit map to an appropriate register.
>
> q_map must be ZERO in the beginning of this process.
>
> Signed-off-by: Yelena Krivosheev <yelena@marvell.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Acked-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Thanks,
Thomas
--
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH net-next 0/9] devlink: Add support for region access
From: Jiri Pirko @ 2018-03-30 10:21 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alex Vesker, David S. Miller, netdev, Tariq Toukan, Jiri Pirko
In-Reply-To: <20180329195154.GB15565@lunn.ch>
Thu, Mar 29, 2018 at 09:51:54PM CEST, andrew@lunn.ch wrote:
>> >>Show all of the exposed regions with region sizes:
>> >>$ devlink region show
>> >>pci/0000:00:05.0/cr-space: size 1048576 snapshot [1 2]
>> >So you have 2Mbytes of snapshot data. Is this held in the device, or
>> >kernel memory?
>> This is allocated in devlink, the maximum number of snapshots is set by the
>> driver.
>
>And it seems to want contiguous pages. How well does that work after
>the system has been running for a while and memory is fragmented?
>
>> >>Dump a snapshot:
>> >>$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1
>> >>0000000000000000 0014 95dc 0014 9514 0035 1670 0034 db30
>> >>0000000000000010 0000 0000 ffff ff04 0029 8c00 0028 8cc8
>> >>0000000000000020 0016 0bb8 0016 1720 0000 0000 c00f 3ffc
>> >>0000000000000030 bada cce5 bada cce5 bada cce5 bada cce5
>> >>
>> >>Read a specific part of a snapshot:
>> >>$ devlink region read pci/0000:00:05.0/fw-health snapshot 1 address 0
>> >> length 16
>> >>0000000000000000 0014 95dc 0014 9514 0035 1670 0034 db30
>> >Why a separate command? It seems to be just a subset of dump.
>>
>> This is useful when debugging values on specific addresses, this also
>> brings the API one step closer for a read and write API.
>
>The functionality is useful, yes. But why two commands? Why not one
>command, dump, which takes optional parameters?
Between userspace and kernel, this is implemented as a single command.
So this is just a userspace wrapper. I think it is nice to provide clear
commands to the user so he is not confused about what is he doing. Also,
as Alex mentioned, we plan to have write command which will have same
command like args as read. These 2 should be in sync.
>
>Also, i doubt write support will be accepted. That sounds like the
>start of an API to allow a user space driver.
We discussed that on netconf in Seoul and was agreed it is needed.
We have 2 options: Some out of tree crap utils and access via /dev/mem,
or something which is well defined and implemented by in-tree drivers.
Writes will serve for debugging purposes, even tuning and bug hunting
on in production. For that, we need a standard way to do it.
^ permalink raw reply
* Re: [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
From: kbuild test robot @ 2018-03-30 10:14 UTC (permalink / raw)
To: Alexey Kodanev
Cc: kbuild-all, netdev, Eric Dumazet, Martin KaFai Lau, David Miller,
Alexey Kodanev
In-Reply-To: <1522345042-26646-2-git-send-email-alexey.kodanev@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]
Hi Alexey,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Alexey-Kodanev/ipv6-move-ip6_dst_store-calls-with-flowi6-checks-to-a-wrapper/20180330-173050
config: ia64-defconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=ia64
All warnings (new ones prefixed by >>):
In file included from include/linux/tcp.h:23:0,
from include/linux/ipv6.h:87,
from include/net/ipv6.h:16,
from include/net/inetpeer.h:16,
from include/net/route.h:28,
from drivers/infiniband/core/addr.c:43:
include/net/ip6_route.h: In function 'ip6_dst_store_flow':
include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
>> include/net/ip6_route.h:221:43: note: in expansion of macro 'sk_v6_daddr'
ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
^~~~~~~~~~~
include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
include/net/ip6_route.h:222:14: note: in expansion of macro 'sk_v6_daddr'
&sk->sk_v6_daddr : NULL,
^~~~~~~~~~~
vim +/sk_v6_daddr +221 include/net/ip6_route.h
219
220 ip6_dst_store(sk, dst,
> 221 ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
222 &sk->sk_v6_daddr : NULL,
223 #ifdef CONFIG_IPV6_SUBTREES
224 ipv6_addr_equal(&fl6->saddr, &np->saddr) ?
225 &np->saddr :
226 #endif
227 NULL);
228 }
229
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 18690 bytes --]
^ permalink raw reply
* [PATCH] net: mvneta: fix enable of all initialized RXQs
From: Gregory CLEMENT @ 2018-03-30 10:05 UTC (permalink / raw)
To: David S. Miller, linux-kernel, netdev
Cc: Thomas Petazzoni, Antoine Tenart, Miquèl Raynal,
Maxime Chevallier, stefanc, ymarkman, Yelena Krivosheev,
Gregory CLEMENT
From: Yelena Krivosheev <yelena@marvell.com>
In mvneta_port_up() we enable relevant RX and TX port queues by write
queues bit map to an appropriate register.
q_map must be ZERO in the beginning of this process.
Signed-off-by: Yelena Krivosheev <yelena@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/net/ethernet/marvell/mvneta.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 25e9a551cc8c..3f6fb635738c 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1132,6 +1132,7 @@ static void mvneta_port_up(struct mvneta_port *pp)
}
mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
+ q_map = 0;
/* Enable all initialized RXQs. */
for (queue = 0; queue < rxq_number; queue++) {
struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
--
2.16.2
^ permalink raw reply related
* Re: [PATCH net-next] net: Revert net_rwsem
From: Kirill Tkhai @ 2018-03-30 9:57 UTC (permalink / raw)
To: davem, netdev
In-Reply-To: <152240169991.24910.6978707493362813761.stgit@localhost.localdomain>
On 30.03.2018 12:23, Kirill Tkhai wrote:
> This reverts:
>
> 152f253152cc net: Remove rtnl_lock() in nf_ct_iterate_destroy()
> ec9c780925c5 ovs: Remove rtnl_lock() from ovs_exit_net()
> 350311aab4c0 security: Remove rtnl_lock() in selinux_xfrm_notify_policyload()
> 10256debb918 net: Don't take rtnl_lock() in wireless_nlevent_flush()
> f0b07bb151b0 net: Introduce net_rwsem to protect net_namespace_list
>
> There are missed, that down_read() can't be taken recursive.
> This is because of rw_semaphore design, which prevents it
> to be occupied by only readers forever.
>
> So, we can't take it in register_netdevice_notifier(), as it's also
> taken in wext_netdev_notifier_call()->wireless_nlevent_flush().
>
> The solution is to protect net_namespace_list modifications
> in register_netdevice_notifier() via pernet_ops_rwsem, as it's
> made in:
>
> https://patchwork.ozlabs.org/project/netdev/list/?series=36495
>
> Then, we won't have to take net_rwsem in call_netevent_notifiers().
>
> But since the patchset is not in kernel, let's just revert net_rwsem
> for now, and I'll resubmit it later (after the above patchset).
>
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Or, if https://patchwork.ozlabs.org/project/netdev/list/?series=36495
is ok enough to go in kernel in a little while, I'll make another fix
(removing down_read(&net_rwsem) from {,un}register_netdevice_notifiers()).
Please, let me know if some other actions are required.
Thanks,
Kirill
> ---
> drivers/infiniband/core/roce_gid_mgmt.c | 2 --
> include/linux/rtnetlink.h | 1 -
> include/net/net_namespace.h | 1 -
> net/core/dev.c | 5 -----
> net/core/fib_notifier.c | 2 --
> net/core/net_namespace.c | 18 +++++-------------
> net/core/rtnetlink.c | 5 -----
> net/netfilter/nf_conntrack_core.c | 4 ++--
> net/openvswitch/datapath.c | 4 ++--
> net/wireless/wext-core.c | 6 ++++--
> security/selinux/include/xfrm.h | 4 ++--
> 11 files changed, 15 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
> index cc2966380c0c..5a52ec77940a 100644
> --- a/drivers/infiniband/core/roce_gid_mgmt.c
> +++ b/drivers/infiniband/core/roce_gid_mgmt.c
> @@ -403,12 +403,10 @@ static void enum_all_gids_of_dev_cb(struct ib_device *ib_dev,
> * our feet
> */
> rtnl_lock();
> - down_read(&net_rwsem);
> for_each_net(net)
> for_each_netdev(net, ndev)
> if (is_eth_port_of_netdev(ib_dev, port, rdma_ndev, ndev))
> add_netdev_ips(ib_dev, port, rdma_ndev, ndev);
> - up_read(&net_rwsem);
> rtnl_unlock();
> }
>
> diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
> index 5225832bd6ff..c7d1e4689325 100644
> --- a/include/linux/rtnetlink.h
> +++ b/include/linux/rtnetlink.h
> @@ -37,7 +37,6 @@ extern int rtnl_lock_killable(void);
>
> extern wait_queue_head_t netdev_unregistering_wq;
> extern struct rw_semaphore pernet_ops_rwsem;
> -extern struct rw_semaphore net_rwsem;
>
> #ifdef CONFIG_PROVE_LOCKING
> extern bool lockdep_rtnl_is_held(void);
> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> index 47e35cce3b64..1ab4f920f109 100644
> --- a/include/net/net_namespace.h
> +++ b/include/net/net_namespace.h
> @@ -291,7 +291,6 @@ static inline struct net *read_pnet(const possible_net_t *pnet)
> #endif
> }
>
> -/* Protected by net_rwsem */
> #define for_each_net(VAR) \
> list_for_each_entry(VAR, &net_namespace_list, list)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index eca5458b2753..e13807b5c84d 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1629,7 +1629,6 @@ int register_netdevice_notifier(struct notifier_block *nb)
> goto unlock;
> if (dev_boot_phase)
> goto unlock;
> - down_read(&net_rwsem);
> for_each_net(net) {
> for_each_netdev(net, dev) {
> err = call_netdevice_notifier(nb, NETDEV_REGISTER, dev);
> @@ -1643,7 +1642,6 @@ int register_netdevice_notifier(struct notifier_block *nb)
> call_netdevice_notifier(nb, NETDEV_UP, dev);
> }
> }
> - up_read(&net_rwsem);
>
> unlock:
> rtnl_unlock();
> @@ -1666,7 +1664,6 @@ int register_netdevice_notifier(struct notifier_block *nb)
> }
>
> outroll:
> - up_read(&net_rwsem);
> raw_notifier_chain_unregister(&netdev_chain, nb);
> goto unlock;
> }
> @@ -1697,7 +1694,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
> if (err)
> goto unlock;
>
> - down_read(&net_rwsem);
> for_each_net(net) {
> for_each_netdev(net, dev) {
> if (dev->flags & IFF_UP) {
> @@ -1708,7 +1704,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
> call_netdevice_notifier(nb, NETDEV_UNREGISTER, dev);
> }
> }
> - up_read(&net_rwsem);
> unlock:
> rtnl_unlock();
> return err;
> diff --git a/net/core/fib_notifier.c b/net/core/fib_notifier.c
> index 13a40b831d6d..b793b523aba3 100644
> --- a/net/core/fib_notifier.c
> +++ b/net/core/fib_notifier.c
> @@ -39,7 +39,6 @@ static unsigned int fib_seq_sum(void)
> struct net *net;
>
> rtnl_lock();
> - down_read(&net_rwsem);
> for_each_net(net) {
> rcu_read_lock();
> list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) {
> @@ -50,7 +49,6 @@ static unsigned int fib_seq_sum(void)
> }
> rcu_read_unlock();
> }
> - up_read(&net_rwsem);
> rtnl_unlock();
>
> return fib_seq;
> diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> index 7fdf321d4997..b5796d17a302 100644
> --- a/net/core/net_namespace.c
> +++ b/net/core/net_namespace.c
> @@ -33,10 +33,6 @@ static struct list_head *first_device = &pernet_list;
> LIST_HEAD(net_namespace_list);
> EXPORT_SYMBOL_GPL(net_namespace_list);
>
> -/* Protects net_namespace_list. Nests iside rtnl_lock() */
> -DECLARE_RWSEM(net_rwsem);
> -EXPORT_SYMBOL_GPL(net_rwsem);
> -
> struct net init_net = {
> .count = REFCOUNT_INIT(1),
> .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head),
> @@ -313,9 +309,9 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
> if (error < 0)
> goto out_undo;
> }
> - down_write(&net_rwsem);
> + rtnl_lock();
> list_add_tail_rcu(&net->list, &net_namespace_list);
> - up_write(&net_rwsem);
> + rtnl_unlock();
> out:
> return error;
>
> @@ -454,7 +450,7 @@ static void unhash_nsid(struct net *net, struct net *last)
> * and this work is the only process, that may delete
> * a net from net_namespace_list. So, when the below
> * is executing, the list may only grow. Thus, we do not
> - * use for_each_net_rcu() or net_rwsem.
> + * use for_each_net_rcu() or rtnl_lock().
> */
> for_each_net(tmp) {
> int id;
> @@ -489,7 +485,7 @@ static void cleanup_net(struct work_struct *work)
> down_read(&pernet_ops_rwsem);
>
> /* Don't let anyone else find us. */
> - down_write(&net_rwsem);
> + rtnl_lock();
> llist_for_each_entry(net, net_kill_list, cleanup_list)
> list_del_rcu(&net->list);
> /* Cache last net. After we unlock rtnl, no one new net
> @@ -503,7 +499,7 @@ static void cleanup_net(struct work_struct *work)
> * useless anyway, as netns_ids are destroyed there.
> */
> last = list_last_entry(&net_namespace_list, struct net, list);
> - up_write(&net_rwsem);
> + rtnl_unlock();
>
> llist_for_each_entry(net, net_kill_list, cleanup_list) {
> unhash_nsid(net, last);
> @@ -904,9 +900,6 @@ static int __register_pernet_operations(struct list_head *list,
>
> list_add_tail(&ops->list, list);
> if (ops->init || (ops->id && ops->size)) {
> - /* We held write locked pernet_ops_rwsem, and parallel
> - * setup_net() and cleanup_net() are not possible.
> - */
> for_each_net(net) {
> error = ops_init(ops, net);
> if (error)
> @@ -930,7 +923,6 @@ static void __unregister_pernet_operations(struct pernet_operations *ops)
> LIST_HEAD(net_exit_list);
>
> list_del(&ops->list);
> - /* See comment in __register_pernet_operations() */
> for_each_net(net)
> list_add_tail(&net->exit_list, &net_exit_list);
> ops_exit_list(ops, &net_exit_list);
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index e86b28482ca7..2d3949789cef 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -418,11 +418,9 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops)
> {
> struct net *net;
>
> - down_read(&net_rwsem);
> for_each_net(net) {
> __rtnl_kill_links(net, ops);
> }
> - up_read(&net_rwsem);
> list_del(&ops->list);
> }
> EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
> @@ -440,9 +438,6 @@ static void rtnl_lock_unregistering_all(void)
> for (;;) {
> unregistering = false;
> rtnl_lock();
> - /* We held write locked pernet_ops_rwsem, and parallel
> - * setup_net() and cleanup_net() are not possible.
> - */
> for_each_net(net) {
> if (net->dev_unreg_count > 0) {
> unregistering = true;
> diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> index 41ff04ee2554..705198de671d 100644
> --- a/net/netfilter/nf_conntrack_core.c
> +++ b/net/netfilter/nf_conntrack_core.c
> @@ -1763,14 +1763,14 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data), void *data)
> {
> struct net *net;
>
> - down_read(&net_rwsem);
> + rtnl_lock();
> for_each_net(net) {
> if (atomic_read(&net->ct.count) == 0)
> continue;
> __nf_ct_unconfirmed_destroy(net);
> nf_queue_nf_hook_drop(net);
> }
> - up_read(&net_rwsem);
> + rtnl_unlock();
>
> /* Need to wait for netns cleanup worker to finish, if its
> * running -- it might have deleted a net namespace from
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index 015e24e08909..ef38e5aecd28 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -2363,10 +2363,10 @@ static void __net_exit ovs_exit_net(struct net *dnet)
> list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
> __dp_destroy(dp);
>
> - down_read(&net_rwsem);
> + rtnl_lock();
> for_each_net(net)
> list_vports_from_net(net, dnet, &head);
> - up_read(&net_rwsem);
> + rtnl_unlock();
>
> /* Detach all vports from given namespace. */
> list_for_each_entry_safe(vport, vport_next, &head, detach_list) {
> diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
> index 5e677dac2a0c..9efbfc753347 100644
> --- a/net/wireless/wext-core.c
> +++ b/net/wireless/wext-core.c
> @@ -347,13 +347,13 @@ void wireless_nlevent_flush(void)
> struct sk_buff *skb;
> struct net *net;
>
> - down_read(&net_rwsem);
> + ASSERT_RTNL();
> +
> for_each_net(net) {
> while ((skb = skb_dequeue(&net->wext_nlevents)))
> rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
> GFP_KERNEL);
> }
> - up_read(&net_rwsem);
> }
> EXPORT_SYMBOL_GPL(wireless_nlevent_flush);
>
> @@ -410,7 +410,9 @@ subsys_initcall(wireless_nlevent_init);
> /* Process events generated by the wireless layer or the driver. */
> static void wireless_nlevent_process(struct work_struct *work)
> {
> + rtnl_lock();
> wireless_nlevent_flush();
> + rtnl_unlock();
> }
>
> static DECLARE_WORK(wireless_nlevent_work, wireless_nlevent_process);
> diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
> index a0b465316292..1f173a7a4daa 100644
> --- a/security/selinux/include/xfrm.h
> +++ b/security/selinux/include/xfrm.h
> @@ -47,10 +47,10 @@ static inline void selinux_xfrm_notify_policyload(void)
> {
> struct net *net;
>
> - down_read(&net_rwsem);
> + rtnl_lock();
> for_each_net(net)
> rt_genid_bump_all(net);
> - up_read(&net_rwsem);
> + rtnl_unlock();
> }
> #else
> static inline int selinux_xfrm_enabled(void)
>
^ permalink raw reply
* Re: [PATCH] netfilter: ipset: Use is_zero_ether_addr instead of static and memcmp
From: Pablo Neira Ayuso @ 2018-03-30 9:54 UTC (permalink / raw)
To: Joe Perches
Cc: linux-kernel, Jozsef Kadlecsik, Florian Westphal, David S. Miller,
netfilter-devel, coreteam, netdev
In-Reply-To: <687a4edaed07441681d3bfe3b63aa4feb55b9d61.1521567319.git.joe@perches.com>
On Tue, Mar 20, 2018 at 10:35:47AM -0700, Joe Perches wrote:
> To make the test a bit clearer and to reduce object size a little.
>
> Miscellanea:
>
> o remove now unnecessary static const array
>
> $ size ip_set_hash_mac.o*
> text data bss dec hex filename
> 22822 4619 64 27505 6b71 ip_set_hash_mac.o.allyesconfig.new
> 22932 4683 64 27679 6c1f ip_set_hash_mac.o.allyesconfig.old
> 10443 1040 0 11483 2cdb ip_set_hash_mac.o.defconfig.new
> 10507 1040 0 11547 2d1b ip_set_hash_mac.o.defconfig.old
Applied, thanks Joe.
^ permalink raw reply
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