* [PATCH v2 net-next 0/3] docs: net: Convert netdev-FAQ to RST
From: Tobin C. Harding @ 2018-07-26 5:00 UTC (permalink / raw)
To: David S. Miller
Cc: Tobin C. Harding, Jonathan Corbet, Edward Cree,
Alexei Starovoitov, Daniel Borkmann, linux-doc, netdev,
linux-kernel
Hi Dave,
Jon answered all the tree questions on v1 so if you will please take
this through your tree that would be awesome.
v2:
- Fix typo 'canonical_path_format' (thanks Edward)
- Add patch fixing references netdev-FAQ
thanks,
Tobin.
Tobin C. Harding (3):
docs: Add rest label the_canonical_patch_format
docs: net: Convert netdev-FAQ to restructured text
docs: Update references to netdev-FAQ
Documentation/bpf/bpf_devel_QA.rst | 21 +-
Documentation/networking/00-INDEX | 2 -
Documentation/networking/index.rst | 1 +
Documentation/networking/netdev-FAQ.rst | 259 ++++++++++++++++++
Documentation/networking/netdev-FAQ.txt | 244 -----------------
Documentation/process/stable-kernel-rules.rst | 2 +-
Documentation/process/submitting-patches.rst | 1 +
7 files changed, 271 insertions(+), 259 deletions(-)
create mode 100644 Documentation/networking/netdev-FAQ.rst
delete mode 100644 Documentation/networking/netdev-FAQ.txt
--
2.17.1
^ permalink raw reply
* Re: [PATCH] net/rds/Kconfig: RDS should depend on IPV6
From: Ka-Cheong Poon @ 2018-07-26 4:56 UTC (permalink / raw)
To: Santosh Shilimkar, Anders Roxell
Cc: davem, netdev, linux-rdma, rds-devel, linux-kernel
In-Reply-To: <cefa5c0b-7935-a6b5-1796-1d5a3da5dd87@oracle.com>
On 07/26/2018 06:36 AM, Santosh Shilimkar wrote:
> On 7/25/2018 3:20 PM, Anders Roxell wrote:
>> Build error, implicit declaration of function __inet6_ehashfn shows up
>> When RDS is enabled but not IPV6.
>> net/rds/connection.c: In function ‘rds_conn_bucket’:
>> net/rds/connection.c:67:9: error: implicit declaration of function
>> ‘__inet6_ehashfn’; did you mean ‘__inet_ehashfn’?
>> [-Werror=implicit-function-declaration]
>> hash = __inet6_ehashfn(lhash, 0, fhash, 0, rds_hash_secret);
>> ^~~~~~~~~~~~~~~
>> __inet_ehashfn
>>
>> Current code adds IPV6 as a depends on in config RDS.
>>
>> Fixes: eee2fa6ab322 ("rds: Changing IP address internal representation
>> to struct in6_addr")
>> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
>> ---
>> net/rds/Kconfig | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/rds/Kconfig b/net/rds/Kconfig
>> index 41f75563b54b..607128f10bcd 100644
>> --- a/net/rds/Kconfig
>> +++ b/net/rds/Kconfig
>> @@ -1,7 +1,7 @@
>> config RDS
>> tristate "The RDS Protocol"
>> - depends on INET
>> + depends on INET && CONFIG_IPV6
> This should build without CONFIG_IPV6 too.
>
> Hi Ka-cheong,
> Can you please loot at it ? I know you modified
> lookup function to take always in6_addr now, but
> probably hashing with '__inet_ehashfn' should
> work too for non IPV6 address(s).
I guess for now, let's add this dependency first. I
will do a follow up patch to remove this dependency.
Thanks.
--
K. Poon
ka-cheong.poon@oracle.com
^ permalink raw reply
* Re: [PATCH net-next] tcp: add SNMP counter for the number of packets pruned from ofo queue
From: Yafang Shao @ 2018-07-26 4:42 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, Eric Dumazet, netdev, LKML
In-Reply-To: <a78450d6-698a-e819-89f4-ebbe03fdf971@gmail.com>
On Thu, Jul 26, 2018 at 12:36 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>
> On 07/25/2018 09:31 PM, Yafang Shao wrote:
>> On Thu, Jul 26, 2018 at 12:06 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>>
>>>
>>> On 07/25/2018 06:42 PM, Yafang Shao wrote:
>>>
>>>>
>>>> Hi Eric,
>>>>
>>>> LINUX_MIB_TCPOFOQUEUE, LINUX_MIB_TCPOFODROP and LINUX_MIB_TCPOFOMERGE
>>>> are all for the number of SKBs, but only LINUX_MIB_OFOPRUNED is for
>>>> the event, that could lead misunderstading.
>>>> So I think introducing a counter for the number of SKB pruned could be
>>>> better, that could help us to track the whole behavior of ofo queue.
>>>> That is why I submit this patch.
>>>
>>> Sure, and I said your patch had issues.
>>> You mixed 'packets' and 'skbs' but apparently you do not get my point.
>>>
>>
>> I had noticed that I made this mistake.
>>
>>> I would rather not add another SNMP counter, and refine the current one,
>>> trying to track something more meaningful.
>>>
>>> The notion of 'skb' is internal to the kernel, and can not be mapped easily
>>> to 'number of network segments' which probably is more useful for the user.
>>>
>>> I will send this instead :
>>>
>>> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
>>> index d51fa358b2b196d0f9c258b24354813f2128a675..141a062abd0660c8f6d049de1dc7c7ecf7a7230d 100644
>>> --- a/net/ipv4/tcp_input.c
>>> +++ b/net/ipv4/tcp_input.c
>>> @@ -5001,18 +5001,19 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
>>> {
>>> struct tcp_sock *tp = tcp_sk(sk);
>>> struct rb_node *node, *prev;
>>> + unsigned int segs = 0;
>>> int goal;
>>>
>>> if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
>>> return false;
>>>
>>> - NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED);
>>> goal = sk->sk_rcvbuf >> 3;
>>> node = &tp->ooo_last_skb->rbnode;
>>> do {
>>> prev = rb_prev(node);
>>> rb_erase(node, &tp->out_of_order_queue);
>>> goal -= rb_to_skb(node)->truesize;
>>> + segs += max_t(u16, 1, skb_shinfo(rb_to_skb(node))->gso_segs);
>>> tcp_drop(sk, rb_to_skb(node));
>>> if (!prev || goal <= 0) {
>>> sk_mem_reclaim(sk);
>>> @@ -5023,6 +5024,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
>>> }
>>> node = prev;
>>> } while (node);
>>> + NET_ADD_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED, segs);
>>> tp->ooo_last_skb = rb_to_skb(prev);
>>>
>>> /* Reset SACK state. A conforming SACK implementation will
>>>
>>
>> You patch will make it more meaningful.
>> How about the other ones?
>
> Same thing really.
>
> Note that tcp_collapse() does not currently propagate skb_shinfo(skb)->gso_segs
> when rebuilding the skbs, so this will need a fix.
>
Got it.
Thank you very much for your comment.
Thanks
Yafang
^ permalink raw reply
* Re: [PATCH net-next] tcp: add SNMP counter for the number of packets pruned from ofo queue
From: Eric Dumazet @ 2018-07-26 4:36 UTC (permalink / raw)
To: Yafang Shao; +Cc: David Miller, Eric Dumazet, netdev, LKML
In-Reply-To: <CALOAHbBKSPQdo9bA5VFLvR448Ag30nE2Td1f6204MPZ7Nfy7ag@mail.gmail.com>
On 07/25/2018 09:31 PM, Yafang Shao wrote:
> On Thu, Jul 26, 2018 at 12:06 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>
>>
>> On 07/25/2018 06:42 PM, Yafang Shao wrote:
>>
>>>
>>> Hi Eric,
>>>
>>> LINUX_MIB_TCPOFOQUEUE, LINUX_MIB_TCPOFODROP and LINUX_MIB_TCPOFOMERGE
>>> are all for the number of SKBs, but only LINUX_MIB_OFOPRUNED is for
>>> the event, that could lead misunderstading.
>>> So I think introducing a counter for the number of SKB pruned could be
>>> better, that could help us to track the whole behavior of ofo queue.
>>> That is why I submit this patch.
>>
>> Sure, and I said your patch had issues.
>> You mixed 'packets' and 'skbs' but apparently you do not get my point.
>>
>
> I had noticed that I made this mistake.
>
>> I would rather not add another SNMP counter, and refine the current one,
>> trying to track something more meaningful.
>>
>> The notion of 'skb' is internal to the kernel, and can not be mapped easily
>> to 'number of network segments' which probably is more useful for the user.
>>
>> I will send this instead :
>>
>> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
>> index d51fa358b2b196d0f9c258b24354813f2128a675..141a062abd0660c8f6d049de1dc7c7ecf7a7230d 100644
>> --- a/net/ipv4/tcp_input.c
>> +++ b/net/ipv4/tcp_input.c
>> @@ -5001,18 +5001,19 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
>> {
>> struct tcp_sock *tp = tcp_sk(sk);
>> struct rb_node *node, *prev;
>> + unsigned int segs = 0;
>> int goal;
>>
>> if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
>> return false;
>>
>> - NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED);
>> goal = sk->sk_rcvbuf >> 3;
>> node = &tp->ooo_last_skb->rbnode;
>> do {
>> prev = rb_prev(node);
>> rb_erase(node, &tp->out_of_order_queue);
>> goal -= rb_to_skb(node)->truesize;
>> + segs += max_t(u16, 1, skb_shinfo(rb_to_skb(node))->gso_segs);
>> tcp_drop(sk, rb_to_skb(node));
>> if (!prev || goal <= 0) {
>> sk_mem_reclaim(sk);
>> @@ -5023,6 +5024,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
>> }
>> node = prev;
>> } while (node);
>> + NET_ADD_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED, segs);
>> tp->ooo_last_skb = rb_to_skb(prev);
>>
>> /* Reset SACK state. A conforming SACK implementation will
>>
>
> You patch will make it more meaningful.
> How about the other ones?
Same thing really.
Note that tcp_collapse() does not currently propagate skb_shinfo(skb)->gso_segs
when rebuilding the skbs, so this will need a fix.
^ permalink raw reply
* Re: [PATCH net-next] tcp: add SNMP counter for the number of packets pruned from ofo queue
From: Yafang Shao @ 2018-07-26 4:31 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, Eric Dumazet, netdev, LKML
In-Reply-To: <70428ad9-5d59-faed-4384-36190939a19d@gmail.com>
On Thu, Jul 26, 2018 at 12:06 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>
> On 07/25/2018 06:42 PM, Yafang Shao wrote:
>
>>
>> Hi Eric,
>>
>> LINUX_MIB_TCPOFOQUEUE, LINUX_MIB_TCPOFODROP and LINUX_MIB_TCPOFOMERGE
>> are all for the number of SKBs, but only LINUX_MIB_OFOPRUNED is for
>> the event, that could lead misunderstading.
>> So I think introducing a counter for the number of SKB pruned could be
>> better, that could help us to track the whole behavior of ofo queue.
>> That is why I submit this patch.
>
> Sure, and I said your patch had issues.
> You mixed 'packets' and 'skbs' but apparently you do not get my point.
>
I had noticed that I made this mistake.
> I would rather not add another SNMP counter, and refine the current one,
> trying to track something more meaningful.
>
> The notion of 'skb' is internal to the kernel, and can not be mapped easily
> to 'number of network segments' which probably is more useful for the user.
>
> I will send this instead :
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index d51fa358b2b196d0f9c258b24354813f2128a675..141a062abd0660c8f6d049de1dc7c7ecf7a7230d 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -5001,18 +5001,19 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
> {
> struct tcp_sock *tp = tcp_sk(sk);
> struct rb_node *node, *prev;
> + unsigned int segs = 0;
> int goal;
>
> if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
> return false;
>
> - NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED);
> goal = sk->sk_rcvbuf >> 3;
> node = &tp->ooo_last_skb->rbnode;
> do {
> prev = rb_prev(node);
> rb_erase(node, &tp->out_of_order_queue);
> goal -= rb_to_skb(node)->truesize;
> + segs += max_t(u16, 1, skb_shinfo(rb_to_skb(node))->gso_segs);
> tcp_drop(sk, rb_to_skb(node));
> if (!prev || goal <= 0) {
> sk_mem_reclaim(sk);
> @@ -5023,6 +5024,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
> }
> node = prev;
> } while (node);
> + NET_ADD_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED, segs);
> tp->ooo_last_skb = rb_to_skb(prev);
>
> /* Reset SACK state. A conforming SACK implementation will
>
You patch will make it more meaningful.
How about the other ones?
I think changing all of them from the number of SKBs to the number of
network segments would be better.
Thanks
Yafang
^ permalink raw reply
* Re: [PATCH 06/18] netlink: Do not subscribe to non-existent groups
From: David Miller @ 2018-07-26 4:22 UTC (permalink / raw)
To: dima; +Cc: linux-kernel, herbert, steffen.klassert, 0x7f454c46, netdev
In-Reply-To: <20180726023144.31066-7-dima@arista.com>
From: Dmitry Safonov <dima@arista.com>
Date: Thu, 26 Jul 2018 03:31:32 +0100
> 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>
This really has nothing to do with adding a compat layer for xfrm,
and is a bug fix that should be submitted separately in it's own
right.
^ permalink raw reply
* Re: [PATCH net-next] amd-xgbe: use dma_mapping_error to check map errors
From: David Miller @ 2018-07-26 4:17 UTC (permalink / raw)
To: yuehaibing; +Cc: thomas.lendacky, linux-kernel, netdev
In-Reply-To: <20180726015127.8740-1-yuehaibing@huawei.com>
From: YueHaibing <yuehaibing@huawei.com>
Date: Thu, 26 Jul 2018 09:51:27 +0800
> The dma_mapping_error() returns true or false, but we want
> to return -ENOMEM if there was an error.
>
> Fixes: 174fd2597b0b ("amd-xgbe: Implement split header receive support")
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Applied, thank you.
^ permalink raw reply
* [PATCH bpf-next 6/6] nfp: bpf: improve map offload info messages
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
FW can put constraints on map element size to maximize resource
use and efficiency. When user attempts offload of a map which
does not fit into those constraints an informational message is
printed to kernel logs to inform user about the reason offload
failed. Map offload does not have access to any advanced error
reporting like verifier log or extack. There is also currently
no way for us to nicely expose the FW capabilities to user
space. Given all those constraints we should make sure log
messages are as informative as possible. Improve them.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
.../net/ethernet/netronome/nfp/bpf/offload.c | 20 +++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index b1fbb3babc7f..1ccd6371a15b 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -380,11 +380,23 @@ nfp_bpf_map_alloc(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
bpf->maps.max_elems - bpf->map_elems_in_use);
return -ENOMEM;
}
- if (offmap->map.key_size > bpf->maps.max_key_sz ||
- offmap->map.value_size > bpf->maps.max_val_sz ||
- round_up(offmap->map.key_size, 8) +
+
+ if (round_up(offmap->map.key_size, 8) +
round_up(offmap->map.value_size, 8) > bpf->maps.max_elem_sz) {
- pr_info("elements don't fit in device constraints\n");
+ pr_info("map elements too large: %u, FW max element size (key+value): %u\n",
+ round_up(offmap->map.key_size, 8) +
+ round_up(offmap->map.value_size, 8),
+ bpf->maps.max_elem_sz);
+ return -ENOMEM;
+ }
+ if (offmap->map.key_size > bpf->maps.max_key_sz) {
+ pr_info("map key size %u, FW max is %u\n",
+ offmap->map.key_size, bpf->maps.max_key_sz);
+ return -ENOMEM;
+ }
+ if (offmap->map.value_size > bpf->maps.max_val_sz) {
+ pr_info("map value size %u, FW max is %u\n",
+ offmap->map.value_size, bpf->maps.max_val_sz);
return -ENOMEM;
}
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 5/6] nfp: bpf: remember maps by ID
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski, Kees Cook
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
Record perf maps by map ID, not raw kernel pointer. This helps
with debug messages, because printing pointers to logs is frowned
upon, and makes debug easier for the users, as map ID is something
they should be more familiar with. Note that perf maps are offload
neutral, therefore IDs won't be orphaned.
While at it use a rate limited print helper for the error message.
Reported-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
CC: Kees Cook <keescook@chromium.org>
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 2 --
drivers/net/ethernet/netronome/nfp/bpf/jit.c | 12 ++++++----
drivers/net/ethernet/netronome/nfp/bpf/main.c | 4 ++--
drivers/net/ethernet/netronome/nfp/bpf/main.h | 3 +++
.../net/ethernet/netronome/nfp/bpf/offload.c | 22 +++++++++++--------
5 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
index 1946291bf4fd..2572a4b91c7c 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
@@ -43,8 +43,6 @@
#include "fw.h"
#include "main.h"
-#define cmsg_warn(bpf, msg...) nn_dp_warn(&(bpf)->app->ctrl->dp, msg)
-
#define NFP_BPF_TAG_ALLOC_SPAN (U16_MAX / 4)
static bool nfp_bpf_all_tags_busy(struct nfp_app_bpf *bpf)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 1d9e36835404..3c22d27de9da 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -3883,6 +3883,7 @@ static int nfp_bpf_replace_map_ptrs(struct nfp_prog *nfp_prog)
struct nfp_insn_meta *meta1, *meta2;
struct nfp_bpf_map *nfp_map;
struct bpf_map *map;
+ u32 id;
nfp_for_each_insn_walk2(nfp_prog, meta1, meta2) {
if (meta1->skip || meta2->skip)
@@ -3894,11 +3895,14 @@ static int nfp_bpf_replace_map_ptrs(struct nfp_prog *nfp_prog)
map = (void *)(unsigned long)((u32)meta1->insn.imm |
(u64)meta2->insn.imm << 32);
- if (bpf_map_offload_neutral(map))
- continue;
- nfp_map = map_to_offmap(map)->dev_priv;
+ if (bpf_map_offload_neutral(map)) {
+ id = map->id;
+ } else {
+ nfp_map = map_to_offmap(map)->dev_priv;
+ id = nfp_map->tid;
+ }
- meta1->insn.imm = nfp_map->tid;
+ meta1->insn.imm = id;
meta2->insn.imm = 0;
}
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index 192e88981fb2..cce1d2945a32 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -45,8 +45,8 @@
const struct rhashtable_params nfp_bpf_maps_neutral_params = {
.nelem_hint = 4,
- .key_len = FIELD_SIZEOF(struct nfp_bpf_neutral_map, ptr),
- .key_offset = offsetof(struct nfp_bpf_neutral_map, ptr),
+ .key_len = FIELD_SIZEOF(struct bpf_map, id),
+ .key_offset = offsetof(struct nfp_bpf_neutral_map, map_id),
.head_offset = offsetof(struct nfp_bpf_neutral_map, l),
.automatic_shrinking = true,
};
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index 017e0ae5e736..57573bfa8c03 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -47,6 +47,8 @@
#include "../nfp_asm.h"
#include "fw.h"
+#define cmsg_warn(bpf, msg...) nn_dp_warn(&(bpf)->app->ctrl->dp, msg)
+
/* For relocation logic use up-most byte of branch instruction as scratch
* area. Remember to clear this before sending instructions to HW!
*/
@@ -221,6 +223,7 @@ struct nfp_bpf_map {
struct nfp_bpf_neutral_map {
struct rhash_head l;
struct bpf_map *ptr;
+ u32 map_id;
u32 count;
};
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 293dda84818f..b1fbb3babc7f 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -67,7 +67,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
ASSERT_RTNL();
/* Reuse path - other offloaded program is already tracking this map. */
- record = rhashtable_lookup_fast(&bpf->maps_neutral, &map,
+ record = rhashtable_lookup_fast(&bpf->maps_neutral, &map->id,
nfp_bpf_maps_neutral_params);
if (record) {
nfp_prog->map_records[nfp_prog->map_records_cnt++] = record;
@@ -89,6 +89,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
}
record->ptr = map;
+ record->map_id = map->id;
record->count = 1;
err = rhashtable_insert_fast(&bpf->maps_neutral, &record->l,
@@ -457,15 +458,17 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
unsigned int len)
{
struct cmsg_bpf_event *cbe = (void *)data;
- u32 pkt_size, data_size;
- struct bpf_map *map;
+ struct nfp_bpf_neutral_map *record;
+ u32 pkt_size, data_size, map_id;
+ u64 map_id_full;
if (len < sizeof(struct cmsg_bpf_event))
return -EINVAL;
pkt_size = be32_to_cpu(cbe->pkt_size);
data_size = be32_to_cpu(cbe->data_size);
- map = (void *)(unsigned long)be64_to_cpu(cbe->map_ptr);
+ map_id_full = be64_to_cpu(cbe->map_ptr);
+ map_id = map_id_full;
if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
return -EINVAL;
@@ -473,15 +476,16 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
return -EINVAL;
rcu_read_lock();
- if (!rhashtable_lookup_fast(&bpf->maps_neutral, &map,
- nfp_bpf_maps_neutral_params)) {
+ record = rhashtable_lookup_fast(&bpf->maps_neutral, &map_id,
+ nfp_bpf_maps_neutral_params);
+ if (!record || map_id_full > U32_MAX) {
rcu_read_unlock();
- pr_warn("perf event: dest map pointer %px not recognized, dropping event\n",
- map);
+ cmsg_warn(bpf, "perf event: map id %lld (0x%llx) not recognized, dropping event\n",
+ map_id_full, map_id_full);
return -EINVAL;
}
- bpf_event_output(map, be32_to_cpu(cbe->cpu_id),
+ bpf_event_output(record->ptr, be32_to_cpu(cbe->cpu_id),
&cbe->data[round_up(pkt_size, 4)], data_size,
cbe->data, pkt_size, nfp_bpf_perf_event_copy);
rcu_read_unlock();
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 4/6] nfp: bpf: allow receiving perf events on data queues
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
Control queue is fairly low latency, and requires SKB allocations,
which means we can't even reach 0.5Msps with perf events. Allow
perf events to be delivered to data queues. This allows us to not
only use multiple queues, but also receive and deliver to user space
more than 5Msps per queue (Xeon E5-2630 v4 2.20GHz, no retpolines).
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 18 ++++++++++++++++++
drivers/net/ethernet/netronome/nfp/bpf/main.c | 1 +
drivers/net/ethernet/netronome/nfp/bpf/main.h | 3 +++
3 files changed, 22 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
index 0a89b53962aa..1946291bf4fd 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
@@ -468,3 +468,21 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb)
err_free:
dev_kfree_skb_any(skb);
}
+
+void
+nfp_bpf_ctrl_msg_rx_raw(struct nfp_app *app, const void *data, unsigned int len)
+{
+ struct nfp_app_bpf *bpf = app->priv;
+ const struct cmsg_hdr *hdr = data;
+
+ if (unlikely(len < sizeof(struct cmsg_reply_map_simple))) {
+ cmsg_warn(bpf, "cmsg drop - too short %d!\n", len);
+ return;
+ }
+
+ if (hdr->type == CMSG_TYPE_BPF_EVENT)
+ nfp_bpf_event_output(bpf, data, len);
+ else
+ cmsg_warn(bpf, "cmsg drop - msg type %d with raw buffer!\n",
+ hdr->type);
+}
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index 994d2b756fe1..192e88981fb2 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -490,6 +490,7 @@ const struct nfp_app_type app_bpf = {
.vnic_free = nfp_bpf_vnic_free,
.ctrl_msg_rx = nfp_bpf_ctrl_msg_rx,
+ .ctrl_msg_rx_raw = nfp_bpf_ctrl_msg_rx_raw,
.setup_tc = nfp_bpf_setup_tc,
.bpf = nfp_ndo_bpf,
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index e25d3c0c7e43..017e0ae5e736 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -505,4 +505,7 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
unsigned int len);
void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb);
+void
+nfp_bpf_ctrl_msg_rx_raw(struct nfp_app *app, const void *data,
+ unsigned int len);
#endif
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 3/6] nfp: bpf: pass raw data buffer to nfp_bpf_event_output()
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
In preparation for SKB-less perf event handling make
nfp_bpf_event_output() take buffer address and length,
not SKB as parameters.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 5 ++++-
drivers/net/ethernet/netronome/nfp/bpf/main.h | 3 ++-
.../net/ethernet/netronome/nfp/bpf/offload.c | 21 ++++++++-----------
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
index cb87fccb9f6a..0a89b53962aa 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
@@ -441,7 +441,10 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb)
}
if (nfp_bpf_cmsg_get_type(skb) == CMSG_TYPE_BPF_EVENT) {
- nfp_bpf_event_output(bpf, skb);
+ if (!nfp_bpf_event_output(bpf, skb->data, skb->len))
+ dev_consume_skb_any(skb);
+ else
+ dev_kfree_skb_any(skb);
return;
}
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index bec935468f90..e25d3c0c7e43 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -501,7 +501,8 @@ int nfp_bpf_ctrl_lookup_entry(struct bpf_offloaded_map *offmap,
int nfp_bpf_ctrl_getnext_entry(struct bpf_offloaded_map *offmap,
void *key, void *next_key);
-int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb);
+int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
+ unsigned int len);
void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb);
#endif
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 49b03f7dbf46..293dda84818f 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -453,23 +453,24 @@ nfp_bpf_perf_event_copy(void *dst, const void *src,
return 0;
}
-int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb)
+int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
+ unsigned int len)
{
- struct cmsg_bpf_event *cbe = (void *)skb->data;
+ struct cmsg_bpf_event *cbe = (void *)data;
u32 pkt_size, data_size;
struct bpf_map *map;
- if (skb->len < sizeof(struct cmsg_bpf_event))
- goto err_drop;
+ if (len < sizeof(struct cmsg_bpf_event))
+ return -EINVAL;
pkt_size = be32_to_cpu(cbe->pkt_size);
data_size = be32_to_cpu(cbe->data_size);
map = (void *)(unsigned long)be64_to_cpu(cbe->map_ptr);
- if (skb->len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
- goto err_drop;
+ if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
+ return -EINVAL;
if (cbe->hdr.ver != CMSG_MAP_ABI_VERSION)
- goto err_drop;
+ return -EINVAL;
rcu_read_lock();
if (!rhashtable_lookup_fast(&bpf->maps_neutral, &map,
@@ -477,7 +478,7 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb)
rcu_read_unlock();
pr_warn("perf event: dest map pointer %px not recognized, dropping event\n",
map);
- goto err_drop;
+ return -EINVAL;
}
bpf_event_output(map, be32_to_cpu(cbe->cpu_id),
@@ -485,11 +486,7 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb)
cbe->data, pkt_size, nfp_bpf_perf_event_copy);
rcu_read_unlock();
- dev_consume_skb_any(skb);
return 0;
-err_drop:
- dev_kfree_skb_any(skb);
- return -EINVAL;
}
static int
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 2/6] nfp: allow control message reception on data queues
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
Port id 0xffffffff is reserved for control messages. Allow reception
of messages with this id on data queues. Hand off a raw buffer to
the higher layer code, without allocating SKB for max efficiency.
The RX handle can't modify or keep the buffer, after it returns
buffer is handed back over to the NIC RX free buffer list.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_app.c | 2 ++
drivers/net/ethernet/netronome/nfp/nfp_app.h | 17 +++++++++++++++++
.../net/ethernet/netronome/nfp/nfp_net_common.c | 11 +++++++++++
.../net/ethernet/netronome/nfp/nfp_net_ctrl.h | 1 +
4 files changed, 31 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c
index 69d4ae7a61f3..8607d09ab732 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c
@@ -172,6 +172,8 @@ struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
if (WARN_ON(!apps[id]->name || !apps[id]->vnic_alloc))
return ERR_PTR(-EINVAL);
+ if (WARN_ON(!apps[id]->ctrl_msg_rx && apps[id]->ctrl_msg_rx_raw))
+ return ERR_PTR(-EINVAL);
app = kzalloc(sizeof(*app), GFP_KERNEL);
if (!app)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h
index afbc19aa66a8..ccb244cf6c30 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h
@@ -98,6 +98,7 @@ extern const struct nfp_app_type app_abm;
* @start: start application logic
* @stop: stop application logic
* @ctrl_msg_rx: control message handler
+ * @ctrl_msg_rx_raw: handler for control messages from data queues
* @setup_tc: setup TC ndo
* @bpf: BPF ndo offload-related calls
* @xdp_offload: offload an XDP program
@@ -150,6 +151,8 @@ struct nfp_app_type {
void (*stop)(struct nfp_app *app);
void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
+ void (*ctrl_msg_rx_raw)(struct nfp_app *app, const void *data,
+ unsigned int len);
int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
enum tc_setup_type type, void *type_data);
@@ -318,6 +321,11 @@ static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
return app->type->ctrl_has_meta;
}
+static inline bool nfp_app_ctrl_uses_data_vnics(struct nfp_app *app)
+{
+ return app && app->type->ctrl_msg_rx_raw;
+}
+
static inline const char *nfp_app_extra_cap(struct nfp_app *app,
struct nfp_net *nn)
{
@@ -381,6 +389,15 @@ static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
app->type->ctrl_msg_rx(app, skb);
}
+static inline void
+nfp_app_ctrl_rx_raw(struct nfp_app *app, const void *data, unsigned int len)
+{
+ trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0, data, len);
+
+ if (app && app->type->ctrl_msg_rx_raw)
+ app->type->ctrl_msg_rx_raw(app, data, len);
+}
+
static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
{
if (!app->type->eswitch_mode_get)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index cdfbd1e8bf4b..ca42f7da4f50 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1759,6 +1759,14 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
if (likely(!meta.portid)) {
netdev = dp->netdev;
+ } else if (meta.portid == NFP_META_PORT_ID_CTRL) {
+ struct nfp_net *nn = netdev_priv(dp->netdev);
+
+ nfp_app_ctrl_rx_raw(nn->app, rxbuf->frag + pkt_off,
+ pkt_len);
+ nfp_net_rx_give_one(dp, rx_ring, rxbuf->frag,
+ rxbuf->dma_addr);
+ continue;
} else {
struct nfp_net *nn;
@@ -3857,6 +3865,9 @@ int nfp_net_init(struct nfp_net *nn)
nn->dp.mtu = NFP_NET_DEFAULT_MTU;
nn->dp.fl_bufsz = nfp_net_calc_fl_bufsz(&nn->dp);
+ if (nfp_app_ctrl_uses_data_vnics(nn->app))
+ nn->dp.ctrl |= nn->cap & NFP_NET_CFG_CTRL_CMSG_DATA;
+
if (nn->cap & NFP_NET_CFG_CTRL_RSS_ANY) {
nfp_net_rss_init(nn);
nn->dp.ctrl |= nn->cap & NFP_NET_CFG_CTRL_RSS2 ?:
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
index bb63c115537d..44d3ea75d043 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
@@ -127,6 +127,7 @@
#define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */
#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO (version 1) */
#define NFP_NET_CFG_CTRL_CTAG_FILTER (0x1 << 11) /* VLAN CTAG filtering */
+#define NFP_NET_CFG_CTRL_CMSG_DATA (0x1 << 12) /* RX cmsgs on data Qs */
#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */
#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS (version 1) */
#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 1/6] nfp: move repr handling on RX path
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726025335.23017-1-jakub.kicinski@netronome.com>
Representor packets are received on PF queues with special metadata tag
for demux. There is no reason to resolve the representor ID -> netdev
after the skb has been allocated. Move the code, this will allow us to
handle special FW messages without SKB allocation overhead.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
.../ethernet/netronome/nfp/nfp_net_common.c | 29 ++++++++++---------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index cf1704e972b7..cdfbd1e8bf4b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1757,6 +1757,21 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
}
}
+ if (likely(!meta.portid)) {
+ netdev = dp->netdev;
+ } else {
+ struct nfp_net *nn;
+
+ nn = netdev_priv(dp->netdev);
+ netdev = nfp_app_repr_get(nn->app, meta.portid);
+ if (unlikely(!netdev)) {
+ nfp_net_rx_drop(dp, r_vec, rx_ring, rxbuf,
+ NULL);
+ continue;
+ }
+ nfp_repr_inc_rx_stats(netdev, pkt_len);
+ }
+
skb = build_skb(rxbuf->frag, true_bufsz);
if (unlikely(!skb)) {
nfp_net_rx_drop(dp, r_vec, rx_ring, rxbuf, NULL);
@@ -1772,20 +1787,6 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
nfp_net_rx_give_one(dp, rx_ring, new_frag, new_dma_addr);
- if (likely(!meta.portid)) {
- netdev = dp->netdev;
- } else {
- struct nfp_net *nn;
-
- nn = netdev_priv(dp->netdev);
- netdev = nfp_app_repr_get(nn->app, meta.portid);
- if (unlikely(!netdev)) {
- nfp_net_rx_drop(dp, r_vec, rx_ring, NULL, skb);
- continue;
- }
- nfp_repr_inc_rx_stats(netdev, pkt_len);
- }
-
skb_reserve(skb, pkt_off);
skb_put(skb, pkt_len);
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 0/6] nfp: bpf: improve efficiency of offloaded perf events
From: Jakub Kicinski @ 2018-07-26 2:53 UTC (permalink / raw)
To: alexei.starovoitov, daniel; +Cc: oss-drivers, netdev, Jakub Kicinski
Hi!
This set is focused on improving the performance of perf events
reported from BPF offload. Perf events can now be received on
packet data queues, which significantly improves the performance
(from total of 0.5 Msps to 5Msps per core). To get to this
performance we need a fast path for control messages which will
operate on raw buffers and recycle them immediately.
Patch 5 replaces the map pointers for perf maps with map IDs.
We look the pointers up in a hashtable, anyway, to validate they
are correct, so there is no performance difference. Map IDs
have the advantage of being easier to understand for users in
case of errors (we no longer print raw pointers to the logs).
Last patch improves info messages about map offload.
Jakub Kicinski (6):
nfp: move repr handling on RX path
nfp: allow control message reception on data queues
nfp: bpf: pass raw data buffer to nfp_bpf_event_output()
nfp: bpf: allow receiving perf events on data queues
nfp: bpf: remember maps by ID
nfp: bpf: improve map offload info messages
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 25 +++++++-
drivers/net/ethernet/netronome/nfp/bpf/jit.c | 12 ++--
drivers/net/ethernet/netronome/nfp/bpf/main.c | 5 +-
drivers/net/ethernet/netronome/nfp/bpf/main.h | 9 ++-
.../net/ethernet/netronome/nfp/bpf/offload.c | 63 +++++++++++--------
drivers/net/ethernet/netronome/nfp/nfp_app.c | 2 +
drivers/net/ethernet/netronome/nfp/nfp_app.h | 17 +++++
.../ethernet/netronome/nfp/nfp_net_common.c | 40 +++++++-----
.../net/ethernet/netronome/nfp/nfp_net_ctrl.h | 1 +
9 files changed, 125 insertions(+), 49 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH net-next] tcp: add SNMP counter for the number of packets pruned from ofo queue
From: Eric Dumazet @ 2018-07-26 4:06 UTC (permalink / raw)
To: Yafang Shao, Eric Dumazet; +Cc: David Miller, Eric Dumazet, netdev, LKML
In-Reply-To: <CALOAHbAHgEF_=w_hbd_03NOH3h9m-4W=UJ0HCYGK0BtEyq=5Tw@mail.gmail.com>
On 07/25/2018 06:42 PM, Yafang Shao wrote:
>
> Hi Eric,
>
> LINUX_MIB_TCPOFOQUEUE, LINUX_MIB_TCPOFODROP and LINUX_MIB_TCPOFOMERGE
> are all for the number of SKBs, but only LINUX_MIB_OFOPRUNED is for
> the event, that could lead misunderstading.
> So I think introducing a counter for the number of SKB pruned could be
> better, that could help us to track the whole behavior of ofo queue.
> That is why I submit this patch.
Sure, and I said your patch had issues.
You mixed 'packets' and 'skbs' but apparently you do not get my point.
I would rather not add another SNMP counter, and refine the current one,
trying to track something more meaningful.
The notion of 'skb' is internal to the kernel, and can not be mapped easily
to 'number of network segments' which probably is more useful for the user.
I will send this instead :
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d51fa358b2b196d0f9c258b24354813f2128a675..141a062abd0660c8f6d049de1dc7c7ecf7a7230d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5001,18 +5001,19 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
struct rb_node *node, *prev;
+ unsigned int segs = 0;
int goal;
if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
return false;
- NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED);
goal = sk->sk_rcvbuf >> 3;
node = &tp->ooo_last_skb->rbnode;
do {
prev = rb_prev(node);
rb_erase(node, &tp->out_of_order_queue);
goal -= rb_to_skb(node)->truesize;
+ segs += max_t(u16, 1, skb_shinfo(rb_to_skb(node))->gso_segs);
tcp_drop(sk, rb_to_skb(node));
if (!prev || goal <= 0) {
sk_mem_reclaim(sk);
@@ -5023,6 +5024,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk)
}
node = prev;
} while (node);
+ NET_ADD_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED, segs);
tp->ooo_last_skb = rb_to_skb(prev);
/* Reset SACK state. A conforming SACK implementation will
^ permalink raw reply related
* [PATCH net-next 4/4] nfp: protect from theoretical size overflows on HW descriptor ring
From: Jakub Kicinski @ 2018-07-26 2:40 UTC (permalink / raw)
To: davem; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726024037.28704-1-jakub.kicinski@netronome.com>
Use array_size() and store the size as full size_t to protect from
theoretical size overflow when handling HW descriptor rings.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net.h | 4 ++--
drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 9 +++++----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 607896910fb0..439e6ffe2f05 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -250,7 +250,7 @@ struct nfp_net_tx_ring {
struct nfp_net_tx_desc *txds;
dma_addr_t dma;
- unsigned int size;
+ size_t size;
bool is_xdp;
} ____cacheline_aligned;
@@ -372,7 +372,7 @@ struct nfp_net_rx_ring {
struct xdp_rxq_info xdp_rxq;
dma_addr_t dma;
- unsigned int size;
+ size_t size;
} ____cacheline_aligned;
/**
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index d02baefcb350..7c1a921d178d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -54,6 +54,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/mm.h>
+#include <linux/overflow.h>
#include <linux/page_ref.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
@@ -1121,7 +1122,7 @@ nfp_net_tx_ring_reset(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring)
tx_ring->rd_p++;
}
- memset(tx_ring->txds, 0, sizeof(*tx_ring->txds) * tx_ring->cnt);
+ memset(tx_ring->txds, 0, tx_ring->size);
tx_ring->wr_p = 0;
tx_ring->rd_p = 0;
tx_ring->qcp_rd_p = 0;
@@ -1301,7 +1302,7 @@ static void nfp_net_rx_ring_reset(struct nfp_net_rx_ring *rx_ring)
rx_ring->rxbufs[last_idx].dma_addr = 0;
rx_ring->rxbufs[last_idx].frag = NULL;
- memset(rx_ring->rxds, 0, sizeof(*rx_ring->rxds) * rx_ring->cnt);
+ memset(rx_ring->rxds, 0, rx_ring->size);
rx_ring->wr_p = 0;
rx_ring->rd_p = 0;
}
@@ -2154,7 +2155,7 @@ nfp_net_tx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring)
tx_ring->cnt = dp->txd_cnt;
- tx_ring->size = sizeof(*tx_ring->txds) * tx_ring->cnt;
+ tx_ring->size = array_size(tx_ring->cnt, sizeof(*tx_ring->txds));
tx_ring->txds = dma_zalloc_coherent(dp->dev, tx_ring->size,
&tx_ring->dma, GFP_KERNEL);
if (!tx_ring->txds)
@@ -2308,7 +2309,7 @@ nfp_net_rx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring)
}
rx_ring->cnt = dp->rxd_cnt;
- rx_ring->size = sizeof(*rx_ring->rxds) * rx_ring->cnt;
+ rx_ring->size = array_size(rx_ring->cnt, sizeof(*rx_ring->rxds));
rx_ring->rxds = dma_zalloc_coherent(dp->dev, rx_ring->size,
&rx_ring->dma, GFP_KERNEL);
if (!rx_ring->rxds)
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 3/4] nfp: restore correct ordering of fields in rx ring structure
From: Jakub Kicinski @ 2018-07-26 2:40 UTC (permalink / raw)
To: davem; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726024037.28704-1-jakub.kicinski@netronome.com>
Commit 7f1c684a8966 ("nfp: setup xdp_rxq_info") mixed the cache
cold and cache hot data in the nfp_net_rx_ring structure (ignoring
the feedback), to try to fit the structure into 2 cache lines
after struct xdp_rxq_info was added. Now that we are about to add
a new field the structure will grow back to 3 cache lines, so
order the members correctly.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 8970ec981e11..607896910fb0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -350,9 +350,9 @@ struct nfp_net_rx_buf {
* @qcp_fl: Pointer to base of the QCP freelist queue
* @rxbufs: Array of transmitted FL/RX buffers
* @rxds: Virtual address of FL/RX ring in host memory
+ * @xdp_rxq: RX-ring info avail for XDP
* @dma: DMA address of the FL/RX ring
* @size: Size, in bytes, of the FL/RX ring (needed to free)
- * @xdp_rxq: RX-ring info avail for XDP
*/
struct nfp_net_rx_ring {
struct nfp_net_r_vector *r_vec;
@@ -364,14 +364,15 @@ struct nfp_net_rx_ring {
u32 idx;
int fl_qcidx;
- unsigned int size;
u8 __iomem *qcp_fl;
struct nfp_net_rx_buf *rxbufs;
struct nfp_net_rx_desc *rxds;
- dma_addr_t dma;
struct xdp_rxq_info xdp_rxq;
+
+ dma_addr_t dma;
+ unsigned int size;
} ____cacheline_aligned;
/**
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 2/4] nfp: use kvcalloc() to allocate SW buffer descriptor arrays
From: Jakub Kicinski @ 2018-07-26 2:40 UTC (permalink / raw)
To: davem; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726024037.28704-1-jakub.kicinski@netronome.com>
Use kvcalloc() instead of tmp variable + kzalloc() when allocating
SW buffer information to allow falling back to vmalloc and to protect
from theoretical integer overflow.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_common.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index cf1704e972b7..d02baefcb350 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -53,6 +53,7 @@
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <linux/mm.h>
#include <linux/page_ref.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
@@ -2126,7 +2127,7 @@ static void nfp_net_tx_ring_free(struct nfp_net_tx_ring *tx_ring)
struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
struct nfp_net_dp *dp = &r_vec->nfp_net->dp;
- kfree(tx_ring->txbufs);
+ kvfree(tx_ring->txbufs);
if (tx_ring->txds)
dma_free_coherent(dp->dev, tx_ring->size,
@@ -2150,7 +2151,6 @@ static int
nfp_net_tx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring)
{
struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
- int sz;
tx_ring->cnt = dp->txd_cnt;
@@ -2160,8 +2160,8 @@ nfp_net_tx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring)
if (!tx_ring->txds)
goto err_alloc;
- sz = sizeof(*tx_ring->txbufs) * tx_ring->cnt;
- tx_ring->txbufs = kzalloc(sz, GFP_KERNEL);
+ tx_ring->txbufs = kvcalloc(tx_ring->cnt, sizeof(*tx_ring->txbufs),
+ GFP_KERNEL);
if (!tx_ring->txbufs)
goto err_alloc;
@@ -2275,7 +2275,7 @@ static void nfp_net_rx_ring_free(struct nfp_net_rx_ring *rx_ring)
if (dp->netdev)
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
- kfree(rx_ring->rxbufs);
+ kvfree(rx_ring->rxbufs);
if (rx_ring->rxds)
dma_free_coherent(dp->dev, rx_ring->size,
@@ -2298,7 +2298,7 @@ static void nfp_net_rx_ring_free(struct nfp_net_rx_ring *rx_ring)
static int
nfp_net_rx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring)
{
- int sz, err;
+ int err;
if (dp->netdev) {
err = xdp_rxq_info_reg(&rx_ring->xdp_rxq, dp->netdev,
@@ -2314,8 +2314,8 @@ nfp_net_rx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring)
if (!rx_ring->rxds)
goto err_alloc;
- sz = sizeof(*rx_ring->rxbufs) * rx_ring->cnt;
- rx_ring->rxbufs = kzalloc(sz, GFP_KERNEL);
+ rx_ring->rxbufs = kvcalloc(rx_ring->cnt, sizeof(*rx_ring->rxbufs),
+ GFP_KERNEL);
if (!rx_ring->rxbufs)
goto err_alloc;
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 1/4] nfp: don't fail probe on pci_sriov_set_totalvfs() errors
From: Jakub Kicinski @ 2018-07-26 2:40 UTC (permalink / raw)
To: davem; +Cc: oss-drivers, netdev, Jakub Kicinski
In-Reply-To: <20180726024037.28704-1-jakub.kicinski@netronome.com>
On machines with buggy ACPI tables or when SR-IOV is already enabled
we may not be able to set the SR-IOV VF limit in sysfs, it's not fatal
because the limit is imposed by the driver anyway. Only the sysfs
'sriov_totalvfs' attribute will be too high. Print an error to inform
user about the failure but allow probe to continue.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 20 +++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 152283d7e59c..4a540c5e27fe 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -236,16 +236,20 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
int err;
pf->limit_vfs = nfp_rtsym_read_le(pf->rtbl, "nfd_vf_cfg_max_vfs", &err);
- if (!err)
- return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
+ if (err) {
+ /* For backwards compatibility if symbol not found allow all */
+ pf->limit_vfs = ~0;
+ if (err == -ENOENT)
+ return 0;
- pf->limit_vfs = ~0;
- /* Allow any setting for backwards compatibility if symbol not found */
- if (err == -ENOENT)
- return 0;
+ nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err);
+ return err;
+ }
- nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err);
- return err;
+ err = pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
+ if (err)
+ nfp_warn(pf->cpp, "Failed to set VF count in sysfs: %d\n", err);
+ return 0;
}
static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs)
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 0/4] nfp: protect from theoretical size overflows and SR-IOV errors
From: Jakub Kicinski @ 2018-07-26 2:40 UTC (permalink / raw)
To: davem; +Cc: oss-drivers, netdev, Jakub Kicinski
Hi!
This small set changes the handling of pci_sriov_set_totalvfs() errors.
nfp is the only driver which fails probe on pci_sriov_set_totalvfs()
errors. It turns out some BIOS configurations may break SR-IOV and
users who don't use that feature should not suffer.
Remaining patches makes sure we use overflow-safe function for ring
allocation, even though ring sizes are limited. It won't hurt and
we can also enable fallback to vmalloc() if memory is tight while
at it.
Jakub Kicinski (4):
nfp: don't fail probe on pci_sriov_set_totalvfs() errors
nfp: use kvcalloc() to allocate SW buffer descriptor arrays
nfp: restore correct ordering of fields in rx ring structure
nfp: protect from theoretical size overflows on HW descriptor ring
drivers/net/ethernet/netronome/nfp/nfp_main.c | 20 +++++++++------
drivers/net/ethernet/netronome/nfp/nfp_net.h | 9 ++++---
.../ethernet/netronome/nfp/nfp_net_common.c | 25 ++++++++++---------
3 files changed, 30 insertions(+), 24 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 18/18] xfrm: Enable compat syscalls
From: Dmitry Safonov @ 2018-07-26 2:31 UTC (permalink / raw)
To: linux-kernel
Cc: Dmitry Safonov, David S. Miller, Herbert Xu, Steffen Klassert,
Dmitry Safonov, netdev, Fan Du
In-Reply-To: <20180726023144.31066-1-dima@arista.com>
Compatible syscalls were disabled for xfrm with the following commits:
19d7df69fdb2 ("xfrm: Refuse to insert 32 bit userspace socket policies
on 64 bit systems") and 74005991b78a ("xfrm: Do not parse 32bits
compiled xfrm netlink msg on 64bits host").
As some structures in xfrm uapi header were not packed by a mistake,
they differ in size between 64-bit and 32-bit applications:
32-bit UABI | 64-bit UABI
--------------------------------------|--------------------------------------
sizeof(xfrm_usersa_info) = 220 | sizeof(xfrm_usersa_info) = 224
sizeof(xfrm_userpolicy_info) = 164 | sizeof(xfrm_userpolicy_info) = 168
sizeof(xfrm_userspi_info) = 228 | sizeof(xfrm_userspi_info) = 232
sizeof(xfrm_user_acquire) = 276 | sizeof(xfrm_user_acquire) = 280
sizeof(xfrm_user_expire) = 224 | sizeof(xfrm_user_expire) = 232
sizeof(xfrm_user_polexpire) = 168 | sizeof(xfrm_user_polexpire) = 176
With previous patches compatible layer was added to xfrm, so now we
support users of both ABI. A selftest to check work of ipsec tunnel is
present in net/ipsec. It can be easily compiled as compat application
and doesn't require any compat libraries.
Revert the mentioned commits and check the size of received message
according to native/compat syscall.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Fan Du <fan.du@intel.com>
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>
---
net/xfrm/xfrm_state.c | 3 ---
net/xfrm/xfrm_user.c | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3f48a6925606..515a565bfc37 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2057,9 +2057,6 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
struct xfrm_mgr *km;
struct xfrm_policy *pol = NULL;
- if (in_compat_syscall())
- return -EOPNOTSUPP;
-
if (!optval && !optlen) {
xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7e3a132b76fb..f6da6ea65d37 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2634,6 +2634,30 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
[XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = sizeof(u32),
};
+static const int xfrm_msg_min_compat[XFRM_NR_MSGTYPES] = {
+ [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info_packed),
+ [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
+ [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
+ [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info_packed),
+ [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
+ [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
+ [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info_packed),
+ [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire_packed),
+ [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire_packed),
+ [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info_packed),
+ [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info_packed),
+ [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire_packed),
+ [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
+ [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0,
+ [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
+ [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
+ [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report),
+ [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
+ [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = sizeof(u32),
+ [XFRM_MSG_NEWSPDINFO - XFRM_MSG_BASE] = sizeof(u32),
+ [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = sizeof(u32),
+};
+
#undef XMSGSIZE
static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
@@ -2715,10 +2739,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *net = sock_net(skb->sk);
struct nlattr *attrs[XFRMA_MAX+1];
const struct xfrm_link *link;
- int type, err;
-
- if (in_compat_syscall())
- return -EOPNOTSUPP;
+ int type, err, hdrlen;
type = nlh->nlmsg_type;
if (type > XFRM_MSG_MAX)
@@ -2747,7 +2768,11 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
}
}
- err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs,
+ hdrlen = xfrm_msg_min[type];
+ if (in_compat_syscall())
+ hdrlen = xfrm_msg_min_compat[type];
+
+ err = nlmsg_parse(nlh, hdrlen, attrs,
link->nla_max ? : XFRMA_MAX,
link->nla_pol ? : xfrma_policy, extack);
if (err < 0)
--
2.13.6
^ permalink raw reply related
* [PATCH 15/18] xfrm: Check compat acquire listeners in xfrm_is_alive()
From: Dmitry Safonov @ 2018-07-26 2:31 UTC (permalink / raw)
To: linux-kernel
Cc: Dmitry Safonov, David S. Miller, Herbert Xu, Steffen Klassert,
Dmitry Safonov, netdev
In-Reply-To: <20180726023144.31066-1-dima@arista.com>
As now there are two groups of listeners:
XFRMNLGRP_ACQUIRE - applications that uses native UABI for messages;
XFRMNLGRP_COMPAT_ACQUIRE - applications that uses compat UABI for messages;
So, both groups should be checked for listeners of acquire
notifications.
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>
---
include/net/xfrm.h | 14 --------------
net/xfrm/xfrm_user.c | 16 ++++++++++++++++
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 557122846e0e..c9b713017ae8 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1784,20 +1784,6 @@ static inline int xfrm_aevent_is_on(struct net *net)
rcu_read_unlock();
return ret;
}
-
-static inline int xfrm_acquire_is_on(struct net *net)
-{
- struct sock *nlsk;
- int ret = 0;
-
- rcu_read_lock();
- nlsk = rcu_dereference(net->xfrm.nlsk);
- if (nlsk)
- ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
- rcu_read_unlock();
-
- return ret;
-}
#endif
static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2fe6174b8a18..752019963b1e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -3517,6 +3517,22 @@ static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_MAPPING);
}
+static inline int xfrm_acquire_is_on(struct net *net)
+{
+ struct sock *nlsk;
+ int ret = 0;
+
+ rcu_read_lock();
+ nlsk = rcu_dereference(net->xfrm.nlsk);
+ if (nlsk)
+ ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
+ if (!ret || IS_ENABLED(CONFIG_COMPAT))
+ ret = netlink_has_listeners(nlsk, XFRMNLGRP_COMPAT_ACQUIRE);
+ rcu_read_unlock();
+
+ return ret;
+}
+
static bool xfrm_is_alive(const struct km_event *c)
{
return (bool)xfrm_acquire_is_on(c->net);
--
2.13.6
^ permalink raw reply related
* [PATCH 14/18] xfrm: Add compat support for xfrm_user_polexpire messages
From: Dmitry Safonov @ 2018-07-26 2:31 UTC (permalink / raw)
To: linux-kernel
Cc: Dmitry Safonov, David S. Miller, Herbert Xu, Steffen Klassert,
Dmitry Safonov, netdev
In-Reply-To: <20180726023144.31066-1-dima@arista.com>
Parse polexpire messages sent by userspace according to in_compat_syscall().
Applications that used native bind() syscall are in XFRMNLGRP_EXPIRE, so
send there xfrm_usersa_info messages (with 64-bit ABI). Compatible
applications are added to kernel-hidden XFRMNLGRP_COMPAT_EXPIRE group, so
send there xfrm_usersa_info messages_packed (with 32-bit ABI)
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>
---
net/xfrm/xfrm_user.c | 89 +++++++++++++++++++++++++++++++++++-----------------
1 file changed, 61 insertions(+), 28 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 89f891a0a9a4..2fe6174b8a18 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -84,6 +84,12 @@ struct xfrm_user_acquire_packed {
__u32 seq;
} __packed;
+struct xfrm_user_polexpire_packed {
+ struct xfrm_userpolicy_info_packed pol;
+ __u8 hard;
+ __u8 __pad[3];
+} __packed;
+
/* In-kernel, non-uapi compat groups.
* As compat/native messages differ, send notifications according
* to .bind() caller's ABI. There are *_COMPAT hidden from userspace
@@ -2225,7 +2231,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
int err = -ENOENT;
struct xfrm_mark m;
u32 mark = xfrm_mark_get(attrs, &m);
+ u8 hard;
+ if (in_compat_syscall()) {
+ struct xfrm_user_polexpire_packed *_up = nlmsg_data(nlh);
+
+ hard = _up->hard;
+ } else {
+ hard = up->hard;
+ }
err = copy_from_user_policy_type(&type, attrs);
if (err)
return err;
@@ -2263,11 +2277,11 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
goto out;
err = 0;
- if (up->hard) {
+ if (hard) {
xfrm_policy_delete(xp, p->dir);
xfrm_audit_policy_delete(xp, 1, true);
}
- km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid);
+ km_policy_expired(xp, p->dir, hard, nlh->nlmsg_pid);
out:
xfrm_pol_put(xp);
@@ -3192,43 +3206,59 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
return xp;
}
-static inline unsigned int xfrm_polexpire_msgsize(struct xfrm_policy *xp)
+static int build_polexpire(struct sk_buff **skb, struct xfrm_policy *xp,
+ int dir, const struct km_event *c, bool compat)
{
- return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire))
+ struct xfrm_user_polexpire_packed *_upe;
+ struct xfrm_user_polexpire *upe;
+ unsigned int upe_size, polexpire_msgsize;
+ int hard = c->data.hard;
+ struct nlmsghdr *nlh;
+ int err;
+
+ if (compat)
+ upe_size = NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire_packed));
+ else
+ upe_size = NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire));
+ polexpire_msgsize = upe_size
+ nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
+ nla_total_size(xfrm_user_sec_ctx_size(xp->security))
+ nla_total_size(sizeof(struct xfrm_mark))
+ userpolicy_type_attrsize();
-}
-static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
- int dir, const struct km_event *c)
-{
- struct xfrm_user_polexpire *upe;
- int hard = c->data.hard;
- struct nlmsghdr *nlh;
- int err;
+ *skb = nlmsg_new(polexpire_msgsize, GFP_ATOMIC);
+ if (*skb == NULL)
+ return -ENOMEM;
- nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
+ nlh = nlmsg_put(*skb, c->portid, 0, XFRM_MSG_POLEXPIRE, upe_size, 0);
if (nlh == NULL)
return -EMSGSIZE;
+ _upe = nlmsg_data(nlh);
upe = nlmsg_data(nlh);
- copy_to_user_policy(xp, &upe->pol, dir);
- err = copy_to_user_tmpl(xp, skb);
+ if (compat)
+ copy_to_user_policy_compat(xp, &_upe->pol, dir);
+ else
+ copy_to_user_policy(xp, &upe->pol, dir);
+
+ err = copy_to_user_tmpl(xp, *skb);
if (!err)
- err = copy_to_user_sec_ctx(xp, skb);
+ err = copy_to_user_sec_ctx(xp, *skb);
if (!err)
- err = copy_to_user_policy_type(xp->type, skb);
+ err = copy_to_user_policy_type(xp->type, *skb);
if (!err)
- err = xfrm_mark_put(skb, &xp->mark);
+ err = xfrm_mark_put(*skb, &xp->mark);
if (err) {
- nlmsg_cancel(skb, nlh);
+ nlmsg_cancel(*skb, nlh);
return err;
}
- upe->hard = !!hard;
- nlmsg_end(skb, nlh);
+ if (compat)
+ _upe->hard = !!hard;
+ else
+ upe->hard = !!hard;
+
+ nlmsg_end(*skb, nlh);
return 0;
}
@@ -3238,14 +3268,17 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, const struct
struct sk_buff *skb;
int err;
- skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC);
- if (skb == NULL)
- return -ENOMEM;
-
- err = build_polexpire(skb, xp, dir, c);
- BUG_ON(err < 0);
+ err = build_polexpire(&skb, xp, dir, c, false);
+ if (err)
+ return err;
+ err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_EXPIRE);
+ if ((err && err != -ESRCH) || !IS_ENABLED(CONFIG_COMPAT))
+ return err;
- return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_EXPIRE);
+ err = build_polexpire(&skb, xp, dir, c, true);
+ if (err)
+ return err;
+ return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_COMPAT_EXPIRE);
}
static int __xfrm_notify_policy(struct xfrm_policy *xp, int dir,
--
2.13.6
^ permalink raw reply related
* [PATCH 05/18] net/xfrm: Parse userspi_info{,_packed} depending on syscall
From: Dmitry Safonov @ 2018-07-26 2:31 UTC (permalink / raw)
To: linux-kernel
Cc: Dmitry Safonov, David S. Miller, Herbert Xu, Steffen Klassert,
Dmitry Safonov, netdev
In-Reply-To: <20180726023144.31066-1-dima@arista.com>
Struct xfrm_userspi_info differs in size between 64-bit/32-bit UAPI
because of (possible) padding of xfrm_usersa_info:
32-bit 64-bit
----------------------------------------------------------------------
sizeof(xfrm_userspi_info) = 228 | sizeof(xfrm_userspi_info) = 232
xfrm_userspi_info::info = 0 | xfrm_userspi_info::info = 0
xfrm_userspi_info::min = 220 | xfrm_userspi_info::min = 224
xfrm_userspi_info::max = 224 | xfrm_userspi_info::max = 228
xfrm_alloc_userspi() can handle both UAPI by checking the type of
send() syscall used by userspace with XFRM_MSG_ALLOCSPI.
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>
---
net/xfrm/xfrm_user.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b382cdd3bef6..bf2ca93edaf5 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -61,6 +61,12 @@ struct xfrm_userpolicy_info_packed {
__u8 share;
} __packed;
+struct xfrm_userspi_info_packed {
+ struct xfrm_usersa_info_packed info;
+ __u32 min;
+ __u32 max;
+} __packed;
+
static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
{
struct nlattr *rt = attrs[type];
@@ -1279,11 +1285,21 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
xfrm_address_t *daddr;
int family;
int err;
- u32 mark;
+ u32 mark, spi_min, spi_max;
struct xfrm_mark m;
p = nlmsg_data(nlh);
- err = verify_spi_info(p->info.id.proto, p->min, p->max);
+ if (in_compat_syscall()) {
+ struct xfrm_userspi_info_packed *_p = nlmsg_data(nlh);
+
+ spi_min = _p->min;
+ spi_max = _p->max;
+ } else {
+ spi_min = p->min;
+ spi_max = p->max;
+ }
+
+ err = verify_spi_info(p->info.id.proto, spi_min, spi_max);
if (err)
goto out_noput;
@@ -1310,7 +1326,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
if (x == NULL)
goto out_noput;
- err = xfrm_alloc_spi(x, p->min, p->max);
+ err = xfrm_alloc_spi(x, spi_min, spi_max);
if (err)
goto out;
--
2.13.6
^ permalink raw reply related
* [PATCH 04/18] net/xfrm: Add _packed types for compat users
From: Dmitry Safonov @ 2018-07-26 2:31 UTC (permalink / raw)
To: linux-kernel
Cc: Dmitry Safonov, David S. Miller, Herbert Xu, Steffen Klassert,
Dmitry Safonov, netdev
In-Reply-To: <20180726023144.31066-1-dima@arista.com>
xfrm_usersa_info and xfrm_userpolicy_info structures differ in size
between 64-bit and 32-bit ABI. In 64-bit ABI there is additional
4-byte padding in the end of the structure:
32-bit:
sizeof(xfrm_usersa_info) = 220
sizeof(xfrm_userpolicy_info) = 164
64-bit:
sizeof(xfrm_usersa_info) = 224
sizeof(xfrm_userpolicy_info) = 168
In preparation to add compat support to xfrm it's needed to add _packed
verstion for those types.
Parse xfrm_usersa_info and xfrm_userpolicy_info netlink messages
sent by userspace using _packed structures (as we don't care about
parsing padding).
Sending _packed notification messages back to userspace will be done
with following patches (in copy_to_user_state() and
copy_to_user_policy()).
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>
---
net/xfrm/xfrm_user.c | 89 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 65 insertions(+), 24 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2677cb55b7a8..b382cdd3bef6 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -33,6 +33,34 @@
#endif
#include <asm/unaligned.h>
+struct xfrm_usersa_info_packed {
+ struct xfrm_selector sel;
+ struct xfrm_id id;
+ xfrm_address_t saddr;
+ struct xfrm_lifetime_cfg lft;
+ struct xfrm_lifetime_cur curlft;
+ struct xfrm_stats stats;
+ __u32 seq;
+ __u32 reqid;
+ __u16 family;
+ __u8 mode; /* XFRM_MODE_xxx */
+ __u8 replay_window;
+ __u8 flags;
+ __u8 __pad[3];
+} __packed;
+
+struct xfrm_userpolicy_info_packed {
+ struct xfrm_selector sel;
+ struct xfrm_lifetime_cfg lft;
+ struct xfrm_lifetime_cur curlft;
+ __u32 priority;
+ __u32 index;
+ __u8 dir;
+ __u8 action;
+ __u8 flags;
+ __u8 share;
+} __packed;
+
static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
{
struct nlattr *rt = attrs[type];
@@ -115,7 +143,7 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs)
return 0;
}
-static inline int verify_replay(struct xfrm_usersa_info *p,
+static inline int verify_replay(struct xfrm_usersa_info_packed *p,
struct nlattr **attrs)
{
struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
@@ -143,7 +171,7 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
return 0;
}
-static int verify_newsa_info(struct xfrm_usersa_info *p,
+static int verify_newsa_info(struct xfrm_usersa_info_packed *p,
struct nlattr **attrs)
{
int err;
@@ -464,7 +492,8 @@ static inline unsigned int xfrm_user_sec_ctx_size(struct xfrm_sec_ctx *xfrm_ctx)
return len;
}
-static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
+static void copy_from_user_state(struct xfrm_state *x,
+ struct xfrm_usersa_info_packed *p)
{
memcpy(&x->id, &p->id, sizeof(x->id));
memcpy(&x->sel, &p->sel, sizeof(x->sel));
@@ -528,9 +557,8 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
}
static struct xfrm_state *xfrm_state_construct(struct net *net,
- struct xfrm_usersa_info *p,
- struct nlattr **attrs,
- int *errp)
+ struct xfrm_usersa_info_packed *p,
+ struct nlattr **attrs, int *errp)
{
struct xfrm_state *x = xfrm_state_alloc(net);
int err = -ENOMEM;
@@ -630,7 +658,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
struct nlattr **attrs)
{
struct net *net = sock_net(skb->sk);
- struct xfrm_usersa_info *p = nlmsg_data(nlh);
+ struct xfrm_usersa_info_packed *p = nlmsg_data(nlh);
struct xfrm_state *x;
int err;
struct km_event c;
@@ -1331,7 +1359,7 @@ static int verify_policy_type(u8 type)
return 0;
}
-static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
+static int verify_newpolicy_info(struct xfrm_userpolicy_info_packed *p)
{
int ret;
@@ -1513,7 +1541,8 @@ static int copy_from_user_policy_type(u8 *tp, struct nlattr **attrs)
return 0;
}
-static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p)
+static void copy_from_user_policy(struct xfrm_policy *xp,
+ struct xfrm_userpolicy_info_packed *p)
{
xp->priority = p->priority;
xp->index = p->index;
@@ -1540,7 +1569,9 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
p->share = XFRM_SHARE_ANY; /* XXX xp->share */
}
-static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
+static struct xfrm_policy *xfrm_policy_construct(struct net *net,
+ struct xfrm_userpolicy_info_packed *p,
+ struct nlattr **attrs, int *errp)
{
struct xfrm_policy *xp = xfrm_policy_alloc(net, GFP_KERNEL);
int err;
@@ -1575,7 +1606,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
struct nlattr **attrs)
{
struct net *net = sock_net(skb->sk);
- struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
+ struct xfrm_userpolicy_info_packed *p = nlmsg_data(nlh);
struct xfrm_policy *xp;
struct km_event c;
int err;
@@ -2079,7 +2110,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *net = sock_net(skb->sk);
struct xfrm_policy *xp;
struct xfrm_user_polexpire *up = nlmsg_data(nlh);
- struct xfrm_userpolicy_info *p = &up->pol;
+ struct xfrm_userpolicy_info_packed *p = (void *)&up->pol;
u8 type = XFRM_POLICY_TYPE_MAIN;
int err = -ENOENT;
struct xfrm_mark m;
@@ -2140,7 +2171,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_state *x;
int err;
struct xfrm_user_expire *ue = nlmsg_data(nlh);
- struct xfrm_usersa_info *p = &ue->state;
+ struct xfrm_usersa_info_packed *p = (struct xfrm_usersa_info_packed *)&ue->state;
struct xfrm_mark m;
u32 mark = xfrm_mark_get(attrs, &m);
@@ -2178,6 +2209,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_mark mark;
struct xfrm_user_acquire *ua = nlmsg_data(nlh);
+ struct xfrm_userpolicy_info_packed *upi = (void *)&ua->policy;
struct xfrm_state *x = xfrm_state_alloc(net);
int err = -ENOMEM;
@@ -2186,12 +2218,12 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
xfrm_mark_get(attrs, &mark);
- err = verify_newpolicy_info(&ua->policy);
+ err = verify_newpolicy_info(upi);
if (err)
goto free_state;
/* build an XP */
- xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
+ xp = xfrm_policy_construct(net, upi, attrs, &err);
if (!xp)
goto free_state;
@@ -2881,11 +2913,21 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
u8 *data, int len, int *dir)
{
struct net *net = sock_net(sk);
- struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
- struct xfrm_user_tmpl *ut = (struct xfrm_user_tmpl *) (p + 1);
+ struct xfrm_userpolicy_info *upi = (void *)data;
+ struct xfrm_userpolicy_info_packed *_upi = (void *)data;
+ size_t policy_size;
+ struct xfrm_user_tmpl *ut;
struct xfrm_policy *xp;
int nr;
+ if (in_compat_syscall()) {
+ ut = (struct xfrm_user_tmpl *)(_upi + 1);
+ policy_size = sizeof(*_upi);
+ } else {
+ ut = (struct xfrm_user_tmpl *)(upi + 1);
+ policy_size = sizeof(*upi);
+ }
+
switch (sk->sk_family) {
case AF_INET:
if (opt != IP_XFRM_POLICY) {
@@ -2908,15 +2950,14 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
*dir = -EINVAL;
- if (len < sizeof(*p) ||
- verify_newpolicy_info(p))
+ if (len < policy_size || verify_newpolicy_info(_upi))
return NULL;
- nr = ((len - sizeof(*p)) / sizeof(*ut));
- if (validate_tmpl(nr, ut, p->sel.family))
+ nr = ((len - policy_size) / sizeof(*ut));
+ if (validate_tmpl(nr, ut, _upi->sel.family))
return NULL;
- if (p->dir > XFRM_POLICY_OUT)
+ if (_upi->dir > XFRM_POLICY_OUT)
return NULL;
xp = xfrm_policy_alloc(net, GFP_ATOMIC);
@@ -2925,11 +2966,11 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
return NULL;
}
- copy_from_user_policy(xp, p);
+ copy_from_user_policy(xp, _upi);
xp->type = XFRM_POLICY_TYPE_MAIN;
copy_templates(xp, ut, nr);
- *dir = p->dir;
+ *dir = _upi->dir;
return xp;
}
--
2.13.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox