Netdev List
 help / color / mirror / Atom feed
* [PATCH 4.9 07/17] netlink: Dont shift on 64 for ngroups
From: Greg Kroah-Hartman @ 2018-08-07 18:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Herbert Xu,
	Steffen Klassert, netdev, Dmitry Safonov
In-Reply-To: <20180807172342.071526922@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dmitry Safonov <dima@arista.com>

commit 91874ecf32e41b5d86a4cb9d60e0bee50d828058 upstream.

It's legal to have 64 groups for netlink_sock.

As user-supplied nladdr->nl_groups is __u32, it's possible to subscribe
only to first 32 groups.

The check for correctness of .bind() userspace supplied parameter
is done by applying mask made from ngroups shift. Which broke Android
as they have 64 groups and the shift for mask resulted in an overflow.

Fixes: 61f4b23769f0 ("netlink: Don't shift with UB on nlk->ngroups")
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: netdev@vger.kernel.org
Cc: stable@vger.kernel.org
Reported-and-Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 net/netlink/af_netlink.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -988,8 +988,8 @@ static int netlink_bind(struct socket *s
 
 	if (nlk->ngroups == 0)
 		groups = 0;
-	else
-		groups &= (1ULL << nlk->ngroups) - 1;
+	else if (nlk->ngroups < 8*sizeof(groups))
+		groups &= (1UL << nlk->ngroups) - 1;
 
 	bound = nlk->bound;
 	if (bound) {

^ permalink raw reply

* [PATCH 4.9 05/17] netlink: Do not subscribe to non-existent groups
From: Greg Kroah-Hartman @ 2018-08-07 18:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Herbert Xu,
	Steffen Klassert, netdev, Dmitry Safonov
In-Reply-To: <20180807172342.071526922@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dmitry Safonov <dima@arista.com>

[ Upstream commit 7acf9d4237c46894e0fa0492dd96314a41742e84 ]

Make ABI more strict about subscribing to group > ngroups.
Code doesn't check for that and it looks bogus.
(one can subscribe to non-existing group)
Still, it's possible to bind() to all possible groups with (-1)

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/netlink/af_netlink.c |    1 +
 1 file changed, 1 insertion(+)

--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -985,6 +985,7 @@ static int netlink_bind(struct socket *s
 		if (err)
 			return err;
 	}
+	groups &= (1UL << nlk->ngroups) - 1;
 
 	bound = nlk->bound;
 	if (bound) {

^ permalink raw reply

* [PATCH 4.14 08/21] netlink: Dont shift on 64 for ngroups
From: Greg Kroah-Hartman @ 2018-08-07 18:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Herbert Xu,
	Steffen Klassert, netdev, Dmitry Safonov
In-Reply-To: <20180807172330.953888701@linuxfoundation.org>

4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dmitry Safonov <dima@arista.com>

commit 91874ecf32e41b5d86a4cb9d60e0bee50d828058 upstream.

It's legal to have 64 groups for netlink_sock.

As user-supplied nladdr->nl_groups is __u32, it's possible to subscribe
only to first 32 groups.

The check for correctness of .bind() userspace supplied parameter
is done by applying mask made from ngroups shift. Which broke Android
as they have 64 groups and the shift for mask resulted in an overflow.

Fixes: 61f4b23769f0 ("netlink: Don't shift with UB on nlk->ngroups")
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: netdev@vger.kernel.org
Cc: stable@vger.kernel.org
Reported-and-Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 net/netlink/af_netlink.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -981,8 +981,8 @@ static int netlink_bind(struct socket *s
 
 	if (nlk->ngroups == 0)
 		groups = 0;
-	else
-		groups &= (1ULL << nlk->ngroups) - 1;
+	else if (nlk->ngroups < 8*sizeof(groups))
+		groups &= (1UL << nlk->ngroups) - 1;
 
 	bound = nlk->bound;
 	if (bound) {

^ permalink raw reply

* [PATCH 4.17 11/18] netlink: Dont shift on 64 for ngroups
From: Greg Kroah-Hartman @ 2018-08-07 18:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, David S. Miller, Herbert Xu,
	Steffen Klassert, netdev, Dmitry Safonov
In-Reply-To: <20180807172312.964272530@linuxfoundation.org>

4.17-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dmitry Safonov <dima@arista.com>

commit 91874ecf32e41b5d86a4cb9d60e0bee50d828058 upstream.

It's legal to have 64 groups for netlink_sock.

As user-supplied nladdr->nl_groups is __u32, it's possible to subscribe
only to first 32 groups.

The check for correctness of .bind() userspace supplied parameter
is done by applying mask made from ngroups shift. Which broke Android
as they have 64 groups and the shift for mask resulted in an overflow.

Fixes: 61f4b23769f0 ("netlink: Don't shift with UB on nlk->ngroups")
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: netdev@vger.kernel.org
Cc: stable@vger.kernel.org
Reported-and-Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 net/netlink/af_netlink.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1013,8 +1013,8 @@ static int netlink_bind(struct socket *s
 
 	if (nlk->ngroups == 0)
 		groups = 0;
-	else
-		groups &= (1ULL << nlk->ngroups) - 1;
+	else if (nlk->ngroups < 8*sizeof(groups))
+		groups &= (1UL << nlk->ngroups) - 1;
 
 	bound = nlk->bound;
 	if (bound) {

^ permalink raw reply

* RE: [PATCH net-next,v3] net/tls: Calculate nsg for zerocopy path without skb_cow_data.
From: Vakul Garg @ 2018-08-07 16:10 UTC (permalink / raw)
  To: Doron Roberts-Kedes, David S . Miller
  Cc: Dave Watson, Boris Pismenny, Aviad Yehezkel,
	netdev@vger.kernel.org
In-Reply-To: <20180806194738.981505-1-doronrk@fb.com>



> -----Original Message-----
> From: Doron Roberts-Kedes [mailto:doronrk@fb.com]
> Sent: Tuesday, August 7, 2018 1:18 AM
> To: David S . Miller <davem@davemloft.net>
> Cc: Vakul Garg <vakul.garg@nxp.com>; Dave Watson
> <davejwatson@fb.com>; Boris Pismenny <borisp@mellanox.com>; Aviad
> Yehezkel <aviadye@mellanox.com>; netdev@vger.kernel.org; Doron
> Roberts-Kedes <doronrk@fb.com>
> Subject: [PATCH net-next,v3] net/tls: Calculate nsg for zerocopy path
> without skb_cow_data.
> 
> decrypt_skb fails if the number of sg elements required to map is
> greater than MAX_SKB_FRAGS. As noted by Vakul Garg, nsg must always be
> calculated, but skb_cow_data adds unnecessary memcpy's for the zerocopy
> case.
> 
> The new function skb_nsg calculates the number of scatterlist elements
> required to map the skb without the extra overhead of skb_cow_data. This
> function mimics the structure of skb_to_sgvec.
> 
> Fixes: c46234ebb4d1 ("tls: RX path for ktls")
> Signed-off-by: Doron Roberts-Kedes <doronrk@fb.com>
> ---
>  net/tls/tls_sw.c | 96
> ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 93 insertions(+), 3 deletions(-)
> 
> diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
> index ff3a6904a722..eb87f931a0d6 100644
> --- a/net/tls/tls_sw.c
> +++ b/net/tls/tls_sw.c
> @@ -43,6 +43,80 @@
> 
>  #define MAX_IV_SIZE	TLS_CIPHER_AES_GCM_128_IV_SIZE
> 
> +static int __skb_nsg(struct sk_buff *skb, int offset, int len,
> +		     unsigned int recursion_level)
> +{
> +	int start = skb_headlen(skb);
> +	int i, copy = start - offset;
> +	struct sk_buff *frag_iter;
> +	int elt = 0;
> +
> +	if (unlikely(recursion_level >= 24))
> +		return -EMSGSIZE;
> +
> +	if (copy > 0) {
> +		if (copy > len)
> +			copy = len;
> +		elt++;
> +		len -= copy;
> +		if (len == 0)
> +			return elt;
> +		offset += copy;
> +	}
> +
> +	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
> +		int end;
> +
> +		WARN_ON(start > offset + len);
> +
> +		end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
> +		copy = end - offset;
> +		if (copy > 0) {
> +			if (copy > len)
> +				copy = len;
> +			elt++;
> +			len -= copy;
> +			if (len == 0)
> +				return elt;
> +			offset += copy;
> +		}
> +		start = end;
> +	}
> +
> +	skb_walk_frags(skb, frag_iter) {
> +		int end, ret;
> +
> +		WARN_ON(start > offset + len);
> +
> +		end = start + frag_iter->len;
> +		copy = end - offset;
> +		if (copy > 0) {
> +			if (copy > len)
> +				copy = len;
> +			ret = __skb_nsg(frag_iter, offset - start, copy,
> +					recursion_level + 1);
> +			if (unlikely(ret < 0))
> +				return ret;
> +			elt += ret;
> +			len -= copy;
> +			if (len == 0)
> +				return elt;
> +			offset += copy;
> +		}
> +		start = end;
> +	}
> +	BUG_ON(len);
> +	return elt;
> +}
> +
> +/* Return the number of scatterlist elements required to completely map
> the
> + * skb, or -EMSGSIZE if the recursion depth is exceeded.
> + */
> +static int skb_nsg(struct sk_buff *skb, int offset, int len)
> +{
> +	return __skb_nsg(skb, offset, len, 0);
> +}
> +
>  static int tls_do_decryption(struct sock *sk,
>  			     struct scatterlist *sgin,
>  			     struct scatterlist *sgout,
> @@ -693,7 +767,7 @@ int decrypt_skb(struct sock *sk, struct sk_buff *skb,
>  	struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
>  	struct scatterlist *sgin = &sgin_arr[0];
>  	struct strp_msg *rxm = strp_msg(skb);
> -	int ret, nsg = ARRAY_SIZE(sgin_arr);
> +	int ret, nsg;
>  	struct sk_buff *unused;
> 
>  	ret = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
> @@ -704,11 +778,27 @@ int decrypt_skb(struct sock *sk, struct sk_buff
> *skb,
> 
>  	memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
>  	if (!sgout) {
> -		nsg = skb_cow_data(skb, 0, &unused) + 1;
> +		nsg = skb_cow_data(skb, 0, &unused);
> +	} else {
> +		nsg = skb_nsg(skb,
> +			      rxm->offset + tls_ctx->rx.prepend_size,
> +			      rxm->full_len - tls_ctx->rx.prepend_size);
> +		if (nsg <= 0)
> +			return nsg;
> +	}
> +
> +	// We need one extra for ctx->rx_aad_ciphertext
> +	nsg++;
> +
> +	if (nsg > ARRAY_SIZE(sgin_arr)) {
>  		sgin = kmalloc_array(nsg, sizeof(*sgin), sk->sk_allocation);
> -		sgout = sgin;
> +		if (!sgin)
> +			return -ENOMEM;
>  	}
> 
> +	if (!sgout)
> +		sgout = sgin;
> +
>  	sg_init_table(sgin, nsg);
>  	sg_set_buf(&sgin[0], ctx->rx_aad_ciphertext, TLS_AAD_SPACE_SIZE);
> 
> --
> 2.17.1

I prefer my name be removed from commit message.

Reported-by: Vakul Garg <Vakul.garg@nxp.com>
Reviewed-by: Vakul Garg <Vakul.garg@nxp.com>
Tested-by: Vakul Garg <Vakul.garg@nxp.com>

^ permalink raw reply

* RE: [PATCH] tipc: fix an interrupt unsafe locking scenario
From: Jon Maloy @ 2018-08-07 16:10 UTC (permalink / raw)
  To: Ying Xue, netdev@vger.kernel.org
  Cc: davem@davemloft.net, tipc-discussion@lists.sourceforge.net
In-Reply-To: <1533628352-31928-1-git-send-email-ying.xue@windriver.com>

Nice fix. I was a little in doubt about using that lock, but deemed it was overkill to introduce an extra lock just for this case.

Acked-by: Jon Maloy <maloy@donjonn.com>

> -----Original Message-----
> From: Ying Xue <ying.xue@windriver.com>
> Sent: Tuesday, 07 August, 2018 02:53
> To: netdev@vger.kernel.org; Jon Maloy <jon.maloy@ericsson.com>
> Cc: davem@davemloft.net; tipc-discussion@lists.sourceforge.net
> Subject: [PATCH] tipc: fix an interrupt unsafe locking scenario
> 
> Commit 9faa89d4ed9d ("tipc: make function tipc_net_finalize() thread
> safe") tries to make it thread safe to set node address, so it uses
> node_list_lock lock to serialize the whole process of setting node
> address in tipc_net_finalize(). But it causes the following interrupt
> unsafe locking scenario:
> 
>        CPU0                    CPU1
>        ----                    ----
>   rht_deferred_worker()
>   rhashtable_rehash_table()
>   lock(&(&ht->lock)->rlock)
> 			       tipc_nl_compat_doit()
>                                tipc_net_finalize()
>                                local_irq_disable();
>                                lock(&(&tn->node_list_lock)->rlock);
>                                tipc_sk_reinit()
>                                rhashtable_walk_enter()
>                                lock(&(&ht->lock)->rlock);
>   <Interrupt>
>   tipc_disc_rcv()
>   tipc_node_check_dest()
>   tipc_node_create()
>   lock(&(&tn->node_list_lock)->rlock);
> 
>  *** DEADLOCK ***
> 
> When rhashtable_rehash_table() holds ht->lock on CPU0, it doesn't
> disable BH. So if an interrupt happens after the lock, it can create
> an inverse lock ordering between ht->lock and tn->node_list_lock. As
> a consequence, deadlock might happen.
> 
> The reason causing the inverse lock ordering scenario above is because
> the initial purpose of node_list_lock is not designed to do the
> serialization of node address setting.
> 
> As cmpxchg() can guarantee CAS (compare-and-swap) process is atomic,
> we use it to replace node_list_lock to ensure setting node address can
> be atomically finished. It turns out the potential deadlock can be
> avoided as well.
> 
> Fixes: 9faa89d4ed9d ("tipc: make function tipc_net_finalize() thread safe")
> Signed-off-by: Ying Xue <ying.xue@windriver.com>
> ---
>  net/tipc/net.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/net/tipc/net.c b/net/tipc/net.c
> index a7f6964..62199cf 100644
> --- a/net/tipc/net.c
> +++ b/net/tipc/net.c
> @@ -123,15 +123,13 @@ void tipc_net_finalize(struct net *net, u32 addr)
>  {
>  	struct tipc_net *tn = tipc_net(net);
> 
> -	spin_lock_bh(&tn->node_list_lock);
> -	if (!tipc_own_addr(net)) {
> +	if (!cmpxchg(&tn->node_addr, 0, addr)) {
>  		tipc_set_node_addr(net, addr);
>  		tipc_named_reinit(net);
>  		tipc_sk_reinit(net);
>  		tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
>  				     TIPC_CLUSTER_SCOPE, 0, addr);
>  	}
> -	spin_unlock_bh(&tn->node_list_lock);
>  }
> 
>  void tipc_net_stop(struct net *net)
> --
> 2.7.4

^ permalink raw reply

* Re: [PATCH net-next] ieee802154: hwsim: fix rcu address annotation
From: David Miller @ 2018-08-07 16:09 UTC (permalink / raw)
  To: stefan; +Cc: aring, netdev, linux-wpan, kernel
In-Reply-To: <2c0316a5-30bb-3064-a992-8152232df94f@datenfreihafen.org>

From: Stefan Schmidt <stefan@datenfreihafen.org>
Date: Tue, 7 Aug 2018 17:28:43 +0200

> Could you apply this patch directly to net-next?

Sure, no problem, done.

^ permalink raw reply

* Re: [PATCH 0/3] Add Broadcom Omega SoC internal switch and phy
From: Andrew Lunn @ 2018-08-07 18:08 UTC (permalink / raw)
  To: Arun Parameswaran
  Cc: David S. Miller, Florian Fainelli, Vivien Didelot, Rob Herring,
	Mark Rutland, netdev, devicetree, linux-kernel,
	bcm-kernel-feedback-list
In-Reply-To: <1533661364-15381-1-git-send-email-arun.parameswaran@broadcom.com>

On Tue, Aug 07, 2018 at 10:02:41AM -0700, Arun Parameswaran wrote:
> Hi,
> 
> The patchset is based on David Miller's "net-next" repo.
> 
> The patches add support for the Broadcom Omega SoC's internal ethernet
> switch and the internal gphy.
> 
> The internal ethernet switch in the Omega is a b53 srab based switch.
> The support for the switch is added to the b53 driver in the dsa
> framework.
> 
> The gphy support is added to the bcm7xxx driver.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH v6 5/9] fm10k: Do not call pcie_print_link_status()
From: Jeff Kirsher @ 2018-08-07 17:52 UTC (permalink / raw)
  To: Alexandru Gagniuc, linux-pci, bhelgaas, jakub.kicinski
  Cc: keith.busch, alex_gagniuc, austin_bolen, shyam_iyer, Ariel Elior,
	everest-linux-l2, David S. Miller, Michael Chan, Ganesh Goudar,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Dirk van der Merwe,
	netdev, linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <20180806232600.25694-5-mr.nuke.me@gmail.com>

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

On Mon, 2018-08-06 at 18:25 -0500, Alexandru Gagniuc wrote:
> This is now done by the PCI core to warn of sub-optimal bandwidth.
> 
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 3 ---
>  1 file changed, 3 deletions(-)

Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v6 6/9] ixgbe: Do not call pcie_print_link_status()
From: Jeff Kirsher @ 2018-08-07 17:51 UTC (permalink / raw)
  To: Alexandru Gagniuc, linux-pci, bhelgaas, jakub.kicinski
  Cc: keith.busch, alex_gagniuc, austin_bolen, shyam_iyer, Ariel Elior,
	everest-linux-l2, David S. Miller, Michael Chan, Ganesh Goudar,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Dirk van der Merwe,
	netdev, linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <20180806232600.25694-6-mr.nuke.me@gmail.com>

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

On Mon, 2018-08-06 at 18:25 -0500, Alexandru Gagniuc wrote:
> This is now done by the PCI core to warn of sub-optimal bandwidth.
> 
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 26 ---------------
> ----
>  1 file changed, 26 deletions(-)

Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* [PATCH net-next 6/6] nfp: flower: add geneve option match offload
From: Simon Horman @ 2018-08-07 15:36 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>

Introduce a new layer for matching on geneve options. This allows
offloading filters configured to match geneve with options.

Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  6 ++++
 drivers/net/ethernet/netronome/nfp/flower/match.c  | 25 ++++++++++++++
 .../net/ethernet/netronome/nfp/flower/offload.c    | 38 ++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index f2aeae88cbf0..325954b829c8 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -52,6 +52,7 @@
 #define NFP_FLOWER_LAYER_VXLAN		BIT(7)
 
 #define NFP_FLOWER_LAYER2_GENEVE	BIT(5)
+#define NFP_FLOWER_LAYER2_GENEVE_OP	BIT(6)
 
 #define NFP_FLOWER_MASK_VLAN_PRIO	GENMASK(15, 13)
 #define NFP_FLOWER_MASK_VLAN_CFI	BIT(12)
@@ -85,6 +86,7 @@
 /* Maximum allowed geneve options */
 #define NFP_FL_MAX_GENEVE_OPT_ACT	32
 #define NFP_FL_MAX_GENEVE_OPT_CNT	64
+#define NFP_FL_MAX_GENEVE_OPT_KEY	32
 
 /* Action opcodes */
 #define NFP_FL_ACTION_OPCODE_OUTPUT		0
@@ -381,6 +383,10 @@ struct nfp_flower_ipv4_udp_tun {
 	__be32 tun_id;
 };
 
+struct nfp_flower_geneve_options {
+	u8 data[NFP_FL_MAX_GENEVE_OPT_KEY];
+};
+
 #define NFP_FL_TUN_VNI_OFFSET 8
 
 /* The base header for a control message packet.
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index b1cbe6927cba..a0c72f277faa 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -262,6 +262,21 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
 	nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version);
 }
 
+static int
+nfp_flower_compile_geneve_opt(void *key_buf, struct tc_cls_flower_offload *flow,
+			      bool mask_version)
+{
+	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
+	struct flow_dissector_key_enc_opts *opts;
+
+	opts = skb_flow_dissector_target(flow->dissector,
+					 FLOW_DISSECTOR_KEY_ENC_OPTS,
+					 target);
+	memcpy(key_buf, opts->data, opts->len);
+
+	return 0;
+}
+
 static void
 nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame,
 				struct tc_cls_flower_offload *flow,
@@ -424,6 +439,16 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
 			nfp_flow->nfp_tun_ipv4_addr = tun_dst;
 			nfp_tunnel_add_ipv4_off(netdev_repr->app, tun_dst);
 		}
+
+		if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) {
+			err = nfp_flower_compile_geneve_opt(ext, flow, false);
+			if (err)
+				return err;
+
+			err = nfp_flower_compile_geneve_opt(msk, flow, true);
+			if (err)
+				return err;
+		}
 	}
 
 	return 0;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index d2230a0e49b9..2edab01c3beb 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -66,6 +66,7 @@
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \
+	 BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IP) | \
 	 BIT(FLOW_DISSECTOR_KEY_MPLS) | \
 	 BIT(FLOW_DISSECTOR_KEY_IP))
@@ -75,6 +76,7 @@
 	 BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
+	 BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IP))
 
@@ -141,6 +143,21 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
 }
 
 static int
+nfp_flower_calc_opt_layer(struct flow_dissector_key_enc_opts *enc_opts,
+			  u32 *key_layer_two, int *key_size)
+{
+	if (enc_opts->len > NFP_FL_MAX_GENEVE_OPT_KEY)
+		return -EOPNOTSUPP;
+
+	if (enc_opts->len > 0) {
+		*key_layer_two |= NFP_FLOWER_LAYER2_GENEVE_OP;
+		*key_size += sizeof(struct nfp_flower_geneve_options);
+	}
+
+	return 0;
+}
+
+static int
 nfp_flower_calculate_key_layers(struct nfp_app *app,
 				struct nfp_fl_key_ls *ret_key_ls,
 				struct tc_cls_flower_offload *flow,
@@ -153,6 +170,7 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
 	u32 key_layer_two;
 	u8 key_layer;
 	int key_size;
+	int err;
 
 	if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
 		return -EOPNOTSUPP;
@@ -178,6 +196,7 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
 			       FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
 		struct flow_dissector_key_ipv4_addrs *mask_ipv4 = NULL;
 		struct flow_dissector_key_ports *mask_enc_ports = NULL;
+		struct flow_dissector_key_enc_opts *enc_op = NULL;
 		struct flow_dissector_key_ports *enc_ports = NULL;
 		struct flow_dissector_key_control *mask_enc_ctl =
 			skb_flow_dissector_target(flow->dissector,
@@ -214,11 +233,21 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
 		if (mask_enc_ports->dst != cpu_to_be16(~0))
 			return -EOPNOTSUPP;
 
+		if (dissector_uses_key(flow->dissector,
+				       FLOW_DISSECTOR_KEY_ENC_OPTS)) {
+			enc_op = skb_flow_dissector_target(flow->dissector,
+							   FLOW_DISSECTOR_KEY_ENC_OPTS,
+							   flow->key);
+		}
+
 		switch (enc_ports->dst) {
 		case htons(NFP_FL_VXLAN_PORT):
 			*tun_type = NFP_FL_TUNNEL_VXLAN;
 			key_layer |= NFP_FLOWER_LAYER_VXLAN;
 			key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
+
+			if (enc_op)
+				return -EOPNOTSUPP;
 			break;
 		case htons(NFP_FL_GENEVE_PORT):
 			if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE))
@@ -228,6 +257,15 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
 			key_size += sizeof(struct nfp_flower_ext_meta);
 			key_layer_two |= NFP_FLOWER_LAYER2_GENEVE;
 			key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
+
+			if (!enc_op)
+				break;
+			if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE_OPT))
+				return -EOPNOTSUPP;
+			err = nfp_flower_calc_opt_layer(enc_op, &key_layer_two,
+							&key_size);
+			if (err)
+				return err;
 			break;
 		default:
 			return -EOPNOTSUPP;
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 5/6] nfp: flower: add geneve option push action offload
From: Simon Horman @ 2018-08-07 15:36 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>

Introduce new push geneve option action. This allows offloading
filters configured to entunnel geneve with options.

Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/action.c | 100 +++++++++++++++++++--
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  20 ++++-
 drivers/net/ethernet/netronome/nfp/flower/main.h   |   1 +
 3 files changed, 114 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index a79d078ab3e8..0ba0356ec4e6 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -32,6 +32,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <net/geneve.h>
 #include <net/pkt_cls.h>
 #include <net/switchdev.h>
 #include <net/tc_act/tc_csum.h>
@@ -45,7 +46,15 @@
 #include "main.h"
 #include "../nfp_net_repr.h"
 
-#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS	(TUNNEL_CSUM | TUNNEL_KEY)
+/* The kernel versions of TUNNEL_* are not ABI and therefore vulnerable
+ * to change. Such changes will break our FW ABI.
+ */
+#define NFP_FL_TUNNEL_CSUM			cpu_to_be16(0x01)
+#define NFP_FL_TUNNEL_KEY			cpu_to_be16(0x04)
+#define NFP_FL_TUNNEL_GENEVE_OPT		cpu_to_be16(0x0800)
+#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS	(NFP_FL_TUNNEL_CSUM | \
+						 NFP_FL_TUNNEL_KEY | \
+						 NFP_FL_TUNNEL_GENEVE_OPT)
 
 static void nfp_fl_pop_vlan(struct nfp_fl_pop_vlan *pop_vlan)
 {
@@ -229,7 +238,71 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len)
 }
 
 static int
-nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
+nfp_fl_push_geneve_options(struct nfp_fl_payload *nfp_fl, int *list_len,
+			   const struct tc_action *action)
+{
+	struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action);
+	int opt_len, opt_cnt, act_start, tot_push_len;
+	u8 *src = ip_tunnel_info_opts(ip_tun);
+
+	/* We need to populate the options in reverse order for HW.
+	 * Therefore we go through the options, calculating the
+	 * number of options and the total size, then we populate
+	 * them in reverse order in the action list.
+	 */
+	opt_cnt = 0;
+	tot_push_len = 0;
+	opt_len = ip_tun->options_len;
+	while (opt_len > 0) {
+		struct geneve_opt *opt = (struct geneve_opt *)src;
+
+		opt_cnt++;
+		if (opt_cnt > NFP_FL_MAX_GENEVE_OPT_CNT)
+			return -EOPNOTSUPP;
+
+		tot_push_len += sizeof(struct nfp_fl_push_geneve) +
+			       opt->length * 4;
+		if (tot_push_len > NFP_FL_MAX_GENEVE_OPT_ACT)
+			return -EOPNOTSUPP;
+
+		opt_len -= sizeof(struct geneve_opt) + opt->length * 4;
+		src += sizeof(struct geneve_opt) + opt->length * 4;
+	}
+
+	if (*list_len + tot_push_len > NFP_FL_MAX_A_SIZ)
+		return -EOPNOTSUPP;
+
+	act_start = *list_len;
+	*list_len += tot_push_len;
+	src = ip_tunnel_info_opts(ip_tun);
+	while (opt_cnt) {
+		struct geneve_opt *opt = (struct geneve_opt *)src;
+		struct nfp_fl_push_geneve *push;
+		size_t act_size, len;
+
+		opt_cnt--;
+		act_size = sizeof(struct nfp_fl_push_geneve) + opt->length * 4;
+		tot_push_len -= act_size;
+		len = act_start + tot_push_len;
+
+		push = (struct nfp_fl_push_geneve *)&nfp_fl->action_data[len];
+		push->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_GENEVE;
+		push->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+		push->reserved = 0;
+		push->class = opt->opt_class;
+		push->type = opt->type;
+		push->length = opt->length;
+		memcpy(&push->opt_data, opt->opt_data, opt->length * 4);
+
+		src += sizeof(struct geneve_opt) + opt->length * 4;
+	}
+
+	return 0;
+}
+
+static int
+nfp_fl_set_ipv4_udp_tun(struct nfp_app *app,
+			struct nfp_fl_set_ipv4_udp_tun *set_tun,
 			const struct tc_action *action,
 			struct nfp_fl_pre_tunnel *pre_tun,
 			enum nfp_flower_tun_type tun_type,
@@ -237,11 +310,17 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
 {
 	size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun);
 	struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action);
+	struct nfp_flower_priv *priv = app->priv;
 	u32 tmp_set_ip_tun_type_index = 0;
 	/* Currently support one pre-tunnel so index is always 0. */
 	int pretun_idx = 0;
 
-	if (ip_tun->options_len)
+	BUILD_BUG_ON(NFP_FL_TUNNEL_CSUM != TUNNEL_CSUM ||
+		     NFP_FL_TUNNEL_KEY	!= TUNNEL_KEY ||
+		     NFP_FL_TUNNEL_GENEVE_OPT != TUNNEL_GENEVE_OPT);
+	if (ip_tun->options_len &&
+	    (tun_type != NFP_FL_TUNNEL_GENEVE ||
+	    !(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE_OPT)))
 		return -EOPNOTSUPP;
 
 	set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL;
@@ -281,11 +360,16 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
 
 	set_tun->tos = ip_tun->key.tos;
 
-	if (!(ip_tun->key.tun_flags & TUNNEL_KEY) ||
+	if (!(ip_tun->key.tun_flags & NFP_FL_TUNNEL_KEY) ||
 	    ip_tun->key.tun_flags & ~NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS)
 		return -EOPNOTSUPP;
 	set_tun->tun_flags = ip_tun->key.tun_flags;
 
+	if (tun_type == NFP_FL_TUNNEL_GENEVE) {
+		set_tun->tun_proto = htons(ETH_P_TEB);
+		set_tun->tun_len = ip_tun->options_len / 4;
+	}
+
 	/* Complete pre_tunnel action. */
 	pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst;
 
@@ -674,9 +758,13 @@ nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a,
 		nfp_fl->meta.shortcut = cpu_to_be32(NFP_FL_SC_ACT_NULL);
 		*a_len += sizeof(struct nfp_fl_pre_tunnel);
 
+		err = nfp_fl_push_geneve_options(nfp_fl, a_len, a);
+		if (err)
+			return err;
+
 		set_tun = (void *)&nfp_fl->action_data[*a_len];
-		err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type,
-					      netdev);
+		err = nfp_fl_set_ipv4_udp_tun(app, set_tun, a, pre_tun,
+					      *tun_type, netdev);
 		if (err)
 			return err;
 		*a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 174acecfba01..f2aeae88cbf0 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -37,6 +37,7 @@
 #include <linux/bitfield.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
+#include <net/geneve.h>
 
 #include "../nfp_app.h"
 #include "../nfpcore/nfp_cpp.h"
@@ -81,6 +82,10 @@
 #define NFP_FL_MAX_A_SIZ		1216
 #define NFP_FL_LW_SIZ			2
 
+/* Maximum allowed geneve options */
+#define NFP_FL_MAX_GENEVE_OPT_ACT	32
+#define NFP_FL_MAX_GENEVE_OPT_CNT	64
+
 /* Action opcodes */
 #define NFP_FL_ACTION_OPCODE_OUTPUT		0
 #define NFP_FL_ACTION_OPCODE_PUSH_VLAN		1
@@ -94,6 +99,7 @@
 #define NFP_FL_ACTION_OPCODE_SET_TCP		15
 #define NFP_FL_ACTION_OPCODE_PRE_LAG		16
 #define NFP_FL_ACTION_OPCODE_PRE_TUNNEL		17
+#define NFP_FL_ACTION_OPCODE_PUSH_GENEVE	26
 #define NFP_FL_ACTION_OPCODE_NUM		32
 
 #define NFP_FL_OUT_FLAGS_LAST		BIT(15)
@@ -206,7 +212,19 @@ struct nfp_fl_set_ipv4_udp_tun {
 	__be16 tun_flags;
 	u8 ttl;
 	u8 tos;
-	__be32 extra[2];
+	__be32 extra;
+	u8 tun_len;
+	u8 res2;
+	__be16 tun_proto;
+};
+
+struct nfp_fl_push_geneve {
+	struct nfp_fl_act_head head;
+	__be16 reserved;
+	__be16 class;
+	u8 type;
+	u8 length;
+	u8 opt_data[];
 };
 
 /* Metadata with L2 (1W/4B)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index ef2114d13387..85f8209bf007 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -69,6 +69,7 @@ struct nfp_app;
 /* Extra features bitmap. */
 #define NFP_FL_FEATS_GENEVE		BIT(0)
 #define NFP_FL_NBI_MTU_SETTING		BIT(1)
+#define NFP_FL_FEATS_GENEVE_OPT		BIT(2)
 #define NFP_FL_FEATS_LAG		BIT(31)
 
 struct nfp_fl_mask_id {
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 4/6] net/sched: allow flower to match tunnel options
From: Simon Horman @ 2018-08-07 15:36 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>

Allow matching on options in Geneve tunnel headers.
This makes use of existing tunnel metadata support.

The options can be described in the form
CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK, where CLASS is
represented as a 16bit hexadecimal value, TYPE as an 8bit
hexadecimal value and DATA as a variable length hexadecimal value.

e.g.
 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev geneve0 ingress
 # tc filter add dev geneve0 protocol ip parent ffff: \
     flower \
       enc_src_ip 10.0.99.192 \
       enc_dst_ip 10.0.99.193 \
       enc_key_id 11 \
       geneve_opts 0102:80:1122334421314151/ffff:ff:ffffffffffffffff \
       ip_proto udp \
       action mirred egress redirect dev eth1

This patch adds support for matching Geneve options in the order
supplied by the user. This leads to an efficient implementation in
the software datapath (and in our opinion hardware datapaths that
offload this feature). It is also compatible with Geneve options
matching provided by the Open vSwitch kernel datapath which is
relevant here as the Flower classifier may be used as a mechanism
to program flows into hardware as a form of Open vSwitch datapath
offload (sometimes referred to as OVS-TC). The netlink
Kernel/Userspace API may be extended, for example by adding a flag,
if other matching options are desired, for example matching given
options in any order. This would require an implementation in the
TC software datapath. And be done in a way that drivers that
facilitate offload of the Flower classifier can reject or accept
such flows based on hardware datapath capabilities.

This approach was discussed and agreed on at Netconf 2018 in Seoul.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/uapi/linux/pkt_cls.h |  26 +++++
 net/sched/cls_flower.c       | 244 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 48e5b5d49a34..be382fb0592d 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -480,12 +480,38 @@ enum {
 	TCA_FLOWER_KEY_ENC_IP_TTL,	/* u8 */
 	TCA_FLOWER_KEY_ENC_IP_TTL_MASK,	/* u8 */
 
+	TCA_FLOWER_KEY_ENC_OPTS,
+	TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
 	__TCA_FLOWER_MAX,
 };
 
 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
 
 enum {
+	TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
+	TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
+					 * TCA_FLOWER_KEY_ENC_OPT_GENEVE_
+					 * attributes
+					 */
+	__TCA_FLOWER_KEY_ENC_OPTS_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
+
+enum {
+	TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC,
+	TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS,            /* u16 */
+	TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE,             /* u8 */
+	TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA,             /* 4 to 128 bytes */
+
+	__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
+		(__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
+
+enum {
 	TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
 	TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
 };
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index a3b69bb6f4b0..9da244235170 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -24,6 +24,7 @@
 #include <net/pkt_cls.h>
 #include <net/ip.h>
 #include <net/flow_dissector.h>
+#include <net/geneve.h>
 
 #include <net/dst.h>
 #include <net/dst_metadata.h>
@@ -53,6 +54,7 @@ struct fl_flow_key {
 	struct flow_dissector_key_tcp tcp;
 	struct flow_dissector_key_ip ip;
 	struct flow_dissector_key_ip enc_ip;
+	struct flow_dissector_key_enc_opts enc_opts;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
 
 struct fl_flow_mask_range {
@@ -482,6 +484,21 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
 	[TCA_FLOWER_KEY_ENC_IP_TOS_MASK] = { .type = NLA_U8 },
 	[TCA_FLOWER_KEY_ENC_IP_TTL]	 = { .type = NLA_U8 },
 	[TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },
+	[TCA_FLOWER_KEY_ENC_OPTS]	= { .type = NLA_NESTED },
+	[TCA_FLOWER_KEY_ENC_OPTS_MASK]	= { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+enc_opts_policy[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1] = {
+	[TCA_FLOWER_KEY_ENC_OPTS_GENEVE]        = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
+	[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]      = { .type = NLA_U16 },
+	[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]       = { .type = NLA_U8 },
+	[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]       = { .type = NLA_BINARY,
+						       .len = 128 },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
@@ -603,6 +620,145 @@ static void fl_set_key_ip(struct nlattr **tb, bool encap,
 	fl_set_key_val(tb, &key->ttl, ttl_key, &mask->ttl, ttl_mask, sizeof(key->ttl));
 }
 
+static int fl_set_geneve_opt(const struct nlattr *nla, struct fl_flow_key *key,
+			     int depth, int option_len,
+			     struct netlink_ext_ack *extack)
+{
+	struct nlattr *tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1];
+	struct nlattr *class = NULL, *type = NULL, *data = NULL;
+	struct geneve_opt *opt;
+	int err, data_len = 0;
+
+	if (option_len > sizeof(struct geneve_opt))
+		data_len = option_len - sizeof(struct geneve_opt);
+
+	opt = (struct geneve_opt *)&key->enc_opts.data[key->enc_opts.len];
+	memset(opt, 0xff, option_len);
+	opt->length = data_len / 4;
+	opt->r1 = 0;
+	opt->r2 = 0;
+	opt->r3 = 0;
+
+	/* If no mask has been prodived we assume an exact match. */
+	if (!depth)
+		return sizeof(struct geneve_opt) + data_len;
+
+	if (nla_type(nla) != TCA_FLOWER_KEY_ENC_OPTS_GENEVE) {
+		NL_SET_ERR_MSG(extack, "Non-geneve option type for mask");
+		return -EINVAL;
+	}
+
+	err = nla_parse_nested(tb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX,
+			       nla, geneve_opt_policy, extack);
+	if (err < 0)
+		return err;
+
+	/* We are not allowed to omit any of CLASS, TYPE or DATA
+	 * fields from the key.
+	 */
+	if (!option_len &&
+	    (!tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] ||
+	     !tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] ||
+	     !tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA])) {
+		NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
+		return -EINVAL;
+	}
+
+	/* Omitting any of CLASS, TYPE or DATA fields is allowed
+	 * for the mask.
+	 */
+	if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]) {
+		int new_len = key->enc_opts.len;
+
+		data = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA];
+		data_len = nla_len(data);
+		if (data_len < 4) {
+			NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
+			return -ERANGE;
+		}
+		if (data_len % 4) {
+			NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
+			return -ERANGE;
+		}
+
+		new_len += sizeof(struct geneve_opt) + data_len;
+		BUILD_BUG_ON(FLOW_DIS_TUN_OPTS_MAX != IP_TUNNEL_OPTS_MAX);
+		if (new_len > FLOW_DIS_TUN_OPTS_MAX) {
+			NL_SET_ERR_MSG(extack, "Tunnel options exceeds max size");
+			return -ERANGE;
+		}
+		opt->length = data_len / 4;
+		memcpy(opt->opt_data, nla_data(data), data_len);
+	}
+
+	if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]) {
+		class = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS];
+		opt->opt_class = nla_get_be16(class);
+	}
+
+	if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]) {
+		type = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE];
+		opt->type = nla_get_u8(type);
+	}
+
+	return sizeof(struct geneve_opt) + data_len;
+}
+
+static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
+			  struct fl_flow_key *mask,
+			  struct netlink_ext_ack *extack)
+{
+	const struct nlattr *nla_enc_key, *nla_opt_key, *nla_opt_msk = NULL;
+	int option_len, key_depth, msk_depth = 0;
+
+	nla_enc_key = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS]);
+
+	if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) {
+		nla_opt_msk = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
+		msk_depth = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
+	}
+
+	nla_for_each_attr(nla_opt_key, nla_enc_key,
+			  nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]), key_depth) {
+		switch (nla_type(nla_opt_key)) {
+		case TCA_FLOWER_KEY_ENC_OPTS_GENEVE:
+			option_len = 0;
+			key->enc_opts.dst_opt_type = TUNNEL_GENEVE_OPT;
+			option_len = fl_set_geneve_opt(nla_opt_key, key,
+						       key_depth, option_len,
+						       extack);
+			if (option_len < 0)
+				return option_len;
+
+			key->enc_opts.len += option_len;
+			/* At the same time we need to parse through the mask
+			 * in order to verify exact and mask attribute lengths.
+			 */
+			mask->enc_opts.dst_opt_type = TUNNEL_GENEVE_OPT;
+			option_len = fl_set_geneve_opt(nla_opt_msk, mask,
+						       msk_depth, option_len,
+						       extack);
+			if (option_len < 0)
+				return option_len;
+
+			mask->enc_opts.len += option_len;
+			if (key->enc_opts.len != mask->enc_opts.len) {
+				NL_SET_ERR_MSG(extack, "Key and mask miss aligned");
+				return -EINVAL;
+			}
+
+			if (msk_depth)
+				nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
+			break;
+		default:
+			NL_SET_ERR_MSG(extack, "Unknown tunnel option type");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int fl_set_key(struct net *net, struct nlattr **tb,
 		      struct fl_flow_key *key, struct fl_flow_key *mask,
 		      struct netlink_ext_ack *extack)
@@ -799,6 +955,12 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
 
 	fl_set_key_ip(tb, true, &key->enc_ip, &mask->enc_ip);
 
+	if (tb[TCA_FLOWER_KEY_ENC_OPTS]) {
+		ret = fl_set_enc_opt(tb, key, mask, extack);
+		if (ret)
+			return ret;
+	}
+
 	if (tb[TCA_FLOWER_KEY_FLAGS])
 		ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);
 
@@ -894,6 +1056,8 @@ static void fl_init_dissector(struct flow_dissector *dissector,
 			     FLOW_DISSECTOR_KEY_ENC_PORTS, enc_tp);
 	FL_KEY_SET_IF_MASKED(mask, keys, cnt,
 			     FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);
+	FL_KEY_SET_IF_MASKED(mask, keys, cnt,
+			     FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);
 
 	skb_flow_dissector_init(dissector, keys, cnt);
 }
@@ -1414,6 +1578,83 @@ static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask)
 	return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask);
 }
 
+static int fl_dump_key_geneve_opt(struct sk_buff *skb,
+				  struct flow_dissector_key_enc_opts *enc_opts)
+{
+	struct geneve_opt *opt;
+	struct nlattr *nest;
+	int opt_off = 0;
+
+	nest = nla_nest_start(skb, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
+	if (!nest)
+		goto nla_put_failure;
+
+	while (enc_opts->len > opt_off) {
+		opt = (struct geneve_opt *)&enc_opts->data[opt_off];
+
+		if (nla_put_be16(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS,
+				 opt->opt_class))
+			goto nla_put_failure;
+		if (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE,
+			       opt->type))
+			goto nla_put_failure;
+		if (nla_put(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA,
+			    opt->length * 4, opt->opt_data))
+			goto nla_put_failure;
+
+		opt_off += sizeof(struct geneve_opt) + opt->length * 4;
+	}
+	nla_nest_end(skb, nest);
+	return 0;
+
+nla_put_failure:
+	nla_nest_cancel(skb, nest);
+	return -EMSGSIZE;
+}
+
+static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
+			       struct flow_dissector_key_enc_opts *enc_opts)
+{
+	struct nlattr *nest;
+	int err;
+
+	if (!enc_opts->len)
+		return 0;
+
+	nest = nla_nest_start(skb, enc_opt_type);
+	if (!nest)
+		goto nla_put_failure;
+
+	switch (enc_opts->dst_opt_type) {
+	case TUNNEL_GENEVE_OPT:
+		err = fl_dump_key_geneve_opt(skb, enc_opts);
+		if (err)
+			goto nla_put_failure;
+		break;
+	default:
+		goto nla_put_failure;
+	}
+	nla_nest_end(skb, nest);
+	return 0;
+
+nla_put_failure:
+	nla_nest_cancel(skb, nest);
+	return -EMSGSIZE;
+}
+
+static int fl_dump_key_enc_opt(struct sk_buff *skb,
+			       struct flow_dissector_key_enc_opts *key_opts,
+			       struct flow_dissector_key_enc_opts *msk_opts)
+{
+	int err;
+
+	err = fl_dump_key_options(skb, TCA_FLOWER_KEY_ENC_OPTS, key_opts);
+	if (err)
+		return err;
+
+	return fl_dump_key_options(skb, TCA_FLOWER_KEY_ENC_OPTS_MASK, msk_opts);
+}
+
 static int fl_dump_key(struct sk_buff *skb, struct net *net,
 		       struct fl_flow_key *key, struct fl_flow_key *mask)
 {
@@ -1594,7 +1835,8 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net,
 			    &mask->enc_tp.dst,
 			    TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
 			    sizeof(key->enc_tp.dst)) ||
-	    fl_dump_key_ip(skb, true, &key->enc_ip, &mask->enc_ip))
+	    fl_dump_key_ip(skb, true, &key->enc_ip, &mask->enc_ip) ||
+	    fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts))
 		goto nla_put_failure;
 
 	if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 3/6] flow_dissector: allow dissection of tunnel options from metadata
From: Simon Horman @ 2018-08-07 15:36 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

Allow the existing 'dissection' of tunnel metadata to 'dissect'
options already present in tunnel metadata. This dissection is
controlled by a new dissector key, FLOW_DISSECTOR_KEY_ENC_OPTS.

This dissection only occurs when skb_flow_dissect_tunnel_info()
is called, currently only the Flower classifier makes that call.
So there should be no impact on other users of the flow dissector.

This is in preparation for allowing the flower classifier to
match on Geneve options.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/net/flow_dissector.h | 17 +++++++++++++++++
 net/core/flow_dissector.c    | 19 ++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 2a17f041f7a1..6a4586dcdede 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -57,6 +57,21 @@ struct flow_dissector_key_mpls {
 		mpls_label:20;
 };
 
+#define FLOW_DIS_TUN_OPTS_MAX 255
+/**
+ * struct flow_dissector_key_enc_opts:
+ * @data: tunnel option data
+ * @len: length of tunnel option data
+ * @dst_opt_type: tunnel option type
+ */
+struct flow_dissector_key_enc_opts {
+	u8 data[FLOW_DIS_TUN_OPTS_MAX];	/* Using IP_TUNNEL_OPTS_MAX is desired
+					 * here but seems difficult to #include
+					 */
+	u8 len;
+	__be16 dst_opt_type;
+};
+
 struct flow_dissector_key_keyid {
 	__be32	keyid;
 };
@@ -208,6 +223,8 @@ enum flow_dissector_key_id {
 	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
 	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */
 	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
+	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
+
 	FLOW_DISSECTOR_KEY_MAX,
 };
 
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 08a5184f4b34..ce9eeeb7c024 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -154,7 +154,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
 	    !dissector_uses_key(flow_dissector,
 				FLOW_DISSECTOR_KEY_ENC_PORTS) &&
 	    !dissector_uses_key(flow_dissector,
-				FLOW_DISSECTOR_KEY_ENC_IP))
+				FLOW_DISSECTOR_KEY_ENC_IP) &&
+	    !dissector_uses_key(flow_dissector,
+				FLOW_DISSECTOR_KEY_ENC_OPTS))
 		return;
 
 	info = skb_tunnel_info(skb);
@@ -224,6 +226,21 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
 		ip->tos = key->tos;
 		ip->ttl = key->ttl;
 	}
+
+	if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_OPTS)) {
+		struct flow_dissector_key_enc_opts *enc_opt;
+
+		enc_opt = skb_flow_dissector_target(flow_dissector,
+						    FLOW_DISSECTOR_KEY_ENC_OPTS,
+						    target_container);
+
+		if (info->options_len) {
+			enc_opt->len = info->options_len;
+			ip_tunnel_info_opts_get(enc_opt->data, info);
+			enc_opt->dst_opt_type = info->key.tun_flags &
+						TUNNEL_OPTIONS_PRESENT;
+		}
+	}
 }
 EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 2/6] nfp: flower: allow matching on ipv4 UDP tunnel tos and ttl
From: Simon Horman @ 2018-08-07 15:35 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

From: John Hurley <john.hurley@netronome.com>

The addition of FLOW_DISSECTOR_KEY_ENC_IP to TC flower means that the ToS
and TTL of the tunnel header can now be matched on.

Extend the NFP tunnel match function to include these new fields.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h    | 7 +++++--
 drivers/net/ethernet/netronome/nfp/flower/match.c   | 9 +++++++++
 drivers/net/ethernet/netronome/nfp/flower/offload.c | 4 +++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 15f1eacd76b6..174acecfba01 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -346,7 +346,7 @@ struct nfp_flower_ipv6 {
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |                         ipv4_addr_dst                         |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                            Reserved                           |
+ * |           Reserved            |      tos      |      ttl      |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |                            Reserved                           |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -356,7 +356,10 @@ struct nfp_flower_ipv6 {
 struct nfp_flower_ipv4_udp_tun {
 	__be32 ip_src;
 	__be32 ip_dst;
-	__be32 reserved[2];
+	__be16 reserved1;
+	u8 tos;
+	u8 ttl;
+	__be32 reserved2;
 	__be32 tun_id;
 };
 
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index 84f7a5dbea9d..b1cbe6927cba 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -270,6 +270,7 @@ nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame,
 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
 	struct flow_dissector_key_ipv4_addrs *tun_ips;
 	struct flow_dissector_key_keyid *vni;
+	struct flow_dissector_key_ip *ip;
 
 	memset(frame, 0, sizeof(struct nfp_flower_ipv4_udp_tun));
 
@@ -293,6 +294,14 @@ nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame,
 		frame->ip_src = tun_ips->src;
 		frame->ip_dst = tun_ips->dst;
 	}
+
+	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ENC_IP)) {
+		ip = skb_flow_dissector_target(flow->dissector,
+					       FLOW_DISSECTOR_KEY_ENC_IP,
+					       target);
+		frame->tos = ip->tos;
+		frame->ttl = ip->ttl;
+	}
 }
 
 int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 6bc8a97f7e03..d2230a0e49b9 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -66,6 +66,7 @@
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \
+	 BIT(FLOW_DISSECTOR_KEY_ENC_IP) | \
 	 BIT(FLOW_DISSECTOR_KEY_MPLS) | \
 	 BIT(FLOW_DISSECTOR_KEY_IP))
 
@@ -74,7 +75,8 @@
 	 BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \
 	 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
-	 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS))
+	 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \
+	 BIT(FLOW_DISSECTOR_KEY_ENC_IP))
 
 #define NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R \
 	(BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 1/6] nfp: flower: set ip tunnel ttl from encap action
From: Simon Horman @ 2018-08-07 15:35 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers
In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com>

From: John Hurley <john.hurley@netronome.com>

The TTL for encapsulating headers in IPv4 UDP tunnels is taken from a
route lookup. Modify this to first check if a user has specified a TTL to
be used in the TC action.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/flower/action.c | 39 ++++++++++++----------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index e56b815a8dc6..a79d078ab3e8 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -238,18 +238,12 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
 	size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun);
 	struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action);
 	u32 tmp_set_ip_tun_type_index = 0;
-	struct flowi4 flow = {};
 	/* Currently support one pre-tunnel so index is always 0. */
 	int pretun_idx = 0;
-	struct rtable *rt;
-	struct net *net;
-	int err;
 
 	if (ip_tun->options_len)
 		return -EOPNOTSUPP;
 
-	net = dev_net(netdev);
-
 	set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL;
 	set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ;
 
@@ -261,19 +255,28 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun,
 	set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index);
 	set_tun->tun_id = ip_tun->key.tun_id;
 
-	/* Do a route lookup to determine ttl - if fails then use default.
-	 * Note that CONFIG_INET is a requirement of CONFIG_NET_SWITCHDEV so
-	 * must be defined here.
-	 */
-	flow.daddr = ip_tun->key.u.ipv4.dst;
-	flow.flowi4_proto = IPPROTO_UDP;
-	rt = ip_route_output_key(net, &flow);
-	err = PTR_ERR_OR_ZERO(rt);
-	if (!err) {
-		set_tun->ttl = ip4_dst_hoplimit(&rt->dst);
-		ip_rt_put(rt);
+	if (ip_tun->key.ttl) {
+		set_tun->ttl = ip_tun->key.ttl;
 	} else {
-		set_tun->ttl = net->ipv4.sysctl_ip_default_ttl;
+		struct net *net = dev_net(netdev);
+		struct flowi4 flow = {};
+		struct rtable *rt;
+		int err;
+
+		/* Do a route lookup to determine ttl - if fails then use
+		 * default. Note that CONFIG_INET is a requirement of
+		 * CONFIG_NET_SWITCHDEV so must be defined here.
+		 */
+		flow.daddr = ip_tun->key.u.ipv4.dst;
+		flow.flowi4_proto = IPPROTO_UDP;
+		rt = ip_route_output_key(net, &flow);
+		err = PTR_ERR_OR_ZERO(rt);
+		if (!err) {
+			set_tun->ttl = ip4_dst_hoplimit(&rt->dst);
+			ip_rt_put(rt);
+		} else {
+			set_tun->ttl = net->ipv4.sysctl_ip_default_ttl;
+		}
 	}
 
 	set_tun->tos = ip_tun->key.tos;
-- 
2.11.0

^ permalink raw reply related

* [PATCH net-next 0/6] nfp: flower: tunnel TTL & TOS, and Geneve options set & match support
From: Simon Horman @ 2018-08-07 15:35 UTC (permalink / raw)
  To: David Miller; +Cc: Jiri Pirko, Cong Wang, Jakub Kicinski, netdev, oss-drivers

Hi Dave,

this series contains updates for the TC Flower classifier
and the offload facility for it in the NFP driver.

* Patches 1 & 2: update the NFP driver to allow offload
  of matching and setting tunnel ToS/TTL of flows using the TC Flower
  classifier and tun_key action

* Patches 3 & 4: enhance the flow dissector and TC Flower classifier
  to allow match on Geneve options

* Patch 5 & 6: update the NFP driver to allow offload of
  matching and setting Geneve options of flows using the TC Flower
  classifier and tun_key action


John Hurley (2):
  nfp: flower: set ip tunnel ttl from encap action
  nfp: flower: allow matching on ipv4 UDP tunnel tos and ttl

Pieter Jansen van Vuuren (3):
  net/sched: allow flower to match tunnel options
  nfp: flower: add geneve option push action offload
  nfp: flower: add geneve option match offload

Simon Horman (1):
  flow_dissector: allow dissection of tunnel options from metadata

 drivers/net/ethernet/netronome/nfp/flower/action.c | 139 ++++++++++--
 drivers/net/ethernet/netronome/nfp/flower/cmsg.h   |  33 ++-
 drivers/net/ethernet/netronome/nfp/flower/main.h   |   1 +
 drivers/net/ethernet/netronome/nfp/flower/match.c  |  34 +++
 .../net/ethernet/netronome/nfp/flower/offload.c    |  42 +++-
 include/net/flow_dissector.h                       |  17 ++
 include/uapi/linux/pkt_cls.h                       |  26 +++
 net/core/flow_dissector.c                          |  19 +-
 net/sched/cls_flower.c                             | 244 ++++++++++++++++++++-
 9 files changed, 525 insertions(+), 30 deletions(-)

-- 
2.11.0

^ permalink raw reply

* Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
From: Jose Abreu @ 2018-08-07 15:29 UTC (permalink / raw)
  To: Florian Fainelli, Jose Abreu, netdev
  Cc: David S. Miller, Joao Pinto, Giuseppe Cavallaro, Alexandre Torgue,
	Andrew Lunn
In-Reply-To: <3a097ddf-cff1-460f-2c63-7347274c1ee5@synopsys.com>

On 07-08-2018 14:35, Jose Abreu wrote:
> Hi Florian,
>
> On 06-08-2018 16:25, Florian Fainelli wrote:
>> On August 6, 2018 12:59:54 AM PDT, Jose Abreu <Jose.Abreu@synopsys.com> wrote:
>>> On 03-08-2018 20:06, Florian Fainelli wrote:
>>>> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>>>>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>>>>
>>>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>>>>> Cc: David S. Miller <davem@davemloft.net>
>>>>> Cc: Joao Pinto <jpinto@synopsys.com>
>>>>> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>>>>> Cc: Alexandre Torgue <alexandre.torgue@st.com>
>>>>> Cc: Andrew Lunn <andrew@lunn.ch>
>>>>> ---
>>>>> +satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int
>>> phyaddr,
>>>>> +				    int phyreg, u32 *hw_addr)
>>>>> +{
>>>>> +	unsigned int mii_data = priv->hw->mii.data;
>>>>> +	u32 tmp;
>>>>> +
>>>>> +	/* HW does not support C22 addr >= 4 */
>>>>> +	if (phyaddr >= 4)
>>>>> +		return -ENODEV;
>>>> It would be nice if this could be moved at probe time so you don't
>>> have
>>>> to wait until you connect to the PHY, read its PHY OUI and find out
>>> it
>>>> has a MDIO address >= 4. Not a blocker, but something that could be
>>>> improved further on.
>>>>
>>>> In premise you could even scan the MDIO bus' device tree node, and
>>> find
>>>> that out ahead of time.
>>> Oh, but I use phylib ... I only provide the read/write callbacks
>>> so I think we should avoid duplicating the code that's already in
>>> the phylib ... No?
>> You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
> Sorry but I dont' think thats the best solution because
> of_mdiobus_register() already scans the bus. 

My mistake. Its stmmac thats scanning the bus. See this:

359         for (addr = 0; addr < PHY_MAX_ADDR; addr++)
{                          
360                 struct phy_device *phydev =
mdiobus_get_phy(new_bus, addr);    
361                                                                                

362                 if
(!phydev)                                                   
363                        
continue;                                              

So, its just cycling through all possible phys (0..31) ... Do you
think it would be okay if I just limit the cycle max to 4 for
this xgmac2 for now ? I would maintain the if in  the
stmmac_xgmac2_c22_format though, as safe-guard.

Thanks and Best Regards,
Jose Miguel Abreu

> Duplicating this
> should be avoided, no?
>
> Note all of this is probably never needed because stmmac just
> picks the first phy it finds, if phy_addr is not specified ...
>
>>>>> +	/* Wait until any existing MII operation is complete */
>>>>> +	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>>>>> +			       !(tmp & MII_XGMAC_BUSY), 100, 10000))
>>>>> +		return -EBUSY;
>>>>> +
>>>>> +	/* Set port as Clause 22 */
>>>>> +	tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>>>>> +	tmp |= BIT(phyaddr);
>>>> Since the registers are being Read/Modify/Write here, don't you need
>>> to
>>>> clear the previous address bits as well?
>>>>
>>>> You probably did not encounter any problems in your testing if you
>>> had
>>>> only one PHY on the MDIO bus, but this is not something that is
>>>> necessarily true, e.g: if you have an Ethernet switch, several MDIO
>>> bus
>>>> addresses are going to be responding.
>>>>
>>>> Your MDIO bus implementation must be able to support one transaction
>>>> with one PHY address and the next transaction with another PHY
>>> address ,
>>>> etc...
>>>>
>>>> That is something that should be easy to fix and be resubmitted as
>>> part
>>>> of v4.
>>> I'm not following you here... I only set/unset the bit for the
>>> corresponding phyaddr that phylib wants to read/write. Why would
>>> I clear the remaining addresses?
>> Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
> I can't test C45 right now but I will in a near future. In that
> case then we will need to support C22 and C45 so I may want to
> only set one bit for a specific phy that only supports c22.
>
> Thanks and Best Regards,
> Jose Miguel Abreu
>

^ permalink raw reply

* Re: [PATCH net-next] ieee802154: hwsim: fix rcu address annotation
From: Stefan Schmidt @ 2018-08-07 15:28 UTC (permalink / raw)
  To: Alexander Aring, netdev; +Cc: linux-wpan, kernel
In-Reply-To: <20180807143444.32224-1-aring@mojatatu.com>

Hello Dave.

On 08/07/2018 04:34 PM, Alexander Aring wrote:
> This patch fixes the following sparse warning about mismatch rcu
> attribute for address space annotation:
> 
> ...
> error: incompatible types in comparison expression (different modifiers)
> error: incompatible types in comparison expression (different address spaces)
> ...
> 
> Some __rcu annotation was at non-pointers list head structures and one was
> missing in edge information which is used by rcu_assign_pointer() to
> update edge setting information.
> 
> Cc: Stefan Schmidt <stefan@datenfreihafen.org>
> Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
> Signed-off-by: Alexander Aring <aring@mojatatu.com>
> ---
> Hopefully I did it right now. Sorry again.
> 
>  drivers/net/ieee802154/mac802154_hwsim.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
> index 1982308b9b1c..f4e92054f7df 100644
> --- a/drivers/net/ieee802154/mac802154_hwsim.c
> +++ b/drivers/net/ieee802154/mac802154_hwsim.c
> @@ -36,7 +36,7 @@ MODULE_LICENSE("GPL");
>  static LIST_HEAD(hwsim_phys);
>  static DEFINE_MUTEX(hwsim_phys_lock);
>  
> -static __rcu LIST_HEAD(hwsim_ifup_phys);
> +static LIST_HEAD(hwsim_ifup_phys);
>  
>  static struct platform_device *mac802154hwsim_dev;
>  
> @@ -68,7 +68,7 @@ struct hwsim_edge_info {
>  
>  struct hwsim_edge {
>  	struct hwsim_phy *endpoint;
> -	struct hwsim_edge_info *info;
> +	struct hwsim_edge_info __rcu *info;
>  
>  	struct list_head list;
>  	struct rcu_head rcu;
> @@ -81,7 +81,7 @@ struct hwsim_phy {
>  	struct hwsim_pib __rcu *pib;
>  
>  	bool suspended;
> -	struct list_head __rcu edges;
> +	struct list_head edges;
>  
>  	struct list_head list;
>  	struct list_head list_ifup;
> 


Could you apply this patch directly to net-next?
It fixes an issue introduced with my pull request from two days ago. I
have nothing else to submit so I would appreciate if you could apply it
directly.

Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>

regards
Stefan Schmidt

^ permalink raw reply

* RE: [PATCH RFC net-next 1/1] net/tls: Combined memory allocation for decryption request
From: Vakul Garg @ 2018-08-07 15:24 UTC (permalink / raw)
  To: Dave Watson
  Cc: netdev@vger.kernel.org, borisp@mellanox.com, aviadye@mellanox.com,
	davem@davemloft.net
In-Reply-To: <20180807145618.GA91350@mengjuew-mbp.dhcp.thefacebook.com>



> -----Original Message-----
> From: Dave Watson [mailto:davejwatson@fb.com]
> Sent: Tuesday, August 7, 2018 8:26 PM
> To: Vakul Garg <vakul.garg@nxp.com>
> Cc: netdev@vger.kernel.org; borisp@mellanox.com;
> aviadye@mellanox.com; davem@davemloft.net
> Subject: Re: [PATCH RFC net-next 1/1] net/tls: Combined memory allocation
> for decryption request
> 
> Hi Vakul,
> 
> Only minor comments, mostly looks good to me.  Thanks
> 
> > +/* This function decrypts the input skb into either out_iov or in
> > +out_sg
> > + * or in skb buffers itself. The input parameter 'zc' indicates if
> > + * zero-copy mode needs to be tried or not. With zero-copy mode,
> > +either
> > + * out_iov or out_sg must be non-NULL. In case both out_iov and
> > +out_sg are
> > + * NULL, then the decryption happens inside skb buffers itself, i.e.
> > + * zero-copy gets disabled and 'zc' is updated.
> > + */
> > +
> > +static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
> > +			    struct iov_iter *out_iov,
> > +			    struct scatterlist *out_sg,
> > +			    int *chunk, bool *zc)
> > +{
> > +	struct tls_context *tls_ctx = tls_get_ctx(sk);
> > +	struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
> > +	struct strp_msg *rxm = strp_msg(skb);
> > +	int n_sgin, n_sgout, nsg, mem_size, aead_size, err, pages = 0;
> > +	struct aead_request *aead_req;
> > +	struct sk_buff *unused;
> > +	u8 *aad, *iv, *mem = NULL;
> > +	struct scatterlist *sgin = NULL;
> > +	struct scatterlist *sgout = NULL;
> > +	const int data_len = rxm->full_len - tls_ctx->rx.overhead_size;
> > +
> > +	if (*zc && (out_iov || out_sg)) {
> > +		if (out_iov)
> > +			n_sgout = iov_iter_npages(out_iov, INT_MAX) + 1;
> > +		else if (out_sg)
> > +			n_sgout = sg_nents(out_sg);
> > +		else
> > +			goto no_zerocopy;
> 
> Is the last else necessary?  It looks like the if already checks for out_iov ||
> out_sg.
> 
You are right. I can remove 'else. 'else if' can also be replaced with 'else'.
I would submit v2.


> >  		struct scatterlist *sgout)
> >  {
> > -	struct tls_context *tls_ctx = tls_get_ctx(sk);
> > -	struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
> > -	char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + MAX_IV_SIZE];
> > -	struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
> > -	struct scatterlist *sgin = &sgin_arr[0];
> > -	struct strp_msg *rxm = strp_msg(skb);
> > -	int ret, nsg;
> > -	struct sk_buff *unused;
> > -
> > -	ret = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
> > -			    iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
> > -			    tls_ctx->rx.iv_size);
> > -	if (ret < 0)
> > -		return ret;
> > -
> > -	memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
> > -	if (!sgout) {
> > -		nsg = skb_cow_data(skb, 0, &unused);
> > -	} else {
> > -		nsg = skb_nsg(skb,
> > -			      rxm->offset + tls_ctx->rx.prepend_size,
> > -			      rxm->full_len - tls_ctx->rx.prepend_size);
> > -		if (nsg <= 0)
> > -			return nsg;
> > -	}
> > -
> > -	// We need one extra for ctx->rx_aad_ciphertext
> > -	nsg++;
> > -
> > -	if (nsg > ARRAY_SIZE(sgin_arr))
> > -		sgin = kmalloc_array(nsg, sizeof(*sgin), sk->sk_allocation);
> > -
> > -	if (!sgout)
> > -		sgout = sgin;
> > -
> > -	sg_init_table(sgin, nsg);
> > -	sg_set_buf(&sgin[0], ctx->rx_aad_ciphertext, TLS_AAD_SPACE_SIZE);
> > -
> > -	nsg = skb_to_sgvec(skb, &sgin[1],
> > -			   rxm->offset + tls_ctx->rx.prepend_size,
> > -			   rxm->full_len - tls_ctx->rx.prepend_size);
> > -	if (nsg < 0) {
> > -		ret = nsg;
> > -		goto out;
> > -	}
> > -
> > -	tls_make_aad(ctx->rx_aad_ciphertext,
> > -		     rxm->full_len - tls_ctx->rx.overhead_size,
> > -		     tls_ctx->rx.rec_seq,
> > -		     tls_ctx->rx.rec_seq_size,
> > -		     ctx->control);
> > -
> > -	ret = tls_do_decryption(sk, sgin, sgout, iv,
> > -				rxm->full_len - tls_ctx->rx.overhead_size,
> > -				skb, sk->sk_allocation);
> > -
> > -out:
> > -	if (sgin != &sgin_arr[0])
> > -		kfree(sgin);
> > +	bool zc = true;
> > +	int chunk;
> >
> > -	return ret;
> > +	return decrypt_internal(sk, skb, NULL, sgout, &chunk, &zc);
> >  }
> 
> Can we merge this function to callsites?  It's pretty useless now.

I retained decrypt_skb() in its existing prototype to keep the caller
in tls_device.c unmodified. It seemed simpler that way to me
from code readability perspective in tls_device.c.

Let me know if this would prevent getting your ack for the patch :).

> >
> >  static bool tls_sw_advance_skb(struct sock *sk, struct sk_buff *skb,
> > @@ -899,43 +964,17 @@ int tls_sw_recvmsg(struct sock *sk,
> >  		}
> >
> >  		if (!ctx->decrypted) {
> > -			int page_count;
> > -			int to_copy;

^ permalink raw reply

* Re: [PATCH RFC net-next 1/1] net/tls: Combined memory allocation for decryption request
From: Dave Watson @ 2018-08-07 14:56 UTC (permalink / raw)
  To: Vakul Garg; +Cc: netdev, borisp, aviadye, davem
In-Reply-To: <20180806163810.30880-2-vakul.garg@nxp.com>

Hi Vakul,

Only minor comments, mostly looks good to me.  Thanks

> +/* This function decrypts the input skb into either out_iov or in out_sg
> + * or in skb buffers itself. The input parameter 'zc' indicates if
> + * zero-copy mode needs to be tried or not. With zero-copy mode, either
> + * out_iov or out_sg must be non-NULL. In case both out_iov and out_sg are
> + * NULL, then the decryption happens inside skb buffers itself, i.e.
> + * zero-copy gets disabled and 'zc' is updated.
> + */
> +
> +static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
> +			    struct iov_iter *out_iov,
> +			    struct scatterlist *out_sg,
> +			    int *chunk, bool *zc)
> +{
> +	struct tls_context *tls_ctx = tls_get_ctx(sk);
> +	struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
> +	struct strp_msg *rxm = strp_msg(skb);
> +	int n_sgin, n_sgout, nsg, mem_size, aead_size, err, pages = 0;
> +	struct aead_request *aead_req;
> +	struct sk_buff *unused;
> +	u8 *aad, *iv, *mem = NULL;
> +	struct scatterlist *sgin = NULL;
> +	struct scatterlist *sgout = NULL;
> +	const int data_len = rxm->full_len - tls_ctx->rx.overhead_size;
> +
> +	if (*zc && (out_iov || out_sg)) {
> +		if (out_iov)
> +			n_sgout = iov_iter_npages(out_iov, INT_MAX) + 1;
> +		else if (out_sg)
> +			n_sgout = sg_nents(out_sg);
> +		else
> +			goto no_zerocopy;

Is the last else necessary?  It looks like the if already checks for
out_iov || out_sg.

>  		struct scatterlist *sgout)
>  {
> -	struct tls_context *tls_ctx = tls_get_ctx(sk);
> -	struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
> -	char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + MAX_IV_SIZE];
> -	struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
> -	struct scatterlist *sgin = &sgin_arr[0];
> -	struct strp_msg *rxm = strp_msg(skb);
> -	int ret, nsg;
> -	struct sk_buff *unused;
> -
> -	ret = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
> -			    iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
> -			    tls_ctx->rx.iv_size);
> -	if (ret < 0)
> -		return ret;
> -
> -	memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
> -	if (!sgout) {
> -		nsg = skb_cow_data(skb, 0, &unused);
> -	} else {
> -		nsg = skb_nsg(skb,
> -			      rxm->offset + tls_ctx->rx.prepend_size,
> -			      rxm->full_len - tls_ctx->rx.prepend_size);
> -		if (nsg <= 0)
> -			return nsg;
> -	}
> -
> -	// We need one extra for ctx->rx_aad_ciphertext
> -	nsg++;
> -
> -	if (nsg > ARRAY_SIZE(sgin_arr))
> -		sgin = kmalloc_array(nsg, sizeof(*sgin), sk->sk_allocation);
> -
> -	if (!sgout)
> -		sgout = sgin;
> -
> -	sg_init_table(sgin, nsg);
> -	sg_set_buf(&sgin[0], ctx->rx_aad_ciphertext, TLS_AAD_SPACE_SIZE);
> -
> -	nsg = skb_to_sgvec(skb, &sgin[1],
> -			   rxm->offset + tls_ctx->rx.prepend_size,
> -			   rxm->full_len - tls_ctx->rx.prepend_size);
> -	if (nsg < 0) {
> -		ret = nsg;
> -		goto out;
> -	}
> -
> -	tls_make_aad(ctx->rx_aad_ciphertext,
> -		     rxm->full_len - tls_ctx->rx.overhead_size,
> -		     tls_ctx->rx.rec_seq,
> -		     tls_ctx->rx.rec_seq_size,
> -		     ctx->control);
> -
> -	ret = tls_do_decryption(sk, sgin, sgout, iv,
> -				rxm->full_len - tls_ctx->rx.overhead_size,
> -				skb, sk->sk_allocation);
> -
> -out:
> -	if (sgin != &sgin_arr[0])
> -		kfree(sgin);
> +	bool zc = true;
> +	int chunk;
>  
> -	return ret;
> +	return decrypt_internal(sk, skb, NULL, sgout, &chunk, &zc);
>  }

Can we merge this function to callsites?  It's pretty useless now.

>  
>  static bool tls_sw_advance_skb(struct sock *sk, struct sk_buff *skb,
> @@ -899,43 +964,17 @@ int tls_sw_recvmsg(struct sock *sk,
>  		}
>  
>  		if (!ctx->decrypted) {
> -			int page_count;
> -			int to_copy;

^ permalink raw reply

* Re: [PATCH net-next] RDS: IB: fix 'passing zero to ERR_PTR()' warning
From: Santosh Shilimkar @ 2018-08-07 17:09 UTC (permalink / raw)
  To: YueHaibing, davem; +Cc: linux-kernel, netdev, linux-rdma, rds-devel
In-Reply-To: <20180807113416.12680-1-yuehaibing@huawei.com>

On 8/7/2018 4:34 AM, YueHaibing wrote:
> Fix a static code checker warning:
>   net/rds/ib_frmr.c:82 rds_ib_alloc_frmr() warn: passing zero to 'ERR_PTR'
> 
> The error path for ib_alloc_mr failure should set err to PTR_ERR.
> 
> Fixes: 1659185fb4d0 ("RDS: IB: Support Fastreg MR (FRMR) memory registration mode")
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
Looks good. Thanks !!

Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>

^ permalink raw reply

* Re: [PATCH 3/3] net: phy: Add support for Broadcom Omega internal Combo GPHY
From: Florian Fainelli @ 2018-08-07 17:06 UTC (permalink / raw)
  To: Arun Parameswaran, David S. Miller, Florian Fainelli, Andrew Lunn,
	Vivien Didelot, Rob Herring, Mark Rutland
  Cc: netdev, devicetree, linux-kernel, bcm-kernel-feedback-list
In-Reply-To: <1533661364-15381-4-git-send-email-arun.parameswaran@broadcom.com>

On 08/07/2018 10:02 AM, Arun Parameswaran wrote:
> Add support for the Broadcom Omega SoC internal Combo Ethernet
> GPHY to the bcm7xxx phy driver.
> 
> Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH 2/3] net: dsa: b53: Add support for Broadcom Omega SoC internal switch
From: Florian Fainelli @ 2018-08-07 17:06 UTC (permalink / raw)
  To: Arun Parameswaran, David S. Miller, Florian Fainelli, Andrew Lunn,
	Vivien Didelot, Rob Herring, Mark Rutland
  Cc: netdev, devicetree, linux-kernel, bcm-kernel-feedback-list
In-Reply-To: <1533661364-15381-3-git-send-email-arun.parameswaran@broadcom.com>

On 08/07/2018 10:02 AM, Arun Parameswaran wrote:
> Add support for the Broadcom Omega SoC internal ethernet switch
> to the b53 srab driver in the DSA framework.
> 
> Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH 1/3] dt-bindings: net: dsa: Add compatibility strings for Broadcom Omega
From: Florian Fainelli @ 2018-08-07 17:06 UTC (permalink / raw)
  To: Arun Parameswaran, David S. Miller, Florian Fainelli, Andrew Lunn,
	Vivien Didelot, Rob Herring, Mark Rutland
  Cc: netdev, devicetree, linux-kernel, bcm-kernel-feedback-list
In-Reply-To: <1533661364-15381-2-git-send-email-arun.parameswaran@broadcom.com>

On 08/07/2018 10:02 AM, Arun Parameswaran wrote:
> Add compatibility strings for the internal switch in the Broadcom
> Omega SoC family (BCM5831X/BCM1140X) to B53.
> 
> Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ 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