Netdev List
 help / color / mirror / Atom feed
* [PATCH 08/17] netfilter: nf_log: fix sparse warning in nf_logger_find_get()
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

net/netfilter/nf_log.c:157:16: warning: incorrect type in assignment (different address spaces)
net/netfilter/nf_log.c:157:16:    expected struct nf_logger *logger
net/netfilter/nf_log.c:157:16:    got struct nf_logger [noderef] <asn:4>*<noident>

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_log.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 9562e39..49a6417 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -154,8 +154,7 @@ int nf_logger_find_get(int pf, enum nf_log_type type)
 	struct nf_logger *logger;
 	int ret = -ENOENT;
 
-	logger = loggers[pf][type];
-	if (logger == NULL)
+	if (rcu_access_pointer(loggers[pf][type]) == NULL)
 		request_module("nf-logger-%u-%u", pf, type);
 
 	rcu_read_lock();
-- 
1.7.10.4

^ permalink raw reply related

* Re: [patch net-next] tc_vlan: fix type of tcfv_push_vid
From: Jamal Hadi Salim @ 2014-11-24 13:25 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem
In-Reply-To: <1416825026-4628-1-git-send-email-jiri@resnulli.us>

On 11/24/14 05:30, Jiri Pirko wrote:
> Should be u16. So fix it to kill the sparse warning.
>
> Fixes: c7e2b9689ef8136 "sched: introduce vlan action"
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
>   include/net/tc_act/tc_vlan.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
> index c809c1d..93b70ad 100644
> --- a/include/net/tc_act/tc_vlan.h
> +++ b/include/net/tc_act/tc_vlan.h
> @@ -18,7 +18,7 @@
>   struct tcf_vlan {
>   	struct tcf_common	common;
>   	int			tcfv_action;
> -	__be16			tcfv_push_vid;
> +	u16			tcfv_push_vid;
>   	__be16			tcfv_push_proto;


User space sends you this in be, no? I thought it was fine
the way it is. Isnt __be16 just an annotation?

cheers,
jamal

^ permalink raw reply

* [PATCH 09/17] netfilter: nft_meta: add cgroup support
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Ana Rey <anarey@gmail.com>

This allows you to filter traffic by process control group (cgroup).

Signed-off-by: Ana Rey <anarey@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/uapi/linux/netfilter/nf_tables.h |    2 ++
 net/netfilter/nft_meta.c                 |    7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 16f62a5..832bc46 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -579,6 +579,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_CPU: cpu id through smp_processor_id()
  * @NFT_META_IIFGROUP: packet input interface group
  * @NFT_META_OIFGROUP: packet output interface group
+ * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid)
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -604,6 +605,7 @@ enum nft_meta_keys {
 	NFT_META_CPU,
 	NFT_META_IIFGROUP,
 	NFT_META_OIFGROUP,
+	NFT_META_CGROUP,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 1e7c076..e99911e 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -165,6 +165,12 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 			goto err;
 		dest->data[0] = out->group;
 		break;
+	case NFT_META_CGROUP:
+		if (skb->sk == NULL)
+			break;
+
+		dest->data[0] = skb->sk->sk_classid;
+		break;
 	default:
 		WARN_ON(1);
 		goto err;
@@ -240,6 +246,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
 	case NFT_META_CPU:
 	case NFT_META_IIFGROUP:
 	case NFT_META_OIFGROUP:
+	case NFT_META_CGROUP:
 		break;
 	default:
 		return -EOPNOTSUPP;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 10/17] netfilter: fix unmet dependencies in NETFILTER_XT_TARGET_REDIRECT
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

warning: (NETFILTER_XT_TARGET_REDIRECT) selects NF_NAT_REDIRECT_IPV4 which has unmet direct dependencies (NET && INET && NETFILTER && NF_NAT_IPV4)

warning: (NETFILTER_XT_TARGET_REDIRECT) selects NF_NAT_REDIRECT_IPV6 which has unmet direct dependencies (NET && INET && IPV6 && NETFILTER && NF_NAT_IPV6)

Fixes: 8b13edd ("netfilter: refactor NAT redirect IPv4 to use it from nf_tables")
Fixes: 9de920e ("netfilter: refactor NAT redirect IPv6 code to use it from nf_tables")
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 373486a..57f15a9 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -844,8 +844,8 @@ config NETFILTER_XT_TARGET_RATEEST
 config NETFILTER_XT_TARGET_REDIRECT
 	tristate "REDIRECT target support"
 	depends on NF_NAT
-	select NF_NAT_REDIRECT_IPV4
-	select NF_NAT_REDIRECT_IPV6 if IP6_NF_IPTABLES
+	select NF_NAT_REDIRECT_IPV4 if NF_NAT_IPV4
+	select NF_NAT_REDIRECT_IPV6 if NF_NAT_IPV6
 	---help---
 	REDIRECT is a special case of NAT: all incoming connections are
 	mapped onto the incoming interface's address, causing the packets to
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 11/17] netfilter: nft_redir: fix sparse warnings
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

>> net/netfilter/nft_redir.c:39:26: sparse: incorrect type in assignment (different base types)
   net/netfilter/nft_redir.c:39:26:    expected unsigned int [unsigned] [usertype] nla_be32
   net/netfilter/nft_redir.c:39:26:    got restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:46:34: sparse: incorrect type in assignment (different base types)
   net/netfilter/nft_redir.c:46:34:    expected unsigned int [unsigned] [usertype] nla_be32
   net/netfilter/nft_redir.c:46:34:    got restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32
>> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32

Fixes: e9105f1 ("netfilter: nf_tables: add new expression nft_redir")
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nft_redir.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index e27b4e3..9e8093f 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -28,7 +28,6 @@ int nft_redir_init(const struct nft_ctx *ctx,
 		   const struct nlattr * const tb[])
 {
 	struct nft_redir *priv = nft_expr_priv(expr);
-	u32 nla_be32;
 	int err;
 
 	err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
@@ -36,15 +35,17 @@ int nft_redir_init(const struct nft_ctx *ctx,
 		return err;
 
 	if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
-		nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]);
-		priv->sreg_proto_min = ntohl(nla_be32);
+		priv->sreg_proto_min =
+			ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
+
 		err = nft_validate_input_register(priv->sreg_proto_min);
 		if (err < 0)
 			return err;
 
 		if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
-			nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]);
-			priv->sreg_proto_max = ntohl(nla_be32);
+			priv->sreg_proto_max =
+				ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]));
+
 			err = nft_validate_input_register(priv->sreg_proto_max);
 			if (err < 0)
 				return err;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 13/17] netfilter: nfnetlink_log: remove unnecessary error messages
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

In case of OOM, there's nothing userspace can do.

If there's no room to put the payload in __build_packet_message(),
jump to nla_put_failure which already performs the corresponding
error reporting.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nfnetlink_log.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b1e3a05..51996ec 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -334,9 +334,6 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
 
 			skb = nfnetlink_alloc_skb(net, pkt_size,
 						  peer_portid, GFP_ATOMIC);
-			if (!skb)
-				pr_err("nfnetlink_log: can't even alloc %u bytes\n",
-				       pkt_size);
 		}
 	}
 
@@ -568,10 +565,8 @@ __build_packet_message(struct nfnl_log_net *log,
 		struct nlattr *nla;
 		int size = nla_attr_size(data_len);
 
-		if (skb_tailroom(inst->skb) < nla_total_size(data_len)) {
-			printk(KERN_WARNING "nfnetlink_log: no tailroom!\n");
-			return -1;
-		}
+		if (skb_tailroom(inst->skb) < nla_total_size(data_len))
+			goto nla_put_failure;
 
 		nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len));
 		nla->nla_type = NFULA_PAYLOAD;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 12/17] netfilter: fix various sparse warnings
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Florian Westphal <fw@strlen.de>

net/bridge/br_netfilter.c:870:6: symbol 'br_netfilter_enable' was not declared. Should it be static?
  no; add include
net/ipv4/netfilter/nft_reject_ipv4.c:22:6: symbol 'nft_reject_ipv4_eval' was not declared. Should it be static?
  yes
net/ipv6/netfilter/nf_reject_ipv6.c:16:6: symbol 'nf_send_reset6' was not declared. Should it be static?
  no; add include
net/ipv6/netfilter/nft_reject_ipv6.c:22:6: symbol 'nft_reject_ipv6_eval' was not declared. Should it be static?
  yes
net/netfilter/core.c:33:32: symbol 'nf_ipv6_ops' was not declared. Should it be static?
  no; add include
net/netfilter/xt_DSCP.c:40:57: cast truncates bits from constant value (ffffff03 becomes 3)
net/netfilter/xt_DSCP.c:57:59: cast truncates bits from constant value (ffffff03 becomes 3)
  add __force, 3 is what we want.
net/ipv4/netfilter/nf_log_arp.c:77:6: symbol 'nf_log_arp_packet' was not declared. Should it be static?
  yes
net/ipv4/netfilter/nf_reject_ipv4.c:17:6: symbol 'nf_send_reset' was not declared. Should it be static?
  no; add include

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/bridge/br_netfilter.c            |    1 +
 net/ipv4/netfilter/nf_log_arp.c      |   12 ++++++------
 net/ipv4/netfilter/nf_reject_ipv4.c  |    1 +
 net/ipv4/netfilter/nft_reject_ipv4.c |    7 +++----
 net/ipv6/netfilter/nf_reject_ipv6.c  |    1 +
 net/ipv6/netfilter/nft_reject_ipv6.c |    7 +++----
 net/netfilter/core.c                 |    1 +
 net/netfilter/xt_DSCP.c              |    6 ++++--
 8 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 1bada53..f81dc33 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -35,6 +35,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/route.h>
+#include <net/netfilter/br_netfilter.h>
 
 #include <asm/uaccess.h>
 #include "br_private.h"
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
index 0c8799a..d059182 100644
--- a/net/ipv4/netfilter/nf_log_arp.c
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -75,12 +75,12 @@ static void dump_arp_packet(struct nf_log_buf *m,
 		       ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst);
 }
 
-void nf_log_arp_packet(struct net *net, u_int8_t pf,
-		      unsigned int hooknum, const struct sk_buff *skb,
-		      const struct net_device *in,
-		      const struct net_device *out,
-		      const struct nf_loginfo *loginfo,
-		      const char *prefix)
+static void nf_log_arp_packet(struct net *net, u_int8_t pf,
+			      unsigned int hooknum, const struct sk_buff *skb,
+			      const struct net_device *in,
+			      const struct net_device *out,
+			      const struct nf_loginfo *loginfo,
+			      const char *prefix)
 {
 	struct nf_log_buf *m;
 
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
index 92b303d..cdcb9a5 100644
--- a/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -11,6 +11,7 @@
 #include <net/tcp.h>
 #include <net/route.h>
 #include <net/dst.h>
+#include <net/netfilter/ipv4/nf_reject.h>
 #include <linux/netfilter_ipv4.h>
 
 /* Send RST reply */
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index ed33299..d729542 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -19,9 +19,9 @@
 #include <net/netfilter/ipv4/nf_reject.h>
 #include <net/netfilter/nft_reject.h>
 
-void nft_reject_ipv4_eval(const struct nft_expr *expr,
-			  struct nft_data data[NFT_REG_MAX + 1],
-			  const struct nft_pktinfo *pkt)
+static void nft_reject_ipv4_eval(const struct nft_expr *expr,
+				 struct nft_data data[NFT_REG_MAX + 1],
+				 const struct nft_pktinfo *pkt)
 {
 	struct nft_reject *priv = nft_expr_priv(expr);
 
@@ -36,7 +36,6 @@ void nft_reject_ipv4_eval(const struct nft_expr *expr,
 
 	data[NFT_REG_VERDICT].verdict = NF_DROP;
 }
-EXPORT_SYMBOL_GPL(nft_reject_ipv4_eval);
 
 static struct nft_expr_type nft_reject_ipv4_type;
 static const struct nft_expr_ops nft_reject_ipv4_ops = {
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
index 20d9def..87576ff 100644
--- a/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -11,6 +11,7 @@
 #include <net/ip6_route.h>
 #include <net/ip6_fib.h>
 #include <net/ip6_checksum.h>
+#include <net/netfilter/ipv6/nf_reject.h>
 #include <linux/netfilter_ipv6.h>
 
 void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 0bc19fa..f732859 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -19,9 +19,9 @@
 #include <net/netfilter/nft_reject.h>
 #include <net/netfilter/ipv6/nf_reject.h>
 
-void nft_reject_ipv6_eval(const struct nft_expr *expr,
-			  struct nft_data data[NFT_REG_MAX + 1],
-			  const struct nft_pktinfo *pkt)
+static void nft_reject_ipv6_eval(const struct nft_expr *expr,
+				 struct nft_data data[NFT_REG_MAX + 1],
+				 const struct nft_pktinfo *pkt)
 {
 	struct nft_reject *priv = nft_expr_priv(expr);
 	struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
@@ -38,7 +38,6 @@ void nft_reject_ipv6_eval(const struct nft_expr *expr,
 
 	data[NFT_REG_VERDICT].verdict = NF_DROP;
 }
-EXPORT_SYMBOL_GPL(nft_reject_ipv6_eval);
 
 static struct nft_expr_type nft_reject_ipv6_type;
 static const struct nft_expr_ops nft_reject_ipv6_ops = {
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 024a2e2..fea9ef5 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/if.h>
 #include <linux/netdevice.h>
+#include <linux/netfilter_ipv6.h>
 #include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/mutex.h>
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index ae82716..3f83d38 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -37,7 +37,8 @@ dscp_tg(struct sk_buff *skb, const struct xt_action_param *par)
 		if (!skb_make_writable(skb, sizeof(struct iphdr)))
 			return NF_DROP;
 
-		ipv4_change_dsfield(ip_hdr(skb), (__u8)(~XT_DSCP_MASK),
+		ipv4_change_dsfield(ip_hdr(skb),
+				    (__force __u8)(~XT_DSCP_MASK),
 				    dinfo->dscp << XT_DSCP_SHIFT);
 
 	}
@@ -54,7 +55,8 @@ dscp_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 		if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
 			return NF_DROP;
 
-		ipv6_change_dsfield(ipv6_hdr(skb), (__u8)(~XT_DSCP_MASK),
+		ipv6_change_dsfield(ipv6_hdr(skb),
+				    (__force __u8)(~XT_DSCP_MASK),
 				    dinfo->dscp << XT_DSCP_SHIFT);
 	}
 	return XT_CONTINUE;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 14/17] netfilter: xt_connlimit: honor conntrack zone if available
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Florian Westphal <fw@strlen.de>

Currently all the conntrack lookups are done using default zone.
In case the skb has a ct attached (e.g. template) we should use this zone
for lookups instead.  This makes connlimit work with connections assigned
to other zones.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/xt_connlimit.c |   25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index fbc66bb..29ba621 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -134,6 +134,7 @@ static bool add_hlist(struct hlist_head *head,
 static unsigned int check_hlist(struct net *net,
 				struct hlist_head *head,
 				const struct nf_conntrack_tuple *tuple,
+				u16 zone,
 				bool *addit)
 {
 	const struct nf_conntrack_tuple_hash *found;
@@ -147,8 +148,7 @@ static unsigned int check_hlist(struct net *net,
 
 	/* check the saved connections */
 	hlist_for_each_entry_safe(conn, n, head, node) {
-		found    = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE,
-						 &conn->tuple);
+		found = nf_conntrack_find_get(net, zone, &conn->tuple);
 		if (found == NULL) {
 			hlist_del(&conn->node);
 			kmem_cache_free(connlimit_conn_cachep, conn);
@@ -201,7 +201,7 @@ static unsigned int
 count_tree(struct net *net, struct rb_root *root,
 	   const struct nf_conntrack_tuple *tuple,
 	   const union nf_inet_addr *addr, const union nf_inet_addr *mask,
-	   u8 family)
+	   u8 family, u16 zone)
 {
 	struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES];
 	struct rb_node **rbnode, *parent;
@@ -229,7 +229,7 @@ count_tree(struct net *net, struct rb_root *root,
 		} else {
 			/* same source network -> be counted! */
 			unsigned int count;
-			count = check_hlist(net, &rbconn->hhead, tuple, &addit);
+			count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit);
 
 			tree_nodes_free(root, gc_nodes, gc_count);
 			if (!addit)
@@ -245,7 +245,7 @@ count_tree(struct net *net, struct rb_root *root,
 			continue;
 
 		/* only used for GC on hhead, retval and 'addit' ignored */
-		check_hlist(net, &rbconn->hhead, tuple, &addit);
+		check_hlist(net, &rbconn->hhead, tuple, zone, &addit);
 		if (hlist_empty(&rbconn->hhead))
 			gc_nodes[gc_count++] = rbconn;
 	}
@@ -290,7 +290,7 @@ static int count_them(struct net *net,
 		      const struct nf_conntrack_tuple *tuple,
 		      const union nf_inet_addr *addr,
 		      const union nf_inet_addr *mask,
-		      u_int8_t family)
+		      u_int8_t family, u16 zone)
 {
 	struct rb_root *root;
 	int count;
@@ -306,7 +306,7 @@ static int count_them(struct net *net,
 
 	spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
 
-	count = count_tree(net, root, tuple, addr, mask, family);
+	count = count_tree(net, root, tuple, addr, mask, family, zone);
 
 	spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
 
@@ -324,13 +324,16 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	enum ip_conntrack_info ctinfo;
 	const struct nf_conn *ct;
 	unsigned int connections;
+	u16 zone = NF_CT_DEFAULT_ZONE;
 
 	ct = nf_ct_get(skb, &ctinfo);
-	if (ct != NULL)
+	if (ct != NULL) {
 		tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-	else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
-				    par->family, &tuple))
+		zone = nf_ct_zone(ct);
+	} else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
+				    par->family, &tuple)) {
 		goto hotdrop;
+	}
 
 	if (par->family == NFPROTO_IPV6) {
 		const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -343,7 +346,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	}
 
 	connections = count_them(net, info->data, tuple_ptr, &addr,
-	                         &info->mask, par->family);
+	                         &info->mask, par->family, zone);
 	if (connections == 0)
 		/* kmalloc failed, drop it entirely */
 		goto hotdrop;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 15/17] netfilter: nf_conntrack_h323: lookup route from proper net namespace
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Vasily Averin <vvs@parallels.com>

Signed-off-by: Vasily Averin <vvs@parallels.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_conntrack_h323_main.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 3a3a60b..1d69f5b 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -728,7 +728,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
 
 /* If the calling party is on the same side of the forward-to party,
  * we don't need to track the second call */
-static int callforward_do_filter(const union nf_inet_addr *src,
+static int callforward_do_filter(struct net *net,
+				 const union nf_inet_addr *src,
 				 const union nf_inet_addr *dst,
 				 u_int8_t family)
 {
@@ -750,9 +751,9 @@ static int callforward_do_filter(const union nf_inet_addr *src,
 
 		memset(&fl2, 0, sizeof(fl2));
 		fl2.daddr = dst->ip;
-		if (!afinfo->route(&init_net, (struct dst_entry **)&rt1,
+		if (!afinfo->route(net, (struct dst_entry **)&rt1,
 				   flowi4_to_flowi(&fl1), false)) {
-			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
+			if (!afinfo->route(net, (struct dst_entry **)&rt2,
 					   flowi4_to_flowi(&fl2), false)) {
 				if (rt_nexthop(rt1, fl1.daddr) ==
 				    rt_nexthop(rt2, fl2.daddr) &&
@@ -774,9 +775,9 @@ static int callforward_do_filter(const union nf_inet_addr *src,
 
 		memset(&fl2, 0, sizeof(fl2));
 		fl2.daddr = dst->in6;
-		if (!afinfo->route(&init_net, (struct dst_entry **)&rt1,
+		if (!afinfo->route(net, (struct dst_entry **)&rt1,
 				   flowi6_to_flowi(&fl1), false)) {
-			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
+			if (!afinfo->route(net, (struct dst_entry **)&rt2,
 					   flowi6_to_flowi(&fl2), false)) {
 				if (ipv6_addr_equal(rt6_nexthop(rt1),
 						    rt6_nexthop(rt2)) &&
@@ -807,6 +808,7 @@ static int expect_callforwarding(struct sk_buff *skb,
 	__be16 port;
 	union nf_inet_addr addr;
 	struct nf_conntrack_expect *exp;
+	struct net *net = nf_ct_net(ct);
 	typeof(nat_callforwarding_hook) nat_callforwarding;
 
 	/* Read alternativeAddress */
@@ -816,7 +818,7 @@ static int expect_callforwarding(struct sk_buff *skb,
 	/* If the calling party is on the same side of the forward-to party,
 	 * we don't need to track the second call */
 	if (callforward_filter &&
-	    callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
+	    callforward_do_filter(net, &addr, &ct->tuplehash[!dir].tuple.src.u3,
 				  nf_ct_l3num(ct))) {
 		pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
 		return 0;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 17/17] netfilter: nfnetlink_log: Make use of pr_fmt where applicable
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Marcelo Leitner <mleitner@redhat.com>

Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nfnetlink_log.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 51996ec..405cf58 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -12,6 +12,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
@@ -1063,19 +1066,19 @@ static int __init nfnetlink_log_init(void)
 	netlink_register_notifier(&nfulnl_rtnl_notifier);
 	status = nfnetlink_subsys_register(&nfulnl_subsys);
 	if (status < 0) {
-		pr_err("log: failed to create netlink socket\n");
+		pr_err("failed to create netlink socket\n");
 		goto cleanup_netlink_notifier;
 	}
 
 	status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
 	if (status < 0) {
-		pr_err("log: failed to register logger\n");
+		pr_err("failed to register logger\n");
 		goto cleanup_subsys;
 	}
 
 	status = register_pernet_subsys(&nfnl_log_net_ops);
 	if (status < 0) {
-		pr_err("log: failed to register pernet ops\n");
+		pr_err("failed to register pernet ops\n");
 		goto cleanup_logger;
 	}
 	return status;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 03/17] netfilter: nf_tables: add new expression nft_redir
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Arturo Borrero <arturo.borrero.glez@gmail.com>

This new expression provides NAT in the redirect flavour, which is to
redirect packets to local machine.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nft_redir.h        |   21 +++++++
 include/uapi/linux/netfilter/nf_tables.h |   16 +++++
 net/ipv4/netfilter/Kconfig               |    9 +++
 net/ipv4/netfilter/Makefile              |    1 +
 net/ipv4/netfilter/nft_redir_ipv4.c      |   77 +++++++++++++++++++++++
 net/ipv6/netfilter/Kconfig               |    9 +++
 net/ipv6/netfilter/Makefile              |    1 +
 net/ipv6/netfilter/nft_redir_ipv6.c      |   77 +++++++++++++++++++++++
 net/netfilter/Kconfig                    |    9 +++
 net/netfilter/Makefile                   |    1 +
 net/netfilter/nft_redir.c                |   98 ++++++++++++++++++++++++++++++
 11 files changed, 319 insertions(+)
 create mode 100644 include/net/netfilter/nft_redir.h
 create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c
 create mode 100644 net/ipv6/netfilter/nft_redir_ipv6.c
 create mode 100644 net/netfilter/nft_redir.c

diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h
new file mode 100644
index 0000000..a2d6754
--- /dev/null
+++ b/include/net/netfilter/nft_redir.h
@@ -0,0 +1,21 @@
+#ifndef _NFT_REDIR_H_
+#define _NFT_REDIR_H_
+
+struct nft_redir {
+	enum nft_registers	sreg_proto_min:8;
+	enum nft_registers	sreg_proto_max:8;
+	u16			flags;
+};
+
+extern const struct nla_policy nft_redir_policy[];
+
+int nft_redir_init(const struct nft_ctx *ctx,
+		   const struct nft_expr *expr,
+		   const struct nlattr * const tb[]);
+
+int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr);
+
+int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
+		       const struct nft_data **data);
+
+#endif /* _NFT_REDIR_H_ */
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index f31fe7b..16f62a5 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -838,6 +838,22 @@ enum nft_masq_attributes {
 #define NFTA_MASQ_MAX		(__NFTA_MASQ_MAX - 1)
 
 /**
+ * enum nft_redir_attributes - nf_tables redirect expression netlink attributes
+ *
+ * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
+ * @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
+ * @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
+ */
+enum nft_redir_attributes {
+	NFTA_REDIR_UNSPEC,
+	NFTA_REDIR_REG_PROTO_MIN,
+	NFTA_REDIR_REG_PROTO_MAX,
+	NFTA_REDIR_FLAGS,
+	__NFTA_REDIR_MAX
+};
+#define NFTA_REDIR_MAX		(__NFTA_REDIR_MAX - 1)
+
+/**
  * enum nft_gen_attributes - nf_tables ruleset generation attributes
  *
  * @NFTA_GEN_ID: Ruleset generation ID (NLA_U32)
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index a300e2c..8358b2d 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -119,6 +119,15 @@ config NFT_MASQ_IPV4
 	  This is the expression that provides IPv4 masquerading support for
 	  nf_tables.
 
+config NFT_REDIR_IPV4
+	tristate "IPv4 redirect support for nf_tables"
+	depends on NF_TABLES_IPV4
+	depends on NFT_REDIR
+	select NF_NAT_REDIRECT_IPV4
+	help
+	  This is the expression that provides IPv4 redirect support for
+	  nf_tables.
+
 config NF_NAT_SNMP_BASIC
 	tristate "Basic SNMP-ALG support"
 	depends on NF_CONNTRACK_SNMP
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 34e436c..902bcd1 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o
 obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
 obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
 obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o
+obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o
 obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
 
 # generic IP tables 
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
new file mode 100644
index 0000000..643c596
--- /dev/null
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_nat.h>
+#include <net/netfilter/ipv4/nf_nat_redirect.h>
+#include <net/netfilter/nft_redir.h>
+
+static void nft_redir_ipv4_eval(const struct nft_expr *expr,
+				struct nft_data data[NFT_REG_MAX + 1],
+				const struct nft_pktinfo *pkt)
+{
+	struct nft_redir *priv = nft_expr_priv(expr);
+	struct nf_nat_ipv4_multi_range_compat mr;
+	unsigned int verdict;
+
+	memset(&mr, 0, sizeof(mr));
+	if (priv->sreg_proto_min) {
+		mr.range[0].min.all = (__force __be16)
+					data[priv->sreg_proto_min].data[0];
+		mr.range[0].max.all = (__force __be16)
+					data[priv->sreg_proto_max].data[0];
+		mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+	}
+
+	mr.range[0].flags |= priv->flags;
+
+	verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum);
+	data[NFT_REG_VERDICT].verdict = verdict;
+}
+
+static struct nft_expr_type nft_redir_ipv4_type;
+static const struct nft_expr_ops nft_redir_ipv4_ops = {
+	.type		= &nft_redir_ipv4_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_redir)),
+	.eval		= nft_redir_ipv4_eval,
+	.init		= nft_redir_init,
+	.dump		= nft_redir_dump,
+	.validate	= nft_redir_validate,
+};
+
+static struct nft_expr_type nft_redir_ipv4_type __read_mostly = {
+	.family		= NFPROTO_IPV4,
+	.name		= "redir",
+	.ops		= &nft_redir_ipv4_ops,
+	.policy		= nft_redir_policy,
+	.maxattr	= NFTA_REDIR_MAX,
+	.owner		= THIS_MODULE,
+};
+
+static int __init nft_redir_ipv4_module_init(void)
+{
+	return nft_register_expr(&nft_redir_ipv4_type);
+}
+
+static void __exit nft_redir_ipv4_module_exit(void)
+{
+	nft_unregister_expr(&nft_redir_ipv4_type);
+}
+
+module_init(nft_redir_ipv4_module_init);
+module_exit(nft_redir_ipv4_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
+MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir");
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 462eebb..0dbe5c7 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -97,6 +97,15 @@ config NFT_MASQ_IPV6
 	  This is the expression that provides IPv4 masquerading support for
 	  nf_tables.
 
+config NFT_REDIR_IPV6
+	tristate "IPv6 redirect support for nf_tables"
+	depends on NF_TABLES_IPV6
+	depends on NFT_REDIR
+	select NF_NAT_REDIRECT_IPV6
+	help
+	  This is the expression that provides IPv4 redirect support for
+	  nf_tables.
+
 endif # NF_NAT_IPV6
 
 config IP6_NF_IPTABLES
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 6c2baab..d2ac9f5 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
 obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o
 obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
 obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o
+obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o
 
 # matches
 obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c
new file mode 100644
index 0000000..83420ee
--- /dev/null
+++ b/net/ipv6/netfilter/nft_redir_ipv6.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_nat.h>
+#include <net/netfilter/nft_redir.h>
+#include <net/netfilter/ipv6/nf_nat_redirect.h>
+
+static void nft_redir_ipv6_eval(const struct nft_expr *expr,
+				struct nft_data data[NFT_REG_MAX + 1],
+				const struct nft_pktinfo *pkt)
+{
+	struct nft_redir *priv = nft_expr_priv(expr);
+	struct nf_nat_range range;
+	unsigned int verdict;
+
+	memset(&range, 0, sizeof(range));
+	if (priv->sreg_proto_min) {
+		range.min_proto.all = (__force __be16)
+					data[priv->sreg_proto_min].data[0];
+		range.max_proto.all = (__force __be16)
+					data[priv->sreg_proto_max].data[0];
+		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+	}
+
+	range.flags |= priv->flags;
+
+	verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum);
+	data[NFT_REG_VERDICT].verdict = verdict;
+}
+
+static struct nft_expr_type nft_redir_ipv6_type;
+static const struct nft_expr_ops nft_redir_ipv6_ops = {
+	.type		= &nft_redir_ipv6_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_redir)),
+	.eval		= nft_redir_ipv6_eval,
+	.init		= nft_redir_init,
+	.dump		= nft_redir_dump,
+	.validate	= nft_redir_validate,
+};
+
+static struct nft_expr_type nft_redir_ipv6_type __read_mostly = {
+	.family		= NFPROTO_IPV6,
+	.name		= "redir",
+	.ops		= &nft_redir_ipv6_ops,
+	.policy		= nft_redir_policy,
+	.maxattr	= NFTA_REDIR_MAX,
+	.owner		= THIS_MODULE,
+};
+
+static int __init nft_redir_ipv6_module_init(void)
+{
+	return nft_register_expr(&nft_redir_ipv6_type);
+}
+
+static void __exit nft_redir_ipv6_module_exit(void)
+{
+	nft_unregister_expr(&nft_redir_ipv6_type);
+}
+
+module_init(nft_redir_ipv6_module_init);
+module_exit(nft_redir_ipv6_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
+MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 49deb4e..373486a 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -505,6 +505,15 @@ config NFT_MASQ
 	  This option adds the "masquerade" expression that you can use
 	  to perform NAT in the masquerade flavour.
 
+config NFT_REDIR
+	depends on NF_TABLES
+	depends on NF_CONNTRACK
+	depends on NF_NAT
+	tristate "Netfilter nf_tables redirect support"
+	help
+	  This options adds the "redirect" expression that you can use
+	  to perform NAT in the redirect flavour.
+
 config NFT_NAT
 	depends on NF_TABLES
 	depends on NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a9571be..f3eb468 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_NFT_HASH)		+= nft_hash.o
 obj-$(CONFIG_NFT_COUNTER)	+= nft_counter.o
 obj-$(CONFIG_NFT_LOG)		+= nft_log.o
 obj-$(CONFIG_NFT_MASQ)		+= nft_masq.o
+obj-$(CONFIG_NFT_REDIR)		+= nft_redir.o
 
 # generic X tables 
 obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
new file mode 100644
index 0000000..e27b4e3
--- /dev/null
+++ b/net/netfilter/nft_redir.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/netfilter/nf_nat.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nft_redir.h>
+
+const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = {
+	[NFTA_REDIR_REG_PROTO_MIN]	= { .type = NLA_U32 },
+	[NFTA_REDIR_REG_PROTO_MAX]	= { .type = NLA_U32 },
+	[NFTA_REDIR_FLAGS]		= { .type = NLA_U32 },
+};
+EXPORT_SYMBOL_GPL(nft_redir_policy);
+
+int nft_redir_init(const struct nft_ctx *ctx,
+		   const struct nft_expr *expr,
+		   const struct nlattr * const tb[])
+{
+	struct nft_redir *priv = nft_expr_priv(expr);
+	u32 nla_be32;
+	int err;
+
+	err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
+	if (err < 0)
+		return err;
+
+	if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
+		nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]);
+		priv->sreg_proto_min = ntohl(nla_be32);
+		err = nft_validate_input_register(priv->sreg_proto_min);
+		if (err < 0)
+			return err;
+
+		if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
+			nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]);
+			priv->sreg_proto_max = ntohl(nla_be32);
+			err = nft_validate_input_register(priv->sreg_proto_max);
+			if (err < 0)
+				return err;
+		} else {
+			priv->sreg_proto_max = priv->sreg_proto_min;
+		}
+	}
+
+	if (tb[NFTA_REDIR_FLAGS]) {
+		priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS]));
+		if (priv->flags & ~NF_NAT_RANGE_MASK)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nft_redir_init);
+
+int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+	const struct nft_redir *priv = nft_expr_priv(expr);
+
+	if (priv->sreg_proto_min) {
+		if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN,
+				 htonl(priv->sreg_proto_min)))
+			goto nla_put_failure;
+		if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX,
+				 htonl(priv->sreg_proto_max)))
+			goto nla_put_failure;
+	}
+
+	if (priv->flags != 0 &&
+	    nla_put_be32(skb, NFTA_REDIR_FLAGS, htonl(priv->flags)))
+			goto nla_put_failure;
+
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
+EXPORT_SYMBOL_GPL(nft_redir_dump);
+
+int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
+		       const struct nft_data **data)
+{
+	return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
+}
+EXPORT_SYMBOL_GPL(nft_redir_validate);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 04/17] ipvs: remove unnecessary assignment in __ip_vs_get_out_rt
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Alex Gartrell <agartrell@fb.com>

It is a precondition of the function that daddr be equal to dest->addr.ip
if dest is non-NULL, so this additional assignment is just confusing for
stupid engineers like me.

Signed-off-by: Alex Gartrell <agartrell@fb.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
 net/netfilter/ipvs/ip_vs_xmit.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 91f17c1..5efa597 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -293,7 +293,6 @@ __ip_vs_get_out_rt(int skb_af, struct sk_buff *skb, struct ip_vs_dest *dest,
 				  &dest->addr.ip, &dest_dst->dst_saddr.ip,
 				  atomic_read(&rt->dst.__refcnt));
 		}
-		daddr = dest->addr.ip;
 		if (ret_saddr)
 			*ret_saddr = dest_dst->dst_saddr.ip;
 	} else {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 16/17] netfilter: Deletion of unnecessary checks before two function calls
From: Pablo Neira Ayuso @ 2014-11-24 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1416835674-11871-1-git-send-email-pablo@netfilter.org>

From: Markus Elfring <elfring@users.sourceforge.net>

The functions free_percpu() and module_put() test whether their argument
is NULL and then return immediately. Thus the test around the call is
not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Acked-by: Julian Anastasov <ja@ssi.bg>
Acked-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/ipvs/ip_vs_ctl.c   |    3 +--
 net/netfilter/ipvs/ip_vs_pe.c    |    3 +--
 net/netfilter/ipvs/ip_vs_sched.c |    3 +--
 net/netfilter/ipvs/ip_vs_sync.c  |    3 +--
 net/netfilter/nf_tables_api.c    |    3 +--
 5 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index ac7ba68..b8295a4 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -465,8 +465,7 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc)
 
 static void ip_vs_service_free(struct ip_vs_service *svc)
 {
-	if (svc->stats.cpustats)
-		free_percpu(svc->stats.cpustats);
+	free_percpu(svc->stats.cpustats);
 	kfree(svc);
 }
 
diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c
index 1a82b29..0df17ca 100644
--- a/net/netfilter/ipvs/ip_vs_pe.c
+++ b/net/netfilter/ipvs/ip_vs_pe.c
@@ -37,8 +37,7 @@ struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name)
 			rcu_read_unlock();
 			return pe;
 		}
-		if (pe->module)
-			module_put(pe->module);
+		module_put(pe->module);
 	}
 	rcu_read_unlock();
 
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index 4dbcda6..199760c 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -104,8 +104,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
 			mutex_unlock(&ip_vs_sched_mutex);
 			return sched;
 		}
-		if (sched->module)
-			module_put(sched->module);
+		module_put(sched->module);
 	}
 
 	mutex_unlock(&ip_vs_sched_mutex);
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 7162c86..c47ffd7 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -820,8 +820,7 @@ ip_vs_conn_fill_param_sync(struct net *net, int af, union ip_vs_sync_conn *sc,
 
 		p->pe_data = kmemdup(pe_data, pe_data_len, GFP_ATOMIC);
 		if (!p->pe_data) {
-			if (p->pe->module)
-				module_put(p->pe->module);
+			module_put(p->pe->module);
 			return -ENOMEM;
 		}
 		p->pe_data_len = pe_data_len;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 1ffb253..18a9dae 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3674,8 +3674,7 @@ static int nf_tables_abort(struct sk_buff *skb)
 			break;
 		case NFT_MSG_NEWCHAIN:
 			if (nft_trans_chain_update(trans)) {
-				if (nft_trans_chain_stats(trans))
-					free_percpu(nft_trans_chain_stats(trans));
+				free_percpu(nft_trans_chain_stats(trans));
 
 				nft_trans_destroy(trans);
 			} else {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH net-next] tipc: add tipc_netlink.h to uapi Kbuild
From: richard.alpe @ 2014-11-24 13:24 UTC (permalink / raw)
  To: netdev; +Cc: Richard Alpe

From: Richard Alpe <richard.alpe@ericsson.com>

tipc_netlink.h is the user-space header for the new netlink api. It
was accidentally left out of the uapi Kbuild list when the api was
added.

Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
---
 include/uapi/linux/Kbuild | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 72298b6..a1e8175 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -389,6 +389,7 @@ header-y += times.h
 header-y += timex.h
 header-y += tiocl.h
 header-y += tipc_config.h
+header-y += tipc_netlink.h
 header-y += tipc.h
 header-y += toshiba.h
 header-y += tty_flags.h
-- 
2.1.3

^ permalink raw reply related

* net_tx_action race condition?
From: Angelo Rizzi @ 2014-11-24 13:29 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 936 bytes --]

Hi Daniel,
Here attached the patch file you required.
The problem i've found is on the declaration of 'struct softnet_data 
*sd' in function 'net_tx_action'
What happens to me (i have an embedded system based on FPGA and a NIOS2 
cpu) is that, due to compiler optimization, the content of 
'sd->completion_queue' is saved in a CPU register before interrupt 
disabling (when the instruction 'if (sd->completion_queue) {' is 
executed) and then the register contents is used for interrupt-disabled 
assignment ('clist = sd->completion_queue') instead of re-read the 
variable contents.
This seems to lead to a race condition when an interrupt modifies the 
content of 'sd->completion_queue' between these two instructions.
What i have done to avoid this situation is to change the declaration of 
'struct softnet_data *sd' to 'volatile struct softnet_data *sd' and now 
everything seems to be ok.
I hope this will help.

Regards,
Angelo


[-- Attachment #2: net_tx_action_patch --]
[-- Type: text/plain, Size: 438 bytes --]

--- linux-2.6.32.64/net/core/dev.c.orig	2014-11-24 12:52:36.103335551 +0100
+++ linux-2.6.32.64/net/core/dev.c	2014-11-24 12:52:58.863949715 +0100
@@ -2069,7 +2069,7 @@ EXPORT_SYMBOL(netif_rx_ni);
 
 static void net_tx_action(struct softirq_action *h)
 {
-	struct softnet_data *sd = &__get_cpu_var(softnet_data);
+	volatile struct softnet_data *sd = &__get_cpu_var(softnet_data);
 
 	if (sd->completion_queue) {
 		struct sk_buff *clist;

^ permalink raw reply

* Re: [patch net-next] tc_vlan: fix type of tcfv_push_vid
From: Jiri Pirko @ 2014-11-24 13:33 UTC (permalink / raw)
  To: Jamal Hadi Salim; +Cc: netdev, davem
In-Reply-To: <547331E0.6030305@mojatatu.com>

Mon, Nov 24, 2014 at 02:25:52PM CET, jhs@mojatatu.com wrote:
>On 11/24/14 05:30, Jiri Pirko wrote:
>>Should be u16. So fix it to kill the sparse warning.
>>
>>Fixes: c7e2b9689ef8136 "sched: introduce vlan action"
>>Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>---
>>  include/net/tc_act/tc_vlan.h | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>>diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
>>index c809c1d..93b70ad 100644
>>--- a/include/net/tc_act/tc_vlan.h
>>+++ b/include/net/tc_act/tc_vlan.h
>>@@ -18,7 +18,7 @@
>>  struct tcf_vlan {
>>  	struct tcf_common	common;
>>  	int			tcfv_action;
>>-	__be16			tcfv_push_vid;
>>+	u16			tcfv_push_vid;
>>  	__be16			tcfv_push_proto;
>
>
>User space sends you this in be, no? I thought it was fine
>the way it is. Isnt __be16 just an annotation?

No, userspace sends this in host. Therefore we should store it in host,
not in be. It is just an annotation.

>
>cheers,
>jamal
>

^ permalink raw reply

* Re: [PATCH net-next v4 0/4] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-11-24 13:45 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, luto-kltTT9wpgjJwATOyAt5JVQ,
	stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
	cwang-xCSkyg8dI+0RB7SZvlqPiA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <871tpph03k.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

Le 30/10/2014 19:41, Eric W. Biederman a écrit :
> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>
>> The goal of this serie is to be able to multicast netlink messages with an
>> attribute that identify a peer netns.
>> This is needed by the userland to interpret some informations contained in
>> netlink messages (like IFLA_LINK value, but also some other attributes in case
>> of x-netns netdevice (see also
>> http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
>> http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).
>>
>> Ids of peer netns are set by userland via a new genl messages. These ids are
>> stored per netns and are local (ie only valid in the netns where they are set).
>> To avoid allocating an int for each peer netns, I use idr_for_each() to retrieve
>> the id of a peer netns. Note that it will be possible to add a table (struct net
>> -> id) later to optimize this lookup if needed.
>>
>> Patch 1/4 introduces the netlink API mechanism to set and get these ids.
>> Patch 2/4 and 3/4 implements an example of how to use these ids in rtnetlink
>> messages. And patch 4/4 shows that the netlink messages can be symetric between
>> a GET and a SET.
>>
>> iproute2 patches are available, I can send them on demand.
>
> A quick reply.  I think this patchset is in the right general direction.
> There are some oddball details that seem odd/awkward to me such as using
> genetlink instead of rtnetlink to get and set the ids, and not having
> ids if they are not set (that feels like a maintenance/usability challenge).
>
> I would like to give your patches a deep review, but I won't be able to
> do that for a couple of weeks.  I am deep in the process of moving,
> and will be mostly offline until about the Nov 11th.
Eric, did you have a chance to look at this?


Regards,
Nicolas
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

^ permalink raw reply

* Re: [PATCH] ip_tunnel: the lack of vti_link_ops' dellink() cause kernel panic
From: Nicolas Dichtel @ 2014-11-24 14:18 UTC (permalink / raw)
  To: Xin Long, network dev, Steffen Klassert; +Cc: Cong Wang
In-Reply-To: <1416726251-13088-1-git-send-email-lucien.xin@gmail.com>

Le 23/11/2014 08:04, Xin Long a écrit :
> Now the vti_link_ops do not point the .dellink, for fb tunnel device
> (ip_vti0), the net_device will be removed as the default .dellink is
> unregister_netdevice_queue,but the tunnel still in the tunnel list,
> then if we add a new vti tunnel, in ip_tunnel_find():
>
>          hlist_for_each_entry_rcu(t, head, hash_node) {
>                  if (local == t->parms.iph.saddr &&
>                      remote == t->parms.iph.daddr &&
>                      link == t->parms.link &&
> ==>                 type == t->dev->type &&
>                      ip_tunnel_key_match(&t->parms, flags, key))
>                          break;
>          }
>
> the panic will happen, cause dev of ip_tunnel *t is null:
> [ 3835.072977] IP: [<ffffffffa04103fd>] ip_tunnel_find+0x9d/0xc0 [ip_tunnel]
> [ 3835.073008] PGD b2c21067 PUD b7277067 PMD 0
> [ 3835.073008] Oops: 0000 [#1] SMP
> .....
> [ 3835.073008] Stack:
> [ 3835.073008]  ffff8800b72d77f0 ffffffffa0411924 ffff8800bb956000 ffff8800b72d78e0
> [ 3835.073008]  ffff8800b72d78a0 0000000000000000 ffffffffa040d100 ffff8800b72d7858
> [ 3835.073008]  ffffffffa040b2e3 0000000000000000 0000000000000000 0000000000000000
> [ 3835.073008] Call Trace:
> [ 3835.073008]  [<ffffffffa0411924>] ip_tunnel_newlink+0x64/0x160 [ip_tunnel]
> [ 3835.073008]  [<ffffffffa040b2e3>] vti_newlink+0x43/0x70 [ip_vti]
> [ 3835.073008]  [<ffffffff8150d4da>] rtnl_newlink+0x4fa/0x5f0
> [ 3835.073008]  [<ffffffff812f68bb>] ? nla_strlcpy+0x5b/0x70
> [ 3835.073008]  [<ffffffff81508fb0>] ? rtnl_link_ops_get+0x40/0x60
> [ 3835.073008]  [<ffffffff8150d11f>] ? rtnl_newlink+0x13f/0x5f0
> [ 3835.073008]  [<ffffffff81509cf4>] rtnetlink_rcv_msg+0xa4/0x270
> [ 3835.073008]  [<ffffffff8126adf5>] ? sock_has_perm+0x75/0x90
> [ 3835.073008]  [<ffffffff81509c50>] ? rtnetlink_rcv+0x30/0x30
> [ 3835.073008]  [<ffffffff81529e39>] netlink_rcv_skb+0xa9/0xc0
> [ 3835.073008]  [<ffffffff81509c48>] rtnetlink_rcv+0x28/0x30
> ....
>
> modprobe ip_vti
> ip link del ip_vti0 type vti
> ip link add ip_vti0 type vti
> rmmod ip_vti
>
> do that one or more times, kernel will panic.
>
> fix it by assigning ip_tunnel_dellink to vti_link_ops' dellink, in
> which we skip the unregister of fb tunnel device. do the same on ip6_vti.
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> Signed-off-by: Cong Wang <cwang@twopensource.com>
> ---
>   net/ipv4/ip_vti.c  |  1 +
>   net/ipv6/ip6_vti.c | 11 +++++++++++
>   2 files changed, 12 insertions(+)
>
> diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
> index 3e86101..1a7e979 100644
> --- a/net/ipv4/ip_vti.c
> +++ b/net/ipv4/ip_vti.c
> @@ -528,6 +528,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = {
>   	.validate	= vti_tunnel_validate,
>   	.newlink	= vti_newlink,
>   	.changelink	= vti_changelink,
> +	.dellink        = ip_tunnel_dellink,
Nitpicking: please, use a tab instead of space to align the '=', like other
lines.

^ permalink raw reply

* Re: [PATCH net-net 0/4] Increase the limit of tuntap queues
From: Pankaj Gupta @ 2014-11-24 14:28 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: David Miller, linux-kernel, netdev, jasowang, dgibson, vfalico,
	edumazet, vyasevic, hkchu, wuzhy, xemul, therbert, bhutchings,
	xii, stephen, jiri, sergei shtylyov
In-Reply-To: <20141124080243.GD6286@redhat.com>


> On Sun, Nov 23, 2014 at 08:23:21PM -0500, David Miller wrote:
> > From: "Michael S. Tsirkin" <mst@redhat.com>
> > Date: Sun, 23 Nov 2014 22:30:32 +0200
> > 
> > > qemu runs in the host, but it's unpriveledged: it gets
> > > passed tun FDs by a priveledged daemon, and it only
> > > has the rights to some operations,
> > > in particular to attach and detach queues.
> > > 
> > > The assumption always was that this operation is safe
> > > and can't make kernel run out of resources.
> > 
> > This creates a rather rediculous situation in my opinion.
> > 
> > Configuring a network device is a privileged operation, the daemon
> > should be setting this thing up.
> > 
> > In no other context would we have to worry about something like this.
> 
> Right.  Jason corrected me.  I got it wrong:
> what qemu does is TUNSETQUEUE and that needs to get a queue
> that's already initialized by the daemon.
> 
> To create new queues daemon calls TUNSETIFF,
> and that already can be used to create new devices,
> so it's a priveledged operation.
> 
> This means it's safe to just drop the restriction,
> exactly as you suggested originally.

I will drop patch2 to add sysctl entry and and will send a v2 with other 
patches.

Thanks,
Pankaj

> --
> MST
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH v3 26/41] vhost: virtio 1.0 endian-ness support
From: Cedric Le Goater @ 2014-11-24 14:28 UTC (permalink / raw)
  To: Michael S. Tsirkin, linux-kernel
  Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, kvm,
	virtualization, netdev
In-Reply-To: <1416829787-14252-27-git-send-email-mst@redhat.com>

Hi Michael,

Do you have a tree from where I could pull these patches ? 

Thanks,

C.

On 11/24/2014 12:54 PM, Michael S. Tsirkin wrote:
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  drivers/vhost/vhost.c | 93 +++++++++++++++++++++++++++++++--------------------
>  1 file changed, 56 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index c90f437..4d379ed 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -33,8 +33,8 @@ enum {
>  	VHOST_MEMORY_F_LOG = 0x1,
>  };
> 
> -#define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num])
> -#define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num])
> +#define vhost_used_event(vq) ((__virtio16 __user *)&vq->avail->ring[vq->num])
> +#define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num])
> 
>  static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
>  			    poll_table *pt)
> @@ -1001,7 +1001,7 @@ EXPORT_SYMBOL_GPL(vhost_log_write);
>  static int vhost_update_used_flags(struct vhost_virtqueue *vq)
>  {
>  	void __user *used;
> -	if (__put_user(vq->used_flags, &vq->used->flags) < 0)
> +	if (__put_user(cpu_to_vhost16(vq, vq->used_flags), &vq->used->flags) < 0)
>  		return -EFAULT;
>  	if (unlikely(vq->log_used)) {
>  		/* Make sure the flag is seen before log. */
> @@ -1019,7 +1019,7 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq)
> 
>  static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
>  {
> -	if (__put_user(vq->avail_idx, vhost_avail_event(vq)))
> +	if (__put_user(cpu_to_vhost16(vq, vq->avail_idx), vhost_avail_event(vq)))
>  		return -EFAULT;
>  	if (unlikely(vq->log_used)) {
>  		void __user *used;
> @@ -1038,6 +1038,7 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
> 
>  int vhost_init_used(struct vhost_virtqueue *vq)
>  {
> +	__virtio16 last_used_idx;
>  	int r;
>  	if (!vq->private_data)
>  		return 0;
> @@ -1046,7 +1047,13 @@ int vhost_init_used(struct vhost_virtqueue *vq)
>  	if (r)
>  		return r;
>  	vq->signalled_used_valid = false;
> -	return get_user(vq->last_used_idx, &vq->used->idx);
> +	if (!access_ok(VERIFY_READ, &vq->used->idx, sizeof vq->used->idx))
> +		return -EFAULT;
> +	r = __get_user(last_used_idx, &vq->used->idx);
> +	if (r)
> +		return r;
> +	vq->last_used_idx = vhost16_to_cpu(vq, last_used_idx);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(vhost_init_used);
> 
> @@ -1087,16 +1094,16 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
>  /* Each buffer in the virtqueues is actually a chain of descriptors.  This
>   * function returns the next descriptor in the chain,
>   * or -1U if we're at the end. */
> -static unsigned next_desc(struct vring_desc *desc)
> +static unsigned next_desc(struct vhost_virtqueue *vq, struct vring_desc *desc)
>  {
>  	unsigned int next;
> 
>  	/* If this descriptor says it doesn't chain, we're done. */
> -	if (!(desc->flags & VRING_DESC_F_NEXT))
> +	if (!(desc->flags & cpu_to_vhost16(vq, VRING_DESC_F_NEXT)))
>  		return -1U;
> 
>  	/* Check they're not leading us off end of descriptors. */
> -	next = desc->next;
> +	next = vhost16_to_cpu(vq, desc->next);
>  	/* Make sure compiler knows to grab that: we don't want it changing! */
>  	/* We will use the result as an index in an array, so most
>  	 * architectures only need a compiler barrier here. */
> @@ -1113,18 +1120,19 @@ static int get_indirect(struct vhost_virtqueue *vq,
>  {
>  	struct vring_desc desc;
>  	unsigned int i = 0, count, found = 0;
> +	u32 len = vhost32_to_cpu(vq, indirect->len);
>  	int ret;
> 
>  	/* Sanity check */
> -	if (unlikely(indirect->len % sizeof desc)) {
> +	if (unlikely(len % sizeof desc)) {
>  		vq_err(vq, "Invalid length in indirect descriptor: "
>  		       "len 0x%llx not multiple of 0x%zx\n",
> -		       (unsigned long long)indirect->len,
> +		       (unsigned long long)vhost32_to_cpu(vq, indirect->len),
>  		       sizeof desc);
>  		return -EINVAL;
>  	}
> 
> -	ret = translate_desc(vq, indirect->addr, indirect->len, vq->indirect,
> +	ret = translate_desc(vq, vhost64_to_cpu(vq, indirect->addr), len, vq->indirect,
>  			     UIO_MAXIOV);
>  	if (unlikely(ret < 0)) {
>  		vq_err(vq, "Translation failure %d in indirect.\n", ret);
> @@ -1135,7 +1143,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
>  	 * architectures only need a compiler barrier here. */
>  	read_barrier_depends();
> 
> -	count = indirect->len / sizeof desc;
> +	count = len / sizeof desc;
>  	/* Buffers are chained via a 16 bit next field, so
>  	 * we can have at most 2^16 of these. */
>  	if (unlikely(count > USHRT_MAX + 1)) {
> @@ -1155,16 +1163,17 @@ static int get_indirect(struct vhost_virtqueue *vq,
>  		if (unlikely(memcpy_fromiovec((unsigned char *)&desc,
>  					      vq->indirect, sizeof desc))) {
>  			vq_err(vq, "Failed indirect descriptor: idx %d, %zx\n",
> -			       i, (size_t)indirect->addr + i * sizeof desc);
> +			       i, (size_t)vhost64_to_cpu(vq, indirect->addr) + i * sizeof desc);
>  			return -EINVAL;
>  		}
> -		if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
> +		if (unlikely(desc.flags & cpu_to_vhost16(vq, VRING_DESC_F_INDIRECT))) {
>  			vq_err(vq, "Nested indirect descriptor: idx %d, %zx\n",
> -			       i, (size_t)indirect->addr + i * sizeof desc);
> +			       i, (size_t)vhost64_to_cpu(vq, indirect->addr) + i * sizeof desc);
>  			return -EINVAL;
>  		}
> 
> -		ret = translate_desc(vq, desc.addr, desc.len, iov + iov_count,
> +		ret = translate_desc(vq, vhost64_to_cpu(vq, desc.addr),
> +				     vhost32_to_cpu(vq, desc.len), iov + iov_count,
>  				     iov_size - iov_count);
>  		if (unlikely(ret < 0)) {
>  			vq_err(vq, "Translation failure %d indirect idx %d\n",
> @@ -1172,11 +1181,11 @@ static int get_indirect(struct vhost_virtqueue *vq,
>  			return ret;
>  		}
>  		/* If this is an input descriptor, increment that count. */
> -		if (desc.flags & VRING_DESC_F_WRITE) {
> +		if (desc.flags & cpu_to_vhost16(vq, VRING_DESC_F_WRITE)) {
>  			*in_num += ret;
>  			if (unlikely(log)) {
> -				log[*log_num].addr = desc.addr;
> -				log[*log_num].len = desc.len;
> +				log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
> +				log[*log_num].len = vhost32_to_cpu(vq, desc.len);
>  				++*log_num;
>  			}
>  		} else {
> @@ -1189,7 +1198,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
>  			}
>  			*out_num += ret;
>  		}
> -	} while ((i = next_desc(&desc)) != -1);
> +	} while ((i = next_desc(vq, &desc)) != -1);
>  	return 0;
>  }
> 
> @@ -1209,15 +1218,18 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>  	struct vring_desc desc;
>  	unsigned int i, head, found = 0;
>  	u16 last_avail_idx;
> +	__virtio16 avail_idx;
> +	__virtio16 ring_head;
>  	int ret;
> 
>  	/* Check it isn't doing very strange things with descriptor numbers. */
>  	last_avail_idx = vq->last_avail_idx;
> -	if (unlikely(__get_user(vq->avail_idx, &vq->avail->idx))) {
> +	if (unlikely(__get_user(avail_idx, &vq->avail->idx))) {
>  		vq_err(vq, "Failed to access avail idx at %p\n",
>  		       &vq->avail->idx);
>  		return -EFAULT;
>  	}
> +	vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
> 
>  	if (unlikely((u16)(vq->avail_idx - last_avail_idx) > vq->num)) {
>  		vq_err(vq, "Guest moved used index from %u to %u",
> @@ -1234,7 +1246,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
> 
>  	/* Grab the next descriptor number they're advertising, and increment
>  	 * the index we've seen. */
> -	if (unlikely(__get_user(head,
> +	if (unlikely(__get_user(ring_head,
>  				&vq->avail->ring[last_avail_idx % vq->num]))) {
>  		vq_err(vq, "Failed to read head: idx %d address %p\n",
>  		       last_avail_idx,
> @@ -1242,6 +1254,8 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>  		return -EFAULT;
>  	}
> 
> +	head = vhost16_to_cpu(vq, ring_head);
> +
>  	/* If their number is silly, that's an error. */
>  	if (unlikely(head >= vq->num)) {
>  		vq_err(vq, "Guest says index %u > %u is available",
> @@ -1274,7 +1288,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>  			       i, vq->desc + i);
>  			return -EFAULT;
>  		}
> -		if (desc.flags & VRING_DESC_F_INDIRECT) {
> +		if (desc.flags & cpu_to_vhost16(vq, VRING_DESC_F_INDIRECT)) {
>  			ret = get_indirect(vq, iov, iov_size,
>  					   out_num, in_num,
>  					   log, log_num, &desc);
> @@ -1286,20 +1300,21 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>  			continue;
>  		}
> 
> -		ret = translate_desc(vq, desc.addr, desc.len, iov + iov_count,
> +		ret = translate_desc(vq, vhost64_to_cpu(vq, desc.addr),
> +				     vhost32_to_cpu(vq, desc.len), iov + iov_count,
>  				     iov_size - iov_count);
>  		if (unlikely(ret < 0)) {
>  			vq_err(vq, "Translation failure %d descriptor idx %d\n",
>  			       ret, i);
>  			return ret;
>  		}
> -		if (desc.flags & VRING_DESC_F_WRITE) {
> +		if (desc.flags & cpu_to_vhost16(vq, VRING_DESC_F_WRITE)) {
>  			/* If this is an input descriptor,
>  			 * increment that count. */
>  			*in_num += ret;
>  			if (unlikely(log)) {
> -				log[*log_num].addr = desc.addr;
> -				log[*log_num].len = desc.len;
> +				log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
> +				log[*log_num].len = vhost32_to_cpu(vq, desc.len);
>  				++*log_num;
>  			}
>  		} else {
> @@ -1312,7 +1327,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>  			}
>  			*out_num += ret;
>  		}
> -	} while ((i = next_desc(&desc)) != -1);
> +	} while ((i = next_desc(vq, &desc)) != -1);
> 
>  	/* On success, increment avail index. */
>  	vq->last_avail_idx++;
> @@ -1335,7 +1350,10 @@ EXPORT_SYMBOL_GPL(vhost_discard_vq_desc);
>   * want to notify the guest, using eventfd. */
>  int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
>  {
> -	struct vring_used_elem heads = { head, len };
> +	struct vring_used_elem heads = {
> +		cpu_to_vhost32(vq, head),
> +		cpu_to_vhost32(vq, len)
> +	};
> 
>  	return vhost_add_used_n(vq, &heads, 1);
>  }
> @@ -1404,7 +1422,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads,
> 
>  	/* Make sure buffer is written before we update index. */
>  	smp_wmb();
> -	if (put_user(vq->last_used_idx, &vq->used->idx)) {
> +	if (__put_user(cpu_to_vhost16(vq, vq->last_used_idx), &vq->used->idx)) {
>  		vq_err(vq, "Failed to increment used idx");
>  		return -EFAULT;
>  	}
> @@ -1422,7 +1440,8 @@ EXPORT_SYMBOL_GPL(vhost_add_used_n);
> 
>  static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
>  {
> -	__u16 old, new, event;
> +	__u16 old, new;
> +	__virtio16 event;
>  	bool v;
>  	/* Flush out used index updates. This is paired
>  	 * with the barrier that the Guest executes when enabling
> @@ -1434,12 +1453,12 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
>  		return true;
> 
>  	if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) {
> -		__u16 flags;
> +		__virtio16 flags;
>  		if (__get_user(flags, &vq->avail->flags)) {
>  			vq_err(vq, "Failed to get flags");
>  			return true;
>  		}
> -		return !(flags & VRING_AVAIL_F_NO_INTERRUPT);
> +		return !(flags & cpu_to_vhost16(vq, VRING_AVAIL_F_NO_INTERRUPT));
>  	}
>  	old = vq->signalled_used;
>  	v = vq->signalled_used_valid;
> @@ -1449,11 +1468,11 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
>  	if (unlikely(!v))
>  		return true;
> 
> -	if (get_user(event, vhost_used_event(vq))) {
> +	if (__get_user(event, vhost_used_event(vq))) {
>  		vq_err(vq, "Failed to get used event idx");
>  		return true;
>  	}
> -	return vring_need_event(event, new, old);
> +	return vring_need_event(vhost16_to_cpu(vq, event), new, old);
>  }
> 
>  /* This actually signals the guest, using eventfd. */
> @@ -1488,7 +1507,7 @@ EXPORT_SYMBOL_GPL(vhost_add_used_and_signal_n);
>  /* OK, now we need to know about added descriptors. */
>  bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
>  {
> -	u16 avail_idx;
> +	__virtio16 avail_idx;
>  	int r;
> 
>  	if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY))
> @@ -1519,7 +1538,7 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
>  		return false;
>  	}
> 
> -	return avail_idx != vq->avail_idx;
> +	return vhost16_to_cpu(vq, avail_idx) != vq->avail_idx;
>  }
>  EXPORT_SYMBOL_GPL(vhost_enable_notify);
> 

^ permalink raw reply

* Re: [PATCH 0/6] kernel tinification: optionally compile out splice family of syscalls (splice, vmsplice, tee and sendfile)
From: Josh Triplett @ 2014-11-24 14:54 UTC (permalink / raw)
  To: Pieter Smith
  Cc: Jeff Layton, David Miller,
	alexander.h.duyck-ral2JQCrhuEAvxtiuMwx3w,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, ast-uqk4Ao+rVK5Wk0Htik3J/w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	beber-2YnHqweIUXrk1uMJSBkQmQ,
	catalina.mocanu-Re5JQEeQqe8AvxtiuMwx3w,
	dborkman-H+wXaHxf7aLQT0dZR+AlfA, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, fabf-AgBVmzD5pcezQB+pC5nmwQ,
	fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	geert-Td1EMuHUCqxL1ZNQvxDV9g, hughd-hpIqsD4AKlfQT0dZR+AlfA,
	iulia.manda21-Re5JQEeQqe8AvxtiuMwx3w, JBeulich-IBi9RG/b67k,
	bfields-uC3wQj2KruNg9hUCZPvPmw, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, mcgrof-IBi9RG/b67k,
	mattst88-Re5JQEeQqe8AvxtiuMwx3w, mgorman-l3A5Bk7waGM,
	mst-H+wXaHxf7aLQT0dZR+AlfA, miklos-sUDqSbJrdHQHWmgEVkV9KA,
	netdev-u79uwXL29TY76Z2rM5mHXA, oleg-H+wXaHxf7aLQT0dZR+AlfA,
	Paul.Durrant-Sxgqhf6Nn4DQT0dZR+AlfA,
	paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	pefoley2-lY0TAiDIAFlBDgjK7y7TUQ, tgraf-G/eBtMaohhA,
	therbert-hpIqsD4AKlfQT0dZR+AlfA, willemb-hpIqsD4AKlfQT0dZR+AlfA,
	xiaoguangrong-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	zhenglong.cai-TJRtMXcVgQTM1kAEIRd3EQ
In-Reply-To: <20141124100138.GB1055@smipidev>

On Mon, Nov 24, 2014 at 11:01:38AM +0100, Pieter Smith wrote:
> On Sun, Nov 23, 2014 at 04:32:51PM -0800, Josh Triplett wrote:
> > On Sun, Nov 23, 2014 at 07:28:10PM -0500, Jeff Layton wrote:
> > > On Sun, 23 Nov 2014 15:36:37 -0800
> > > Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org> wrote:
> > > 
> > > > On Sun, Nov 23, 2014 at 09:30:40PM +0100, Pieter Smith wrote:
> > > > > On Sun, Nov 23, 2014 at 11:43:26AM -0800, Josh Triplett wrote:
> > > > > > On Sun, Nov 23, 2014 at 01:46:23PM -0500, David Miller wrote:
> > > > > > > Truly removing sendfile/sendpage means that you can't even compile NFS
> > > > > > > into the tree.
> > > > > > 
> > > > > > If you mean the in-kernel nfsd (CONFIG_NFSD), that already has a large
> > > > > > stack of "select" and "depends on", both directly and indirectly; adding
> > > > > > a "select SPLICE_SYSCALL" to it seems fine.  (That select does need
> > > > > > adding, though.  Pieter, you need to test-compile more than just
> > > > > > tinyconfig and defconfig.  Try an allyesconfig with *just* splice turned
> > > > > > off, and make sure that compiles.)
> > > > > 
> > > > > Did exacly that. Took forever on my hardware, but no problems.
> > > > 
> > > > Ah, I see.  Looking more closely at nfsd, it looks like it already has a
> > > > code path for filesystems that don't do splice.  I think, rather than
> > > > making nfsd select SPLICE_SYSCALL, that it would suffice to change the
> > > > "rqstp->rq_splice_ok = true;" in svc_process_common (net/sunrpc/svc.c)
> > > > to:
> > > > 
> > > > rqstp->rq_splice_ok = IS_ENABLED(CONFIG_SPLICE_SYSCALL);
> > > > 
> > > > Then nfsd should simply *always* fall back to its non-splice support.
> > > > 
> > > 
> > > I'd probably prefer the above, actually. We have to keep supporting
> > > non-splice enabled fs' for the forseeable future, so we may as well
> > > allow people to run nfsd in such configurations. It could even be
> > > useful for testing the non-splice-enabled codepaths.
> > 
> > Good point!
> > 
> > - Josh Triplett
> 
> I'll add this to svc_process_common. I can squash this into PATCH 3, which is
> where the syscalls can be compiled out. The log entry may however get a little
> crowded and multi-functional.
> 
> Should I keep this as a separate patch?

I'd keep it as a separate patch, yes.  It doesn't become necessary until
patch 6, so you can add it as a new patch between patches 3 and 6.

- Josh Triplett

^ permalink raw reply

* Re: [RFC PATCH 0/4] switch device: offload policy attributes
From: Roopa Prabhu @ 2014-11-24 14:55 UTC (permalink / raw)
  To: Scott Feldman
  Cc: Jiří Pírko, Jamal Hadi Salim, Benjamin LaHaise,
	Thomas Graf, john.fastabend, stephen, John Linville, nhorman,
	Nicolas Dichtel, vyasevic, Florian Fainelli, buytenh, Aviad Raveh,
	Netdev, David S. Miller, shrijeet, Andy Gospodarek
In-Reply-To: <CAE4R7bCDp2Cf=azOJvnm3_YRdsD5vwCafbcVFuseUaPuYKDA1g@mail.gmail.com>

On 11/24/14, 2:18 AM, Scott Feldman wrote:
> Hi Roopa,
>
> I have a patch pending against Jiri's v2 that's uses existing
> ndo_bridge_setlink/getlink to push policy settings down to port driver
> for controlling HW offload.  I had to make a few tweaks, but for the
> most part setlink/getlink already has the master/self semantics so
> users can set policy flags on bridge's SW version of the port (master)
> or on the offloaded version of the port (self).
>    I added the new
> hwmode option "swdev" to the existing "vepa"|"veb" choices.  When you
> specify hwmode, SELF is set and the port driver's setlink get's
> called.  Did you look at setlink/getlink?  It looks like the kernel
> and iproute2 where going down this route of using setlink/getlink for
> SELF policy, so I'm wondering if we need more?
If i understand you correctly, this will mean the port driver implements 
the
setlink/getlink with the  bridge port flags and attributes. And, it also 
means
the port driver will parse the netlink msg instead of the bridge driver
parsing all attributes and then calling offloads.

But, in cases where we want bridge port flags and attributes set both in 
hw and sw,
the user (iproute2) will have to set both MASTER and SELF flags, and the
netlink parsing will now happen in two places, the bridge driver and the 
bridge port
driver ?

For bridge stp state updates, the bridge driver will call the 
ports->setlink ndo op ?

(We should probably rename the ndo_bridge_setlink to ndo_setlink)

>
> On FDB entries, using master/self semantics that exist, it's clear
> which are owned by offloaded device and which are owned by bridge.
> The one missing annotation was a flag indicating FDB entry in bridge
> was synced from device.  And a policy flag to turn on/off syncing from
> the device.  The policy flag is just another IFLA_BRPORT flags passed
> with setlink/getlink.
>
> The setlink/getlink patch will go out in v3 once I finish testing it
> and push it to Jiri.  Hopefully tomorrow.

In my patches, I used newlink..., but in most cases all attributes set 
via newlink can be
used with setlink and hence getlink. So, i think we are close here.

But, Oh wait, i am talking about rtnl_link_ops 
->newlink/changelink/getlink/dellink. I did not
realize there was a parallel ndo op to this. But thats probably because, 
rtnl_link_ops can be
used only for logical devices. But, i see bridge driver implementing 
both the
rtnl_link_ops changelink and ndo op setlink. hmm..seems like a lot of 
duplication.
Will look closely some more.


Coming back to my series, i was trying to get a common set of flags for 
all netdevs
(bridge, bond, vxlans so far), and hence the common flag in 'struct 
ifiinfomsg'.

But, I am all for using existing infrastructure if it fits well.

For the fdb offloads, the NTF_SELF and NTF_MASTER is in 'struct 
ndmsg->ndm_flags', which is also
what i was proposing. So, ack there.

For the bridge netdev, using the flag in IFLA_BRIDGE_FLAGS, is also ok.


I will look at your patches when they are out.

Thanks,
Roopa




On Fri, Nov 21, 2014 at 12:49 PM, <roopa@cumulusnetworks.com> wrote:
>> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>
>>
>> This series aims at introducing new policy attibutes/flags to enable
>> selective offloading of kernel network objects.
>> This is in the context of supporting switch devices in the linux kernel.
>>
>> Assumption:
>>      - All kernel network objects (routes, neighs, bridges, bonds, vxlans)
>>        can be offloaded (This is true today with a few exceptions maybe)
>>
>> policy points:
>>      - By default all objects exist in software (kernel)
>>      - Per object flag to add/del/show in kernel, hardware or both
>>      - System global option to turn on/off offloads for all network objects.
>>        This is for systems who want to turn offloading on for all network objects
>>        by default. us :). Apps dont need to know about offloading in this
>>        model. (TBD)
>>
>> Patches are based on jiri/sfeldma's rocker work.
>>
>> Apologize for the incomplete and untested code. This is a sample patch
>>   to get some initial feedback.
>>
>> Roopa Prabhu (4):
>>    rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object
>>      offload to hardware
>>    netdev: new feature flag NETIF_F_HW_OFFLOAD to indicate netdev object
>>      offload to hardware
>>    swdevice: new generic op to set bridge port attr
>>    bridge: make hw offload conditional on bridge and bridge port offload
>>      flags
>>
>>   include/linux/netdev_features.h |    1 +
>>   include/net/switchdev.h         |    8 ++++++-
>>   include/uapi/linux/netlink.h    |    2 ++
>>   net/bridge/br_netlink.c         |   50 +++++++++++++++++++++++++++++++--------
>>   net/bridge/br_private.h         |    2 ++
>>   net/bridge/br_stp.c             |    9 ++++---
>>   net/bridge/br_stp_if.c          |    8 +++++--
>>   net/core/rtnetlink.c            |    7 ++++++
>>   net/switchdev/switchdev.c       |   17 +++++++++++++
>>   9 files changed, 88 insertions(+), 16 deletions(-)
>>
>> --
>> 1.7.10.4
>>

^ permalink raw reply

* Re: net_tx_action race condition?
From: Herbert Xu @ 2014-11-24 15:08 UTC (permalink / raw)
  To: Angelo Rizzi; +Cc: netdev
In-Reply-To: <547332D7.7050104@3dautomazione.it>

Angelo Rizzi <angelo.rizzi@3dautomazione.it> wrote:
> [-- text/plain, encoding 7bit, charset: iso-8859-15, 22 lines --]
> 
> Hi Daniel,
> Here attached the patch file you required.
> The problem i've found is on the declaration of 'struct softnet_data 
> *sd' in function 'net_tx_action'
> What happens to me (i have an embedded system based on FPGA and a NIOS2 
> cpu) is that, due to compiler optimization, the content of 
> 'sd->completion_queue' is saved in a CPU register before interrupt 
> disabling (when the instruction 'if (sd->completion_queue) {' is 
> executed) and then the register contents is used for interrupt-disabled 
> assignment ('clist = sd->completion_queue') instead of re-read the 
> variable contents.
> This seems to lead to a race condition when an interrupt modifies the 
> content of 'sd->completion_queue' between these two instructions.
> What i have done to avoid this situation is to change the declaration of 
> 'struct softnet_data *sd' to 'volatile struct softnet_data *sd' and now 
> everything seems to be ok.
> I hope this will help.

local_irq_disable is supposed to contain a compiler barrier.  So
this is either a buggy arch or a buggy compiler.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: net_tx_action race condition?
From: Eric Dumazet @ 2014-11-24 15:33 UTC (permalink / raw)
  To: Angelo Rizzi; +Cc: netdev, linux-kernel@vger.kernel.org
In-Reply-To: <547332D7.7050104@3dautomazione.it>

On Mon, 2014-11-24 at 14:29 +0100, Angelo Rizzi wrote:
> Hi Daniel,
> Here attached the patch file you required.
> The problem i've found is on the declaration of 'struct softnet_data 
> *sd' in function 'net_tx_action'
> What happens to me (i have an embedded system based on FPGA and a NIOS2 
> cpu) is that, due to compiler optimization, the content of 
> 'sd->completion_queue' is saved in a CPU register before interrupt 
> disabling (when the instruction 'if (sd->completion_queue) {' is 
> executed) and then the register contents is used for interrupt-disabled 
> assignment ('clist = sd->completion_queue') instead of re-read the 
> variable contents.
> This seems to lead to a race condition when an interrupt modifies the 
> content of 'sd->completion_queue' between these two instructions.
> What i have done to avoid this situation is to change the declaration of 
> 'struct softnet_data *sd' to 'volatile struct softnet_data *sd' and now 
> everything seems to be ok.
> I hope this will help.
> 
> Regards,
> Angelo
> 

Do not add volatile in the kernel, this is not how we solve this kind of
problems.  Documentation/memory-barriers.txt and

Documentation/00-INDEX:476:volatile-considered-harmful.txt
Documentation/00-INDEX:477:     - Why the "volatile" type class should not be used


I am surprised this patch is needed. Many other 'bugs' would need
similar fixes.

local_irq_disable() MUST have a memory barrier. This looks like a bug in
one particular arch implementation.


On x86 for example, native_irq_disable() is really :

	asm volatile("cli": : :"memory");


diff --git a/net/core/dev.c b/net/core/dev.c
index ac4836241a965a71952469ba054f87d8dfca2d32..fa73072e515aa07fa8ae1bc39174b7d59c7a31a5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3406,7 +3406,7 @@ static void net_tx_action(struct softirq_action *h)
 		struct sk_buff *clist;
 
 		local_irq_disable();
-		clist = sd->completion_queue;
+		clist = ACCESS_ONCE(sd->completion_queue);
 		sd->completion_queue = NULL;
 		local_irq_enable();
 

^ permalink raw reply related

* Re: [fuse-devel] [PATCH 4/6] fs/fuse: support compiling out splice
From: Josh Triplett @ 2014-11-24 16:05 UTC (permalink / raw)
  To: Pieter Smith
  Cc: Richard Weinberger, Michael S. Tsirkin, Bertrand Jacquin,
	Oleg Nesterov, J. Bruce Fields, Eric Dumazet,
	蔡正龙, Jeff Layton, Tom Herbert,
	Alexei Starovoitov, Miklos Szeredi, Peter Foley, Hugh Dickins,
	Xiao Guangrong, Geert Uytterhoeven, Mel Gorman, Matt Turner,
	Paul E. McKenney, Alexander Duyck, open list:FUSE: FILESYSTEM...,
	Luis R. Rodriguez
In-Reply-To: <20141124094931.GA1055@smipidev>

On Mon, Nov 24, 2014 at 10:49:31AM +0100, Pieter Smith wrote:
> On Sun, Nov 23, 2014 at 03:23:02PM -0800, Josh Triplett wrote:
> > On Sun, Nov 23, 2014 at 11:29:08PM +0100, Richard Weinberger wrote:
> > > On Sun, Nov 23, 2014 at 3:20 PM, Pieter Smith <pieter@boesman.nl> wrote:
> > > > To implement splice support, fs/fuse makes use of nosteal_pipe_buf_ops. This
> > > > struct is exported by fs/splice. The goal of the larger patch set is to
> > > > completely compile out fs/splice, so uses of the exported struct need to be
> > > > compiled out along with fs/splice.
> > > >
> > > > This patch therefore compiles out splice support in fs/fuse when
> > > > CONFIG_SYSCALL_SPLICE is undefined.
> > > >
> > > > Signed-off-by: Pieter Smith <pieter@boesman.nl>
> > > > ---
> > > >  fs/fuse/dev.c      | 4 ++--
> > > >  include/linux/fs.h | 6 ++++++
> > > >  2 files changed, 8 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> > > > index ca88731..f8f92a4 100644
> > > > --- a/fs/fuse/dev.c
> > > > +++ b/fs/fuse/dev.c
> > > > @@ -1291,7 +1291,7 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
> > > >         return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
> > > >  }
> > > >
> > > > -static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
> > > > +static ssize_t __maybe_unused fuse_dev_splice_read(struct file *in, loff_t *ppos,
> > > >                                     struct pipe_inode_info *pipe,
> > > >                                     size_t len, unsigned int flags)
> > > >  {
> > > > @@ -2144,7 +2144,7 @@ const struct file_operations fuse_dev_operations = {
> > > >         .llseek         = no_llseek,
> > > >         .read           = do_sync_read,
> > > >         .aio_read       = fuse_dev_read,
> > > > -       .splice_read    = fuse_dev_splice_read,
> > > > +       .splice_read    = __splice_p(fuse_dev_splice_read),
> > > >         .write          = do_sync_write,
> > > >         .aio_write      = fuse_dev_write,
> > > >         .splice_write   = fuse_dev_splice_write,
> > > > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > > > index a957d43..04c0975 100644
> > > > --- a/include/linux/fs.h
> > > > +++ b/include/linux/fs.h
> > > > @@ -2443,6 +2443,12 @@ extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
> > > >                         int datasync);
> > > >  extern void block_sync_page(struct page *page);
> > > >
> > > > +#ifdef CONFIG_SYSCALL_SPLICE
> > > > +#define __splice_p(x) x
> > > > +#else
> > > > +#define __splice_p(x) NULL
> > > > +#endif
> > > > +
> > > 
> > > This needs to go into a different patch.
> > > One logical change per patch please. :-)
> > 
> > Easy enough to merge this one into the patch introducing
> > CONFIG_SYSCALL_SPLICE, then.
> > 
> > - Josh Triplett
> 
> The patch introducing CONFIG_SYSCALL_SPLICE (PATCH 3) only compiles out the
> syscalls. PATCH 6 on the other hand, compiles out fs/splice.c. This patch
> allows fs/fuse to be compiled when fs/splice.c is compiled out. If I am to
> squash it, it would be logical to include it in PATCH 6, not 3.

The suggestion wasn't to move the fs/fuse/dev.c bits; those should
definitely stay in this patch.  The suggestion was just to move the bit
of the patch defining __splice_p from this patch to patch 3.  (Note that
you need to define it before you use it, so it can't go in patch 6.)

- Josh Triplett

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox