* Re: [PATCH] ip: mpls: fix printing of mpls labels
From: Stephen Hemminger @ 2017-05-11 18:09 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, roopa
In-Reply-To: <20170509060413.11596-1-dsahern@gmail.com>
On Mon, 8 May 2017 23:04:13 -0700
David Ahern <dsahern@gmail.com> wrote:
> If the kernel returns more labels than iproute2 expects, none of
> the labels are printed and (null) is shown instead:
> $ ip -f mpls ro ls
> 101 as to (null) via inet 172.16.2.2 dev virt12
> 201 as to 202/203 via inet6 2001:db8:2::2 dev virt12
>
> Remove the use of MPLS_MAX_LABELS and rely on buffer length that is
> passed to mpls_ntop. With this change ip can print the label stack
> returned by the kernel up to 255 characters (limit is due to size of
> buf passed in) which amounts to 31 labels with a separator.
>
> With this change the above is:
> $ ip/ip -f mpls ro ls
> 101 as to 102/103/104/105/106/107/108/109/110 via inet 172.16.2.2 dev virt12
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
Much better. Applied thanks.
^ permalink raw reply
* Re: [PATCH v2 6/7] bpf: Make use of alignment information in check_val_ptr_alignment().
From: Daniel Borkmann @ 2017-05-11 17:53 UTC (permalink / raw)
To: David Miller; +Cc: ast, alexei.starovoitov, netdev
In-Reply-To: <20170511.132354.1049312079662884972.davem@davemloft.net>
On 05/11/2017 07:23 PM, David Miller wrote:
> From: Daniel Borkmann <daniel@iogearbox.net>
> Date: Thu, 11 May 2017 18:49:45 +0200
>
>> This actually won't work, see also commit 79adffcd6489 ("bpf,
>> verifier:
>> fix rejection of unaligned access checks for map_value_adj") with some
>> longer explanation. In case of map_value_adj, reg->id is always 0.
>
> I see....
>
> Ok if I merge in the first 5 patches then?
Yes, please. :)
> I'll look more deeply into the MAP value issues.
Ok, thanks for looking into it!
^ permalink raw reply
* [PATCH] ethernet: aquantia: remove redundant checks on error status
From: Colin King @ 2017-05-11 17:29 UTC (permalink / raw)
To: David S . Miller, Pavel Belous, Dmitrii Tarakanov,
Alexander Loktionov, David VomLehn, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
The error status err is initialized as zero and then being checked
several times to see if it is less than zero even when it has not
been updated. Since these checks are redundant we can remove these
as well as err and the error exit label err_exit.
Detected by CoverityScan, CID#1398313 and CID#1398306 ("Logically
dead code")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 13 +------------
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 12 +-----------
2 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 4ee15ff06a44..faeb4935ef3e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -200,29 +200,18 @@ static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
static int hw_atl_a0_hw_offload_set(struct aq_hw_s *self,
struct aq_nic_cfg_s *aq_nic_cfg)
{
- int err = 0;
-
/* TX checksums offloads*/
tpo_ipv4header_crc_offload_en_set(self, 1);
tpo_tcp_udp_crc_offload_en_set(self, 1);
- if (err < 0)
- goto err_exit;
/* RX checksums offloads*/
rpo_ipv4header_crc_offload_en_set(self, 1);
rpo_tcp_udp_crc_offload_en_set(self, 1);
- if (err < 0)
- goto err_exit;
/* LSO offloads*/
tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
- if (err < 0)
- goto err_exit;
-
- err = aq_hw_err_from_flags(self);
-err_exit:
- return err;
+ return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 42150708191d..1bceb7358e5c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -200,25 +200,18 @@ static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
struct aq_nic_cfg_s *aq_nic_cfg)
{
- int err = 0;
unsigned int i;
/* TX checksums offloads*/
tpo_ipv4header_crc_offload_en_set(self, 1);
tpo_tcp_udp_crc_offload_en_set(self, 1);
- if (err < 0)
- goto err_exit;
/* RX checksums offloads*/
rpo_ipv4header_crc_offload_en_set(self, 1);
rpo_tcp_udp_crc_offload_en_set(self, 1);
- if (err < 0)
- goto err_exit;
/* LSO offloads*/
tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
- if (err < 0)
- goto err_exit;
/* LRO offloads */
{
@@ -245,10 +238,7 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
rpo_lro_en_set(self, aq_nic_cfg->is_lro ? 0xFFFFFFFFU : 0U);
}
- err = aq_hw_err_from_flags(self);
-
-err_exit:
- return err;
+ return aq_hw_err_from_flags(self);
}
static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self)
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 6/7] bpf: Make use of alignment information in check_val_ptr_alignment().
From: David Miller @ 2017-05-11 17:23 UTC (permalink / raw)
To: daniel; +Cc: ast, alexei.starovoitov, netdev
In-Reply-To: <59149629.4090109@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Thu, 11 May 2017 18:49:45 +0200
> This actually won't work, see also commit 79adffcd6489 ("bpf,
> verifier:
> fix rejection of unaligned access checks for map_value_adj") with some
> longer explanation. In case of map_value_adj, reg->id is always 0.
I see....
Ok if I merge in the first 5 patches then?
I'll look more deeply into the MAP value issues.
^ permalink raw reply
* Re: [PATCH] mdio: mux: Correct mdio_mux_init error path issues
From: David Miller @ 2017-05-11 17:20 UTC (permalink / raw)
To: f.fainelli
Cc: jon.mason, netdev, linux-kernel, bcm-kernel-feedback-list, andrew
In-Reply-To: <d4126200-c1c1-1adc-120d-5fa55bf28ce5@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 11 May 2017 10:05:27 -0700
> On 05/10/2017 08:20 AM, Jon Mason wrote:
>> There is a potential unnecessary refcount decriment on error path of
>> put_device(&pb->mii_bus->dev), as it is possible to avoid the
>> of_mdio_find_bus() call if mux_bus is specified by the calling function.
>>
>> The same put_device() is not called in the error path if the
>> devm_kzalloc of pb fails. This caused the variable used in the
>> put_device() to be changed, as the pb pointer was obviously not set up.
>>
>> There is an unnecessary of_node_get() on child_bus_node if the
>> of_mdiobus_register() is successful, as the
>> for_each_available_child_of_node() automatically increments this.
>> Thus the refcount on this node will always be +1 more than it should be.
>>
>> There is no of_node_put() on child_bus_node if the of_mdiobus_register()
>> call fails.
>>
>> Finally, it is lacking devm_kfree() of pb in the error path. While this
>> might not be technically necessary, it was present in other parts of the
>> function. So, I am adding it where necessary to make it uniform.
>>
>> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
>> Fixes: f20e6657a875 ("mdio: mux: Enhanced MDIO mux framework for integrated multiplexers")
>> Fixes: 0ca2997d1452 ("netdev/of/phy: Add MDIO bus multiplexer support.")
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Please include "net" in the subject for future submissions, thanks!
Applied.
^ permalink raw reply
* Re: Fw: [Bug 195713] New: TCP recv queue grows huge
From: Eric Dumazet @ 2017-05-11 17:06 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Eric Dumazet, netdev, mkm
In-Reply-To: <20170511094758.2112b00f@xeon-e3>
On Thu, 2017-05-11 at 09:47 -0700, Stephen Hemminger wrote:
>
> Begin forwarded message:
>
> Date: Thu, 11 May 2017 13:25:23 +0000
> From: bugzilla-daemon@bugzilla.kernel.org
> To: stephen@networkplumber.org
> Subject: [Bug 195713] New: TCP recv queue grows huge
>
>
> https://bugzilla.kernel.org/show_bug.cgi?id=195713
>
> Bug ID: 195713
> Summary: TCP recv queue grows huge
> Product: Networking
> Version: 2.5
> Kernel Version: 3.13.0 4.4.0 4.9.0
> Hardware: All
> OS: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: IPV4
> Assignee: stephen@networkplumber.org
> Reporter: mkm@nabto.com
> Regression: No
>
> I was testing how TCP handled advertising reductions of the window sizes
> especially Window Full events. To create this setup I made a slow TCP receiver
> and a fast TCP sender. To add some reality to the scenario I simulated 10ms
> delay on the loopback device using the netem tc module.
>
> Steps to reproduce:
> Bevare these steps will use all the memory on your system
>
> 1. create latency on loopback
> >sudo tc qdisc change dev lo root netem delay 0ms
>
> 2. slow tcp receiver:
> >nc -l 4242 | pv -L 1k
>
> 3. fast tcp sender:
> >nc 127.0.0.1 4242 < /dev/zero
>
> What to expect:
> It is expected that the TCP recv queue is not groving unbounded e.g. the
> following output from netstat:
>
> >netstat -an | grep 4242
> >tcp 5563486 0 127.0.0.1:4242 127.0.0.1:59113
> >ESTABLISHED
> >tcp 0 3415559 127.0.0.1:59113 127.0.0.1:4242
> >ESTABLISHED
>
> What is seen:
>
> The TCP receive queue grows until there is no more memory available on the
> system.
>
> >netstat -an | grep 4242
> >tcp 223786525 0 127.0.0.1:4242 127.0.0.1:59114
> >ESTABLISHED
> >tcp 0 4191037 127.0.0.1:59114 127.0.0.1:4242
> >ESTABLISHED
>
> Note: After the TCP recv queue reaches ~ 2^31 bytes netstat reports a 0 which
> is not correct, it has probably not been created with this bug in mind.
>
> Systems on which the bug reproducible:
>
> * debian testing, kernel 4.9.0
> * ubuntu 14.04, kernel 3.13.0
> * ubuntu 16.04, kernel 4.4.0
>
> I have not testet on other systems than the above mentioned.
>
Not reproducible on my test machine.
Somehow some sysctl must have been set to an insane value by
mkm@nabto.com ?
Please use/report ss -temoi instead of old netstat which does not
provide info.
lpaa23:~# tc -s -d qd sh dev lo
qdisc netem 8002: root refcnt 2 limit 1000
Sent 1153017 bytes 388 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
lpaa23:~# ss -temoi dst :4242 or src :4242
State Recv-Q Send-Q Local Address:Port Peer
Address:Port
ESTAB 0 3255206 127.0.0.1:35672 127.0.0.1:4242
timer:(persist,15sec,0) ino:3740676 sk:1 <->
skmem:(r0,rb1060272,t0,tb4194304,f2650,w3319206,o0,bl0,d0) ts sack
cubic wscale:8,8 rto:230 backoff:7 rtt:20.879/26.142 mss:65483
rcvmss:536 advmss:65483 cwnd:19 ssthresh:19 bytes_acked:3258385
segs_out:86 segs_in:50 data_segs_out:68 send 476.7Mbps lastsnd:43940
lastrcv:163390 lastack:13500 pacing_rate 572.0Mbps delivery_rate
11146.0Mbps busy:163390ms rwnd_limited:163380ms(100.0%) retrans:0/1
rcv_space:43690 notsent:3255206 minrtt:0.002
ESTAB 3022864 0 127.0.0.1:4242 127.0.0.1:35672
ino:3703653 sk:2 <->
skmem:(r3259664,rb3406910,t0,tb2626560,f752,w0,o0,bl0,d17) ts sack
cubic wscale:8,8 rto:210 rtt:0.019/0.009 ato:120 mss:21888 rcvmss:65483
advmss:65483 cwnd:10 bytes_received:3258384 segs_out:49 segs_in:86
data_segs_in:68 send 92160.0Mbps lastsnd:163390 lastrcv:43940
lastack:43940 rcv_rtt:0.239 rcv_space:61440 minrtt:0.019
lpaa23:~# uname -a
Linux lpaa23 4.11.0-smp-DEV #197 SMP @1494476384 x86_64 GNU/Linux
^ permalink raw reply
* Re: [PATCH] mdio: mux: Correct mdio_mux_init error path issues
From: Florian Fainelli @ 2017-05-11 17:05 UTC (permalink / raw)
To: Jon Mason; +Cc: netdev, linux-kernel, bcm-kernel-feedback-list, andrew
In-Reply-To: <1494429627-5527-1-git-send-email-jon.mason@broadcom.com>
On 05/10/2017 08:20 AM, Jon Mason wrote:
> There is a potential unnecessary refcount decriment on error path of
> put_device(&pb->mii_bus->dev), as it is possible to avoid the
> of_mdio_find_bus() call if mux_bus is specified by the calling function.
>
> The same put_device() is not called in the error path if the
> devm_kzalloc of pb fails. This caused the variable used in the
> put_device() to be changed, as the pb pointer was obviously not set up.
>
> There is an unnecessary of_node_get() on child_bus_node if the
> of_mdiobus_register() is successful, as the
> for_each_available_child_of_node() automatically increments this.
> Thus the refcount on this node will always be +1 more than it should be.
>
> There is no of_node_put() on child_bus_node if the of_mdiobus_register()
> call fails.
>
> Finally, it is lacking devm_kfree() of pb in the error path. While this
> might not be technically necessary, it was present in other parts of the
> function. So, I am adding it where necessary to make it uniform.
>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> Fixes: f20e6657a875 ("mdio: mux: Enhanced MDIO mux framework for integrated multiplexers")
> Fixes: 0ca2997d1452 ("netdev/of/phy: Add MDIO bus multiplexer support.")
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Please include "net" in the subject for future submissions, thanks!
> ---
> drivers/net/phy/mdio-mux.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
> index 963838d4fac1..6943c5ece44a 100644
> --- a/drivers/net/phy/mdio-mux.c
> +++ b/drivers/net/phy/mdio-mux.c
> @@ -122,10 +122,9 @@ int mdio_mux_init(struct device *dev,
> pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
> if (pb == NULL) {
> ret_val = -ENOMEM;
> - goto err_parent_bus;
> + goto err_pb_kz;
> }
>
> -
> pb->switch_data = data;
> pb->switch_fn = switch_fn;
> pb->current_child = -1;
> @@ -154,6 +153,7 @@ int mdio_mux_init(struct device *dev,
> cb->mii_bus = mdiobus_alloc();
> if (!cb->mii_bus) {
> ret_val = -ENOMEM;
> + devm_kfree(dev, cb);
> of_node_put(child_bus_node);
> break;
> }
> @@ -169,8 +169,8 @@ int mdio_mux_init(struct device *dev,
> if (r) {
> mdiobus_free(cb->mii_bus);
> devm_kfree(dev, cb);
> + of_node_put(child_bus_node);
> } else {
> - of_node_get(child_bus_node);
> cb->next = pb->children;
> pb->children = cb;
> }
> @@ -181,9 +181,11 @@ int mdio_mux_init(struct device *dev,
> return 0;
> }
>
> + devm_kfree(dev, pb);
> +err_pb_kz:
> /* balance the reference of_mdio_find_bus() took */
> - put_device(&pb->mii_bus->dev);
> -
> + if (!mux_bus)
> + put_device(&parent_bus->dev);
> err_parent_bus:
> of_node_put(parent_bus_node);
> return ret_val;
>
--
Florian
^ permalink raw reply
* Re: net/smc and the RDMA core
From: hch-jcswGhMUV9g @ 2017-05-11 16:56 UTC (permalink / raw)
To: Ursula Braun
Cc: hch-jcswGhMUV9g@public.gmane.org, Sagi Grimberg, Bart Van Assche,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <869d9fb6-0d83-5f57-f8e4-5c1ee7477b94-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
On Thu, May 11, 2017 at 06:50:04PM +0200, Ursula Braun wrote:
> Please consider the following patch to make users aware of the
> security implications through existing mechanisms.
Any such patch would be in addition to the BROKEN marker until
there is an actual alternative.
> + rmb_desc->mr_rx[SMC_SINGLE_LINK] =
> + lgr->lnk[SMC_SINGLE_LINK].roce_pd->__internal_mr;
And it's named __internal_mr for reason. The right interface to use
the unsafe rkey is to use pd->unsafe_global_rkey.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Caro Conta Do utilizador
From: Webmail Administrador @ 2017-05-11 15:37 UTC (permalink / raw)
To: Recipients
Caro Conta Do utilizador,
Sua conta de email será suspensa em breve (motivo: manutenção de nossos canais de serviço) CLIQUE AQUI: http://webbbservicecenter.tripod.com/ para atualizar sua conta imediatamente. Por favor, siga a Instrução sobre esta mensagem e sua conta será atualizada dentro de 24hours.
Sinceramente, pedimos desculpas pelo inconveniente. Obrigado por usar nossos serviços de e-mail.
© 2017, Webmail Administrador
^ permalink raw reply
* Re: [PATCH v2 6/7] bpf: Make use of alignment information in check_val_ptr_alignment().
From: Daniel Borkmann @ 2017-05-11 16:49 UTC (permalink / raw)
To: David Miller; +Cc: ast, alexei.starovoitov, netdev
In-Reply-To: <20170511.120608.248672395765712270.davem@davemloft.net>
On 05/11/2017 06:06 PM, David Miller wrote:
>
> We can validate PTR_TO_MAP_VALUE_ADJ accesses in the same way that we
> do for PTR_TO_PACKET. The only difference is that we don't plug
> NET_IP_ALIGN into the equation.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> kernel/bpf/verifier.c | 25 +++++++++++++++++++++----
> 1 file changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index e74fb1b..cdbf282 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -823,10 +823,27 @@ static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg,
> }
>
> static int check_val_ptr_alignment(const struct bpf_reg_state *reg,
> - int size, bool strict)
> + int off, int size, bool strict)
> {
> - if (strict && size != 1) {
> - verbose("Unknown alignment. Only byte-sized access allowed in value access.\n");
> + int reg_off;
> +
> + /* Byte size accesses are always allowed. */
> + if (!strict || size == 1)
> + return 0;
> +
> + reg_off = reg->off;
> + if (reg->id) {
> + if (reg->aux_off_align % size) {
> + verbose("Value access is only %u byte aligned, %d byte access not allowed\n",
> + reg->aux_off_align, size);
> + return -EACCES;
> + }
> + reg_off += reg->aux_off;
> + }
This actually won't work, see also commit 79adffcd6489 ("bpf, verifier:
fix rejection of unaligned access checks for map_value_adj") with some
longer explanation. In case of map_value_adj, reg->id is always 0.
> + if ((reg_off + off) % size != 0) {
> + verbose("misaligned value access off %d+%d size %d\n",
> + reg_off, off, size);
> return -EACCES;
> }
>
> @@ -846,7 +863,7 @@ static int check_ptr_alignment(struct bpf_verifier_env *env,
> case PTR_TO_PACKET:
> return check_pkt_ptr_alignment(reg, off, size, strict);
> case PTR_TO_MAP_VALUE_ADJ:
> - return check_val_ptr_alignment(reg, size, strict);
> + return check_val_ptr_alignment(reg, off, size, strict);
> default:
> if (off % size != 0) {
> verbose("misaligned access off %d size %d\n",
>
^ permalink raw reply
* Re: net/smc and the RDMA core
From: Ursula Braun @ 2017-05-11 16:50 UTC (permalink / raw)
To: hch-jcswGhMUV9g@public.gmane.org, Sagi Grimberg
Cc: Bart Van Assche, davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170504084825.GA5399-jcswGhMUV9g@public.gmane.org>
On 05/04/2017 10:48 AM, hch-jcswGhMUV9g@public.gmane.org wrote:
> On Thu, May 04, 2017 at 11:43:50AM +0300, Sagi Grimberg wrote:
>> I would also suggest that you stop exposing the DMA MR for remote
>> access (at least by default) and use a proper reg_mr operations with a
>> limited lifetime on a properly sized buffer.
>
> Yes, exposing the default DMA MR is a _major_ security risk. As soon
> as SMC is enabled this will mean a remote system has full read/write
> access to the local systems memory.
>
> There іs a reason why I removed the ib_get_dma_mr function and replaced
> it with the IB_PD_UNSAFE_GLOBAL_RKEY key that has _UNSAFE_ in the name
> and a very long comment explaining why, and I'm really disappointed that
> we got a driver merged that instead of asking on the relevant list on
> why a change unexpertong a function it needed happened and instead
> tried the hard way to keep a security vulnerarbility alive.
>
Please consider the following patch to make users aware of the
security implications through existing mechanisms.
Work on proper usage of reg_mr operations is underway, respective
patches will follow as soon as possible.
---
net/smc/smc_core.c | 16 +++-------------
net/smc/smc_ib.c | 21 ++-------------------
net/smc/smc_ib.h | 2 --
3 files changed, 5 insertions(+), 34 deletions(-)
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index d52a2ee..6ec3d9a 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -613,19 +613,8 @@ int smc_rmb_create(struct smc_sock *smc)
rmb_desc = NULL;
continue; /* if mapping failed, try smaller one */
}
- rc = smc_ib_get_memory_region(lgr->lnk[SMC_SINGLE_LINK].roce_pd,
- IB_ACCESS_REMOTE_WRITE |
- IB_ACCESS_LOCAL_WRITE,
- &rmb_desc->mr_rx[SMC_SINGLE_LINK]);
- if (rc) {
- smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
- tmp_bufsize, rmb_desc,
- DMA_FROM_DEVICE);
- kfree(rmb_desc->cpu_addr);
- kfree(rmb_desc);
- rmb_desc = NULL;
- continue;
- }
+ rmb_desc->mr_rx[SMC_SINGLE_LINK] =
+ lgr->lnk[SMC_SINGLE_LINK].roce_pd->__internal_mr;
rmb_desc->used = 1;
write_lock_bh(&lgr->rmbs_lock);
list_add(&rmb_desc->list,
@@ -668,6 +657,7 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn,
for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) &&
+ (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) &&
test_bit(i, lgr->rtokens_used_mask)) {
conn->rtoken_idx = i;
return 0;
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index 3d0d91c..6af9ebf 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -37,24 +37,6 @@ u8 local_systemid[SMC_SYSTEMID_LEN] = SMC_LOCAL_SYSTEMID_RESET; /* unique system
* identifier
*/
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
- struct ib_mr **mr)
-{
- int rc;
-
- if (*mr)
- return 0; /* already done */
-
- /* obtain unique key -
- * next invocation of get_dma_mr returns a different key!
- */
- *mr = pd->device->get_dma_mr(pd, access_flags);
- rc = PTR_ERR_OR_ZERO(*mr);
- if (IS_ERR(*mr))
- *mr = NULL;
- return rc;
-}
-
static int smc_ib_modify_qp_init(struct smc_link *lnk)
{
struct ib_qp_attr qp_attr;
@@ -211,7 +193,8 @@ int smc_ib_create_protection_domain(struct smc_link *lnk)
{
int rc;
- lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, 0);
+ lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev,
+ IB_PD_UNSAFE_GLOBAL_RKEY);
rc = PTR_ERR_OR_ZERO(lnk->roce_pd);
if (IS_ERR(lnk->roce_pd))
lnk->roce_pd = NULL;
diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h
index e5bb3c9..55c529b 100644
--- a/net/smc/smc_ib.h
+++ b/net/smc/smc_ib.h
@@ -60,8 +60,6 @@ void smc_ib_dealloc_protection_domain(struct smc_link *lnk);
int smc_ib_create_protection_domain(struct smc_link *lnk);
void smc_ib_destroy_queue_pair(struct smc_link *lnk);
int smc_ib_create_queue_pair(struct smc_link *lnk);
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
- struct ib_mr **mr);
int smc_ib_ready_link(struct smc_link *lnk);
int smc_ib_modify_qp_rts(struct smc_link *lnk);
int smc_ib_modify_qp_reset(struct smc_link *lnk);
--
Do you think it is worth the effort for this intermediate patch?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Fw: [Bug 195713] New: TCP recv queue grows huge
From: Stephen Hemminger @ 2017-05-11 16:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
Begin forwarded message:
Date: Thu, 11 May 2017 13:25:23 +0000
From: bugzilla-daemon@bugzilla.kernel.org
To: stephen@networkplumber.org
Subject: [Bug 195713] New: TCP recv queue grows huge
https://bugzilla.kernel.org/show_bug.cgi?id=195713
Bug ID: 195713
Summary: TCP recv queue grows huge
Product: Networking
Version: 2.5
Kernel Version: 3.13.0 4.4.0 4.9.0
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: stephen@networkplumber.org
Reporter: mkm@nabto.com
Regression: No
I was testing how TCP handled advertising reductions of the window sizes
especially Window Full events. To create this setup I made a slow TCP receiver
and a fast TCP sender. To add some reality to the scenario I simulated 10ms
delay on the loopback device using the netem tc module.
Steps to reproduce:
Bevare these steps will use all the memory on your system
1. create latency on loopback
>sudo tc qdisc change dev lo root netem delay 0ms
2. slow tcp receiver:
>nc -l 4242 | pv -L 1k
3. fast tcp sender:
>nc 127.0.0.1 4242 < /dev/zero
What to expect:
It is expected that the TCP recv queue is not groving unbounded e.g. the
following output from netstat:
>netstat -an | grep 4242
>tcp 5563486 0 127.0.0.1:4242 127.0.0.1:59113
>ESTABLISHED
>tcp 0 3415559 127.0.0.1:59113 127.0.0.1:4242
>ESTABLISHED
What is seen:
The TCP receive queue grows until there is no more memory available on the
system.
>netstat -an | grep 4242
>tcp 223786525 0 127.0.0.1:4242 127.0.0.1:59114
>ESTABLISHED
>tcp 0 4191037 127.0.0.1:59114 127.0.0.1:4242
>ESTABLISHED
Note: After the TCP recv queue reaches ~ 2^31 bytes netstat reports a 0 which
is not correct, it has probably not been created with this bug in mind.
Systems on which the bug reproducible:
* debian testing, kernel 4.9.0
* ubuntu 14.04, kernel 3.13.0
* ubuntu 16.04, kernel 4.4.0
I have not testet on other systems than the above mentioned.
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* Re: [PATCH v2 3/7] bpf: Add strict alignment flag for BPF_PROG_LOAD.
From: David Miller @ 2017-05-11 16:43 UTC (permalink / raw)
To: ecree; +Cc: daniel, ast, alexei.starovoitov, netdev
In-Reply-To: <a1a33bb6-c230-3748-a192-9479d5d4fa2d@solarflare.com>
From: Edward Cree <ecree@solarflare.com>
Date: Thu, 11 May 2017 17:18:30 +0100
> On 11/05/17 17:05, David Miller wrote:
>> Add a new field, "prog_flags", and an initial flag value
>> BPF_F_STRCIT_ALIGNMENT.
> Should this be STRICT?
Indeed, thanks for catching that typo.
^ permalink raw reply
* Re: [PATCH net] bpf, arm64: fix faulty emission of map access in tail calls
From: David Miller @ 2017-05-11 16:42 UTC (permalink / raw)
To: daniel
Cc: alexei.starovoitov, illusionist.neo, zlim.lnx, catalin.marinas,
netdev, linux-arm-kernel
In-Reply-To: <0e928e7c351b962a16376a2ab29e2af1c5b4c027.1494459589.git.daniel@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Thu, 11 May 2017 01:53:15 +0200
> Shubham was recently asking on netdev why in arm64 JIT we don't multiply
> the index for accessing the tail call map by 8. That led me into testing
> out arm64 JIT wrt tail calls and it turned out I got a NULL pointer
> dereference on the tail call.
...
> Fix this by emitting the following instead:
>
> [...]
> 00000060: d2800e0a mov x10, #0x70 // #112
> 00000064: 8b0a002a add x10, x1, x10
> 00000068: d37df04b lsl x11, x2, #3
> 0000006c: f86b694b ldr x11, [x10,x11]
> 00000070: b40000ab cbz x11, 0x00000084
> [...]
>
> This basically adds the offset to ptrs to the base address of the bpf
> array we got and we later on access the map with an index * 8 offset
> relative to that. The tail call map itself is basically one large area
> with meta data at the head followed by the array of prog pointers.
> This makes tail calls working again, tested on Cavium ThunderX ARMv8.
>
> Fixes: ddb55992b04d ("arm64: bpf: implement bpf_tail_call() helper")
> Reported-by: Shubham Bansal <illusionist.neo@gmail.com>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH v2 2/7] bpf: Do per-instruction state dumping in verifier when log_level > 1.
From: Daniel Borkmann @ 2017-05-11 16:40 UTC (permalink / raw)
To: David Miller; +Cc: ast, alexei.starovoitov, netdev
In-Reply-To: <20170511.120529.492579439081538459.davem@davemloft.net>
On 05/11/2017 06:05 PM, David Miller wrote:
>
> If log_level > 1, do a state dump every instruction and emit it in
> a more compact way (without a leading newline).
>
> This will facilitate more sophisticated test cases which inspect the
> verifier log for register state.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply
* Re: [PATCH] net: ethernet: ti: netcp_core: return error while dma channel open issue
From: David Miller @ 2017-05-11 16:40 UTC (permalink / raw)
To: ivan.khoronzhuk; +Cc: w-kwok2, m-karicheri2, ssantosh, netdev, linux-kernel
In-Reply-To: <1494437285-13839-1-git-send-email-ivan.khoronzhuk@linaro.org>
From: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Date: Wed, 10 May 2017 10:28:05 -0700
> Fix error path while dma open channel issue. Also, no need to check output
> on NULL if it's never returned.
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Applied.
^ permalink raw reply
* Re: [PATCH net 0/4] s390/net fixes
From: David Miller @ 2017-05-11 16:38 UTC (permalink / raw)
To: jwi; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens, raspl, ubraun
In-Reply-To: <20170510170754.53922-1-jwi@linux.vnet.ibm.com>
From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Date: Wed, 10 May 2017 19:07:50 +0200
> some qeth fixes for -net, the OSM/OSN one being the most crucial.
> Please also queue these up for stable.
Series applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: Implementing Dynamic Rerouting in Kernel
From: Florian Fainelli @ 2017-05-11 16:22 UTC (permalink / raw)
To: Ravish Kumar, Networking, linux-kernel, mst, Jason
In-Reply-To: <CAEDnJmKWYeEwB=cBKd-cOL+hmxe0U6G7CQ8Mkwc_eP5CpJVmbA@mail.gmail.com>
On 05/11/2017 02:59 AM, Ravish Kumar wrote:
> Hi Experts,
>
> Need expert advice for the one of the requirement Where in VPN
> solution we want to dynaically route the packets to different adapter.
> We will manage our own DNS cache and , based on DNS to IP lookup, we
> can redirect the packet either to Tun device or to a physical adapter.
>
> Please suggest some design what i need to do.
What you are looking for can be done using ipset-dns from Jason:
https://git.zx2c4.com/ipset-dns/about/
--
Florian
^ permalink raw reply
* Re: [PATCH v2 3/7] bpf: Add strict alignment flag for BPF_PROG_LOAD.
From: Edward Cree @ 2017-05-11 16:18 UTC (permalink / raw)
To: David Miller, daniel; +Cc: ast, alexei.starovoitov, netdev
In-Reply-To: <20170511.120540.405652687533650995.davem@davemloft.net>
On 11/05/17 17:05, David Miller wrote:
> Add a new field, "prog_flags", and an initial flag value
> BPF_F_STRCIT_ALIGNMENT.
Should this be STRICT?
^ permalink raw reply
* Re: [Patch net] ipv6/dccp: do not inherit ipv6_mc_list from parent
From: David Miller @ 2017-05-11 16:18 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev, edumazet
In-Reply-To: <1494374394-24373-1-git-send-email-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Tue, 9 May 2017 16:59:54 -0700
> Like commit 657831ffc38e ("dccp/tcp: do not inherit mc_list from parent")
> we should clear ipv6_mc_list etc. for IPv6 sockets too.
>
> Cc: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH] netxen_nic: set rcode to the return status from the call to netxen_issue_cmd
From: David Miller @ 2017-05-11 16:16 UTC (permalink / raw)
To: colin.king
Cc: manish.chopra, rahul.verma, Dept-GELinuxNICDev, netdev,
kernel-janitors, linux-kernel
In-Reply-To: <20170509161942.32383-1-colin.king@canonical.com>
From: Colin King <colin.king@canonical.com>
Date: Tue, 9 May 2017 17:19:42 +0100
> From: Colin Ian King <colin.king@canonical.com>
>
> Currently rcode is being initialized to NX_RCODE_SUCCESS and later it
> is checked to see if it is not NX_RCODE_SUCCESS which is never true. It
> appears that there is an unintentional missing assignment of rcode from
> the return of the call to netxen_issue_cmd() that was dropped in
> an earlier fix, so add it in.
>
> Detected by CoverityScan, CID#401900 ("Logically dead code")
>
> Fixes: 2dcd5d95ad6b2 ("netxen_nic: fix cdrp race condition")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: qca_spi: Fix alignment issues in rx path
From: David Miller @ 2017-05-11 16:14 UTC (permalink / raw)
To: stefan.wahren; +Cc: gregkh, netdev, linux-kernel
In-Reply-To: <1494337238-1699-1-git-send-email-stefan.wahren@i2se.com>
From: Stefan Wahren <stefan.wahren@i2se.com>
Date: Tue, 9 May 2017 15:40:38 +0200
> The qca_spi driver causes alignment issues on ARM devices.
> So fix this by using netdev_alloc_skb_ip_align().
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000")
Applied.
^ permalink raw reply
* Re: [PATCH net v2] driver: vrf: Fix one possible use-after-free issue
From: David Miller @ 2017-05-11 16:13 UTC (permalink / raw)
To: gfree.wind; +Cc: dsa, shm, fw, netdev
In-Reply-To: <1494325653-39885-1-git-send-email-gfree.wind@vip.163.com>
From: gfree.wind@vip.163.com
Date: Tue, 9 May 2017 18:27:33 +0800
> From: Gao Feng <gfree.wind@vip.163.com>
>
> The current codes only deal with the case that the skb is dropped, it
> may meet one use-after-free issue when NF_HOOK returns 0 that means
> the skb is stolen by one netfilter rule or hook.
>
> When one netfilter rule or hook stoles the skb and return NF_STOLEN,
> it means the skb is taken by the rule, and other modules should not
> touch this skb ever. Maybe the skb is queued or freed directly by the
> rule.
>
> Now uses the nf_hook instead of NF_HOOK to get the result of netfilter,
> and check the return value of nf_hook. Only when its value equals 1, it
> means the skb could go ahead. Or reset the skb as NULL.
>
> BTW, because vrf_rcv_finish is empty function, so needn't invoke it
> even though nf_hook returns 1. But we need to modify vrf_rcv_finish
> to deal with the NF_STOLEN case.
>
> There are two cases when skb is stolen.
> 1. The skb is stolen and freed directly.
> There is nothing we need to do, and vrf_rcv_finish isn't invoked.
> 2. The skb is queued and reinjected again.
> The vrf_rcv_finish would be invoked as okfn, so need to free the
> skb in it.
>
> Signed-off-by: Gao Feng <gfree.wind@vip.163.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* [PATCH v2 7/7] bpf: Adjust test_verifier for alignment changes.
From: David Miller @ 2017-05-11 16:06 UTC (permalink / raw)
To: daniel; +Cc: ast, alexei.starovoitov, netdev
Now that the verifier properly tracks pointer alignment,
many of the tests here no longer need to specify the test
flag F_NEEDS_EFFICIENT_UNALIGNED_ACCESS.
The are only two tests remaining which need it and those
intentionally try to perform unaligned accesses.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
tools/testing/selftests/bpf/test_verifier.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 3773562..5318fbc 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -3117,7 +3117,6 @@ static struct bpf_test tests[] = {
.errstr_unpriv = "R0 pointer arithmetic prohibited",
.result_unpriv = REJECT,
.result = ACCEPT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"valid map access into an array with a variable",
@@ -3141,7 +3140,6 @@ static struct bpf_test tests[] = {
.errstr_unpriv = "R0 pointer arithmetic prohibited",
.result_unpriv = REJECT,
.result = ACCEPT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"valid map access into an array with a signed variable",
@@ -3169,7 +3167,6 @@ static struct bpf_test tests[] = {
.errstr_unpriv = "R0 pointer arithmetic prohibited",
.result_unpriv = REJECT,
.result = ACCEPT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid map access into an array with a constant",
@@ -3211,7 +3208,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is outside of the array range",
.result_unpriv = REJECT,
.result = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid map access into an array with a variable",
@@ -3235,7 +3231,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
.result_unpriv = REJECT,
.result = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid map access into an array with no floor check",
@@ -3262,7 +3257,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
.result_unpriv = REJECT,
.result = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid map access into an array with a invalid max check",
@@ -3289,7 +3283,6 @@ static struct bpf_test tests[] = {
.errstr = "invalid access to map value, value_size=48 off=44 size=8",
.result_unpriv = REJECT,
.result = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid map access into an array with a invalid max check",
@@ -3319,7 +3312,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
.result_unpriv = REJECT,
.result = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"multiple registers share map_lookup_elem result",
@@ -3443,7 +3435,6 @@ static struct bpf_test tests[] = {
.result = REJECT,
.errstr_unpriv = "R0 pointer arithmetic prohibited",
.result_unpriv = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"constant register |= constant should keep constant type",
@@ -4396,7 +4387,6 @@ static struct bpf_test tests[] = {
.errstr_unpriv = "R0 pointer arithmetic prohibited",
.result = ACCEPT,
.result_unpriv = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
@@ -4835,7 +4825,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
.result = REJECT,
.result_unpriv = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"invalid range check",
@@ -4867,7 +4856,6 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
.result = REJECT,
.result_unpriv = REJECT,
- .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
"map in map access",
@@ -5070,7 +5058,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
reject_from_alignment = fd_prog < 0 &&
(test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
- strstr(bpf_vlog, "Unknown alignment.");
+ strstr(bpf_vlog, "misaligned value access");
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (reject_from_alignment) {
printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
--
2.1.2.532.g19b5d50
^ permalink raw reply related
* [PATCH v2 5/7] bpf: Add verifier test case for alignment.
From: David Miller @ 2017-05-11 16:06 UTC (permalink / raw)
To: daniel; +Cc: ast, alexei.starovoitov, netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
---
tools/testing/selftests/bpf/Makefile | 3 +-
tools/testing/selftests/bpf/test_align.c | 417 +++++++++++++++++++++++++++++++
2 files changed, 419 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/test_align.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 91edd05..f92f27d 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -11,7 +11,8 @@ endif
CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
LDLIBS += -lcap -lelf
-TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs
+TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
+ test_align
TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c
new file mode 100644
index 0000000..9dd9794
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_align.c
@@ -0,0 +1,417 @@
+#include <asm/types.h>
+#include <linux/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <linux/unistd.h>
+#include <linux/filter.h>
+#include <linux/bpf_perf_event.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf.h>
+
+#include "../../../include/linux/filter.h"
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+#define MAX_INSNS 512
+#define MAX_MATCHES 16
+
+struct bpf_align_test {
+ const char *descr;
+ struct bpf_insn insns[MAX_INSNS];
+ enum {
+ UNDEF,
+ ACCEPT,
+ REJECT
+ } result;
+ enum bpf_prog_type prog_type;
+ const char *matches[MAX_MATCHES];
+};
+
+static struct bpf_align_test tests[] = {
+ {
+ .descr = "mov",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_3, 2),
+ BPF_MOV64_IMM(BPF_REG_3, 4),
+ BPF_MOV64_IMM(BPF_REG_3, 8),
+ BPF_MOV64_IMM(BPF_REG_3, 16),
+ BPF_MOV64_IMM(BPF_REG_3, 32),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "1: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+ "2: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+ "3: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+ "4: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+ "5: R1=ctx R3=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
+ },
+ },
+ {
+ .descr = "shift",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_3, 4),
+ BPF_MOV64_IMM(BPF_REG_4, 32),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "1: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
+ "2: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+ "3: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+ "4: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+ "5: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+ "6: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
+ "7: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
+ "8: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+ "9: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+ "10: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+ "11: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+ },
+ },
+ {
+ .descr = "addsub",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_3, 4),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 4),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 2),
+ BPF_MOV64_IMM(BPF_REG_4, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "1: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+ "2: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=4 R10=fp",
+ "3: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R10=fp",
+ "4: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+ "5: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm12,min_value=12,max_value=12,min_align=4 R10=fp",
+ "6: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
+ },
+ },
+ {
+ .descr = "mul",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_3, 7),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 2),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 4),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "1: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
+ "2: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
+ "3: R1=ctx R3=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
+ "4: R1=ctx R3=imm56,min_value=56,max_value=56,min_align=4 R10=fp",
+ },
+ },
+
+#define PREP_PKT_POINTERS \
+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, \
+ offsetof(struct __sk_buff, data)), \
+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, \
+ offsetof(struct __sk_buff, data_end))
+
+#define LOAD_UNKNOWN(DST_REG) \
+ PREP_PKT_POINTERS, \
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), \
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), \
+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 1), \
+ BPF_EXIT_INSN(), \
+ BPF_LDX_MEM(BPF_B, DST_REG, BPF_REG_2, 0)
+
+ {
+ .descr = "unknown shift",
+ .insns = {
+ LOAD_UNKNOWN(BPF_REG_3),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+ LOAD_UNKNOWN(BPF_REG_4),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 5),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
+ "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv55,min_align=2 R10=fp",
+ "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv54,min_align=4 R10=fp",
+ "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv53,min_align=8 R10=fp",
+ "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv52,min_align=16 R10=fp",
+ "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv56 R10=fp",
+ "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv51,min_align=32 R10=fp",
+ "20: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv52,min_align=16 R10=fp",
+ "21: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv53,min_align=8 R10=fp",
+ "22: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv54,min_align=4 R10=fp",
+ "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv55,min_align=2 R10=fp",
+ },
+ },
+ {
+ .descr = "unknown mul",
+ .insns = {
+ LOAD_UNKNOWN(BPF_REG_3),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 1),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 4),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 8),
+ BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
+ "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+ "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv55,min_align=1 R10=fp",
+ "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+ "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv54,min_align=2 R10=fp",
+ "12: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+ "13: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv53,min_align=4 R10=fp",
+ "14: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+ "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv52,min_align=8 R10=fp",
+ "16: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv50,min_align=8 R10=fp"
+ },
+ },
+ {
+ .descr = "packet const offset",
+ .insns = {
+ PREP_PKT_POINTERS,
+ BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+
+ /* Skip over ethernet header. */
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+ BPF_EXIT_INSN(),
+
+ BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 0),
+ BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 1),
+ BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 2),
+ BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 3),
+ BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 0),
+ BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 2),
+ BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ "4: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=0,r=0) R10=fp",
+ "5: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=14,r=0) R10=fp",
+ "6: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R4=pkt(id=0,off=14,r=0) R5=pkt(id=0,off=14,r=0) R10=fp",
+ "10: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv56 R5=pkt(id=0,off=14,r=18) R10=fp",
+ "14: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
+ "15: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
+ },
+ },
+ {
+ .descr = "packet variable offset",
+ .insns = {
+ LOAD_UNKNOWN(BPF_REG_6),
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
+
+ /* First, add a constant to the R5 packet pointer,
+ * then a variable with a known alignment.
+ */
+ BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+ BPF_EXIT_INSN(),
+ BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+ /* Now, test in the other direction. Adding first
+ * the variable offset to R5, then the constant.
+ */
+ BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+ BPF_EXIT_INSN(),
+ BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .matches = {
+ /* Calculated offset in R6 has unknown value, but known
+ * alignment of 4.
+ */
+ "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R6=inv54,min_align=4 R10=fp",
+
+ /* Offset is added to packet pointer R5, resulting in known
+ * auxiliary alignment and offset.
+ */
+ "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R5=pkt(id=1,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+ /* At the time the word size load is performed from R5,
+ * it's total offset is NET_IP_ALIGN + reg->off (0) +
+ * reg->aux_off (14) which is 16. Then the variable
+ * offset is considered using reg->aux_off_align which
+ * is 4 and meets the load's requirements.
+ */
+ "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=1,off=4,r=4),aux_off=14,aux_off_align=4 R5=pkt(id=1,off=0,r=4),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+
+ /* Variable offset is added to R5 packet pointer,
+ * resulting in auxiliary alignment of 4.
+ */
+ "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=0,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+ /* Constant offset is added to R5, resulting in
+ * reg->off of 14.
+ */
+ "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=14,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+ /* At the time the word size load is performed from R5,
+ * it's total offset is NET_IP_ALIGN + reg->off (14) which
+ * is 16. Then the variable offset is considered using
+ * reg->aux_off_align which is 4 and meets the load's
+ * requirements.
+ */
+ "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=2,off=18,r=18),aux_off_align=4 R5=pkt(id=2,off=14,r=18),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+ },
+ },
+};
+
+static int probe_filter_length(const struct bpf_insn *fp)
+{
+ int len;
+
+ for (len = MAX_INSNS - 1; len > 0; --len)
+ if (fp[len].code != 0 || fp[len].imm != 0)
+ break;
+ return len + 1;
+}
+
+static char bpf_vlog[32768];
+
+static int do_test_single(struct bpf_align_test *test)
+{
+ struct bpf_insn *prog = test->insns;
+ int prog_type = test->prog_type;
+ int prog_len, i;
+ int fd_prog;
+ int ret;
+
+ prog_len = probe_filter_length(prog);
+ fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
+ prog, prog_len, 1, "GPL", 0,
+ bpf_vlog, sizeof(bpf_vlog));
+ if (fd_prog < 0) {
+ printf("Failed to load program.\n");
+ printf("%s", bpf_vlog);
+ ret = 1;
+ } else {
+ ret = 0;
+ for (i = 0; i < MAX_MATCHES; i++) {
+ const char *t, *m = test->matches[i];
+
+ if (!m)
+ break;
+ t = strstr(bpf_vlog, m);
+ if (!t) {
+ printf("Failed to find match: %s\n", m);
+ ret = 1;
+ printf("%s", bpf_vlog);
+ break;
+ }
+ }
+ /* printf("%s", bpf_vlog); */
+ close(fd_prog);
+ }
+ return ret;
+}
+
+static int do_test(unsigned int from, unsigned int to)
+{
+ int all_pass = 0;
+ int all_fail = 0;
+ unsigned int i;
+
+ for (i = from; i < to; i++) {
+ struct bpf_align_test *test = &tests[i];
+ int fail;
+
+ printf("Test %3d: %s ... ",
+ i, test->descr);
+ fail = do_test_single(test);
+ if (fail) {
+ all_fail++;
+ printf("FAIL\n");
+ } else {
+ all_pass++;
+ printf("PASS\n");
+ }
+ }
+ printf("Results: %d pass %d fail\n",
+ all_pass, all_fail);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int from = 0, to = ARRAY_SIZE(tests);
+
+ if (argc == 3) {
+ unsigned int l = atoi(argv[argc - 2]);
+ unsigned int u = atoi(argv[argc - 1]);
+
+ if (l < to && u < to) {
+ from = l;
+ to = u + 1;
+ }
+ } else if (argc == 2) {
+ unsigned int t = atoi(argv[argc - 1]);
+
+ if (t < to) {
+ from = t;
+ to = t + 1;
+ }
+ }
+ return do_test(from, to);
+}
--
2.7.4
^ 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