From: Peter Oskolkov <hidden> Date: 2019-02-14 06:09:54
On error the skb should be freed. Tested with diff/steps
provided by David Ahern.
Reported-by: David Ahern <redacted>
Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c")
Signed-off-by: Peter Oskolkov <redacted>
---
net/core/lwt_bpf.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
@@ -179,18 +179,19 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)structnet_device*l3mdev=l3mdev_master_dev_rcu(skb_dst(skb)->dev);intoif=l3mdev?l3mdev->ifindex:0;structdst_entry*dst=NULL;+interr=-EAFNOSUPPORT;structsock*sk;structnet*net;boolipv4;-interr;if(skb->protocol==htons(ETH_P_IP))ipv4=true;elseif(skb->protocol==htons(ETH_P_IPV6))ipv4=false;else-return-EAFNOSUPPORT;+gotoerr;+err=-EINVAL;sk=sk_to_full_sk(skb->sk);if(sk){if(sk->sk_bound_dev_if)
@@ -216,7 +217,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)rt=ip_route_output_key(net,&fl4);if(IS_ERR(rt))-return-EINVAL;+gotoerr;dst=&rt->dst;}else{structipv6hdr*iph6=ipv6_hdr(skb);
@@ -231,12 +232,15 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)fl6.saddr=iph6->saddr;err=ipv6_stub->ipv6_dst_lookup(net,skb->sk,&dst,&fl6);-if(err||IS_ERR(dst))-return-EINVAL;+if(err||IS_ERR(dst)){+err=-EINVAL;+gotoerr;+}}if(unlikely(dst->error)){dst_release(dst);-return-EINVAL;+err=-EINVAL;+gotoerr;}/* Although skb header was reserved in bpf_lwt_push_ip_encap(), it
From: David Ahern <hidden> Date: 2019-02-14 18:11:57
On 2/13/19 11:09 PM, Peter Oskolkov wrote:
quoted hunk
On error the skb should be freed. Tested with diff/steps
provided by David Ahern.
Reported-by: David Ahern <redacted>
Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c")
Signed-off-by: Peter Oskolkov <redacted>
---
net/core/lwt_bpf.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
@@ -179,18 +179,19 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)structnet_device*l3mdev=l3mdev_master_dev_rcu(skb_dst(skb)->dev);intoif=l3mdev?l3mdev->ifindex:0;structdst_entry*dst=NULL;+interr=-EAFNOSUPPORT;structsock*sk;structnet*net;boolipv4;-interr;if(skb->protocol==htons(ETH_P_IP))ipv4=true;elseif(skb->protocol==htons(ETH_P_IPV6))ipv4=false;else-return-EAFNOSUPPORT;+gotoerr;+err=-EINVAL;sk=sk_to_full_sk(skb->sk);if(sk){if(sk->sk_bound_dev_if)
@@ -216,7 +217,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)rt=ip_route_output_key(net,&fl4);if(IS_ERR(rt))-return-EINVAL;+gotoerr;dst=&rt->dst;}else{structipv6hdr*iph6=ipv6_hdr(skb);
@@ -231,12 +232,15 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)fl6.saddr=iph6->saddr;err=ipv6_stub->ipv6_dst_lookup(net,skb->sk,&dst,&fl6);-if(err||IS_ERR(dst))-return-EINVAL;+if(err||IS_ERR(dst)){+err=-EINVAL;+gotoerr;+}}if(unlikely(dst->error)){dst_release(dst);-return-EINVAL;+err=-EINVAL;+gotoerr;}/* Although skb header was reserved in bpf_lwt_push_ip_encap(), it
EINVAL is a confusing return code; it is not an EINVAL problem, it is a
routing problem:
...
starting egress IPv4 encap test
ping: sendmsg: Invalid argument
FAIL: test_ping: 1
Versus returning the error from the lookup:
...
starting egress IPv4 encap test
ping: sendmsg: No route to host
FAIL: test_ping: 1
I figured it was a leaked skb.
Also, the test script needs to be updated as well with the negative
tests -- ie., toggle the route from a dev/gateway to a reject
(e.g.,unreachable) and back.
Also, don't exit on the first failure - run all of them.
Having the result line up is more user friendly. e.g.,
# ./fib_tests.sh
Single path route test
Start point
TEST: IPv4 fibmatch [ OK ]
TEST: IPv6 fibmatch [ OK ]
Nexthop device deleted
TEST: IPv4 fibmatch - no route [ OK ]
TEST: IPv6 fibmatch - no route [ OK ]
...
From: Peter Oskolkov <hidden> Date: 2019-02-14 18:42:55
On Thu, Feb 14, 2019 at 10:11 AM David Ahern [off-list ref] wrote:
On 2/13/19 11:09 PM, Peter Oskolkov wrote:
quoted
On error the skb should be freed. Tested with diff/steps
provided by David Ahern.
Reported-by: David Ahern <redacted>
Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c")
Signed-off-by: Peter Oskolkov <redacted>
---
net/core/lwt_bpf.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
@@ -179,18 +179,19 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)structnet_device*l3mdev=l3mdev_master_dev_rcu(skb_dst(skb)->dev);intoif=l3mdev?l3mdev->ifindex:0;structdst_entry*dst=NULL;+interr=-EAFNOSUPPORT;structsock*sk;structnet*net;boolipv4;-interr;if(skb->protocol==htons(ETH_P_IP))ipv4=true;elseif(skb->protocol==htons(ETH_P_IPV6))ipv4=false;else-return-EAFNOSUPPORT;+gotoerr;+err=-EINVAL;sk=sk_to_full_sk(skb->sk);if(sk){if(sk->sk_bound_dev_if)
@@ -216,7 +217,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)rt=ip_route_output_key(net,&fl4);if(IS_ERR(rt))-return-EINVAL;+gotoerr;dst=&rt->dst;}else{structipv6hdr*iph6=ipv6_hdr(skb);
@@ -231,12 +232,15 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)fl6.saddr=iph6->saddr;err=ipv6_stub->ipv6_dst_lookup(net,skb->sk,&dst,&fl6);-if(err||IS_ERR(dst))-return-EINVAL;+if(err||IS_ERR(dst)){+err=-EINVAL;+gotoerr;+}}if(unlikely(dst->error)){dst_release(dst);-return-EINVAL;+err=-EINVAL;+gotoerr;}/* Although skb header was reserved in bpf_lwt_push_ip_encap(), it
EINVAL is a confusing return code; it is not an EINVAL problem, it is a
routing problem:
Thanks, David! Sent a v2 of the patch.
quoted hunk
...
starting egress IPv4 encap test
ping: sendmsg: Invalid argument
FAIL: test_ping: 1
Versus returning the error from the lookup:
...
starting egress IPv4 encap test
ping: sendmsg: No route to host
FAIL: test_ping: 1
I figured it was a leaked skb.
Also, the test script needs to be updated as well with the negative
tests -- ie., toggle the route from a dev/gateway to a reject
(e.g.,unreachable) and back.
Also, don't exit on the first failure - run all of them.
I'll refactor the test as you suggest here
when I add VRF and GRO tests in a couple of weeks, if this is OK.
Having the result line up is more user friendly. e.g.,
# ./fib_tests.sh
Single path route test
Start point
TEST: IPv4 fibmatch [ OK ]
TEST: IPv6 fibmatch [ OK ]
Nexthop device deleted
TEST: IPv4 fibmatch - no route [ OK ]
TEST: IPv6 fibmatch - no route [ OK ]
...
From: David Ahern <hidden> Date: 2019-02-14 19:10:50
On 2/14/19 11:42 AM, Peter Oskolkov wrote:
I'll refactor the test as you suggest here
when I add VRF and GRO tests in a couple of weeks, if this is OK.
IMO, the tests should go in with the feature, not a release later. If we
are at -rc6 this week then you might get next week as well.
The unreachable toggle is a fairly quick integration. GRO really should
also get in the same cycle as the feature. Preferably VRF tests as well
since you have the commands.
The pretty printing cleanup can be done later.
From: Peter Oskolkov <hidden> Date: 2019-02-14 19:28:31
On Thu, Feb 14, 2019 at 11:10 AM David Ahern [off-list ref] wrote:
On 2/14/19 11:42 AM, Peter Oskolkov wrote:
quoted
I'll refactor the test as you suggest here
when I add VRF and GRO tests in a couple of weeks, if this is OK.
IMO, the tests should go in with the feature, not a release later. If we
are at -rc6 this week then you might get next week as well.
The unreachable toggle is a fairly quick integration. GRO really should
also get in the same cycle as the feature. Preferably VRF tests as well
since you have the commands.
OK, I'll work on the negative tests and GRO first.