All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue
@ 2014-03-29  1:27 Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 1/3] ipv6: tcp_ipv6 do some cleanup Wangyufen
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Wangyufen @ 2014-03-29  1:27 UTC (permalink / raw)
  To: davem, netdev; +Cc: kuznet, Wang Yufen

From: Wang Yufen <wangyufen@huawei.com>

Wang Yufen (3):
  ipv6: tcp_ipv6 do some cleanup
  ipv6: reuse rt6_need_strict
  ipv6: tcp_ipv6 policy route issue

v4: use rt6_need_strict to check whether the oif directly
    assigned to iif
v5: Move the whole rt6_need_strict as static inline into 
    ip6_route.h, instade of just delete static.

 include/net/ip6_route.h | 5 +++++
 net/ipv6/route.c        | 6 ------
 net/ipv6/ip6_fib.c | 42 +++---
 3 file changed, 27 insertions(+), 26 deletions(-)

 -- 
1.7.12

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next v6 1/3] ipv6: tcp_ipv6 do some cleanup
  2014-03-29  1:27 [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue Wangyufen
@ 2014-03-29  1:27 ` Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 2/3] ipv6: reuse rt6_need_strict Wangyufen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Wangyufen @ 2014-03-29  1:27 UTC (permalink / raw)
  To: davem, netdev; +Cc: kuznet, Wang Yufen

From: Wang Yufen <wangyufen@huawei.com>


Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
 net/ipv6/tcp_ipv6.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3277680..10b7c04 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -39,7 +39,7 @@
 #include <linux/ipsec.h>
 #include <linux/times.h>
 #include <linux/slab.h>
-
+#include <linux/uaccess.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/random.h>
@@ -65,8 +65,6 @@
 #include <net/tcp_memcontrol.h>
 #include <net/busy_poll.h>
 
-#include <asm/uaccess.h>
-
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
@@ -532,8 +530,8 @@ static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
 	return tcp_v6_md5_do_lookup(sk, &inet_rsk(req)->ir_v6_rmt_addr);
 }
 
-static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
-				  int optlen)
+static int tcp_v6_parse_md5_keys(struct sock *sk, char __user *optval,
+				 int optlen)
 {
 	struct tcp_md5sig cmd;
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr;
@@ -717,7 +715,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
 	.send_ack	=	tcp_v6_reqsk_send_ack,
 	.destructor	=	tcp_v6_reqsk_destructor,
 	.send_reset	=	tcp_v6_send_reset,
-	.syn_ack_timeout = 	tcp_syn_ack_timeout,
+	.syn_ack_timeout =	tcp_syn_ack_timeout,
 };
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -1261,7 +1259,8 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
 #ifdef CONFIG_TCP_MD5SIG
 	/* Copy over the MD5 key from the original socket */
-	if ((key = tcp_v6_md5_do_lookup(sk, &newsk->sk_v6_daddr)) != NULL) {
+	key = tcp_v6_md5_do_lookup(sk, &newsk->sk_v6_daddr);
+	if (key != NULL) {
 		/* We're using one, so create a matching key
 		 * on the newsk structure. If we fail to get
 		 * memory, then we end up not copying the key
@@ -1305,9 +1304,8 @@ static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
 					      &ipv6_hdr(skb)->saddr,
 					      &ipv6_hdr(skb)->daddr, 0));
 
-	if (skb->len <= 76) {
+	if (skb->len <= 76)
 		return __skb_checksum_complete(skb);
-	}
 	return 0;
 }
 
@@ -1337,7 +1335,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 		return tcp_v4_do_rcv(sk, skb);
 
 #ifdef CONFIG_TCP_MD5SIG
-	if (tcp_v6_inbound_md5_hash (sk, skb))
+	if (tcp_v6_inbound_md5_hash(sk, skb))
 		goto discard;
 #endif
 
@@ -1604,7 +1602,8 @@ do_time_wait:
 		break;
 	case TCP_TW_RST:
 		goto no_tcp_socket;
-	case TCP_TW_SUCCESS:;
+	case TCP_TW_SUCCESS:
+		;
 	}
 	goto discard_it;
 }
@@ -1649,7 +1648,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb)
 static struct timewait_sock_ops tcp6_timewait_sock_ops = {
 	.twsk_obj_size	= sizeof(struct tcp6_timewait_sock),
 	.twsk_unique	= tcp_twsk_unique,
-	.twsk_destructor= tcp_twsk_destructor,
+	.twsk_destructor = tcp_twsk_destructor,
 };
 
 static const struct inet_connection_sock_af_ops ipv6_specific = {
@@ -1683,7 +1682,6 @@ static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
 /*
  *	TCP over IPv4 via INET6 API
  */
-
 static const struct inet_connection_sock_af_ops ipv6_mapped = {
 	.queue_xmit	   = ip_queue_xmit,
 	.send_check	   = tcp_v4_send_check,
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next v6 2/3] ipv6: reuse rt6_need_strict
  2014-03-29  1:27 [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 1/3] ipv6: tcp_ipv6 do some cleanup Wangyufen
@ 2014-03-29  1:27 ` Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue Wangyufen
  2014-03-31 20:16 ` [PATCH net-next v6 0/3] " David Miller
  3 siblings, 0 replies; 8+ messages in thread
From: Wangyufen @ 2014-03-29  1:27 UTC (permalink / raw)
  To: davem, netdev; +Cc: kuznet, Wang Yufen

From: Wang Yufen <wangyufen@huawei.com>

Move the whole rt6_need_strict as static inline into ip6_route.h, 
so that it can be reused

Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
 include/net/ip6_route.h | 5 +++++
 net/ipv6/route.c        | 6 ------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 00e3f12..33e8694 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -51,6 +51,11 @@ static inline unsigned int rt6_flags2srcprefs(int flags)
 	return (flags >> 3) & 7;
 }
 
+static inline bool rt6_need_strict(const struct in6_addr *daddr)
+{
+	return ipv6_addr_type(daddr) &
+		(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
+}
 
 void ip6_route_input(struct sk_buff *skb);
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b93ae6a..5015c50 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -374,12 +374,6 @@ static bool rt6_check_expired(const struct rt6_info *rt)
 	return false;
 }
 
-static bool rt6_need_strict(const struct in6_addr *daddr)
-{
-	return ipv6_addr_type(daddr) &
-		(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
-}
-
 /* Multipath route selection:
  *   Hash based function using packet header and flowlabel.
  * Adapted from fib_info_hashfn()
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue
  2014-03-29  1:27 [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 1/3] ipv6: tcp_ipv6 do some cleanup Wangyufen
  2014-03-29  1:27 ` [PATCH net-next v6 2/3] ipv6: reuse rt6_need_strict Wangyufen
@ 2014-03-29  1:27 ` Wangyufen
  2014-04-10  9:23   ` Lorenzo Colitti
  2014-03-31 20:16 ` [PATCH net-next v6 0/3] " David Miller
  3 siblings, 1 reply; 8+ messages in thread
From: Wangyufen @ 2014-03-29  1:27 UTC (permalink / raw)
  To: davem, netdev; +Cc: kuznet, Wang Yufen

From: Wang Yufen <wangyufen@huawei.com>

The issue raises when adding policy route, specify a particular
NIC as oif, the policy route did not take effect. The reason is
that fl6.oif is not set and route map failed. From the 
tcp_v6_send_response function, if the binding address is linklocal,
fl6.oif is set, but not for global address.

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
 net/ipv6/tcp_ipv6.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 10b7c04..5ca56ce 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -726,7 +726,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
 #endif
 
 static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
-				 u32 tsval, u32 tsecr,
+				 u32 tsval, u32 tsecr, int oif,
 				 struct tcp_md5sig_key *key, int rst, u8 tclass,
 				 u32 label)
 {
@@ -798,8 +798,10 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
 	__tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);
 
 	fl6.flowi6_proto = IPPROTO_TCP;
-	if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
+	if (rt6_need_strict(&fl6.daddr) || !oif)
 		fl6.flowi6_oif = inet6_iif(skb);
+	else
+		fl6.flowi6_oif = oif;
 	fl6.fl6_dport = t1->dest;
 	fl6.fl6_sport = t1->source;
 	security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
@@ -833,6 +835,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 	int genhash;
 	struct sock *sk1 = NULL;
 #endif
+	int oif;
 
 	if (th->rst)
 		return;
@@ -876,7 +879,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 		ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
 			  (th->doff << 2);
 
-	tcp_v6_send_response(skb, seq, ack_seq, 0, 0, 0, key, 1, 0, 0);
+	oif = sk ? sk->sk_bound_dev_if : 0;
+	tcp_v6_send_response(skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0);
 
 #ifdef CONFIG_TCP_MD5SIG
 release_sk1:
@@ -888,11 +892,11 @@ release_sk1:
 }
 
 static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
-			    u32 win, u32 tsval, u32 tsecr,
+			    u32 win, u32 tsval, u32 tsecr, int oif,
 			    struct tcp_md5sig_key *key, u8 tclass,
 			    u32 label)
 {
-	tcp_v6_send_response(skb, seq, ack, win, tsval, tsecr, key, 0, tclass,
+	tcp_v6_send_response(skb, seq, ack, win, tsval, tsecr, oif, key, 0, tclass,
 			     label);
 }
 
@@ -904,7 +908,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
 	tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 			tcp_time_stamp + tcptw->tw_ts_offset,
-			tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw),
+			tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw),
 			tw->tw_tclass, (tw->tw_flowlabel << 12));
 
 	inet_twsk_put(tw);
@@ -914,7 +918,7 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 				  struct request_sock *req)
 {
 	tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1,
-			req->rcv_wnd, tcp_time_stamp, req->ts_recent,
+			req->rcv_wnd, tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if,
 			tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
 			0, 0);
 }
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue
  2014-03-29  1:27 [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue Wangyufen
                   ` (2 preceding siblings ...)
  2014-03-29  1:27 ` [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue Wangyufen
@ 2014-03-31 20:16 ` David Miller
  3 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2014-03-31 20:16 UTC (permalink / raw)
  To: wangyufen; +Cc: netdev, kuznet

From: Wangyufen <wangyufen@huawei.com>
Date: Sat, 29 Mar 2014 09:27:28 +0800

> From: Wang Yufen <wangyufen@huawei.com>
> 
> Wang Yufen (3):
>   ipv6: tcp_ipv6 do some cleanup
>   ipv6: reuse rt6_need_strict
>   ipv6: tcp_ipv6 policy route issue
> 
> v4: use rt6_need_strict to check whether the oif directly
>     assigned to iif
> v5: Move the whole rt6_need_strict as static inline into 
>     ip6_route.h, instade of just delete static.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue
  2014-03-29  1:27 ` [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue Wangyufen
@ 2014-04-10  9:23   ` Lorenzo Colitti
  2014-04-10 21:57     ` Hannes Frederic Sowa
  0 siblings, 1 reply; 8+ messages in thread
From: Lorenzo Colitti @ 2014-04-10  9:23 UTC (permalink / raw)
  To: Wangyufen; +Cc: David Miller, netdev, Alexey Kuznetsov

On Sat, Mar 29, 2014 at 10:27 AM, Wangyufen <wangyufen@huawei.com> wrote:
> The issue raises when adding policy route, specify a particular
> NIC as oif, the policy route did not take effect. The reason is
> that fl6.oif is not set and route map failed. From the
> tcp_v6_send_response function, if the binding address is linklocal,
> fl6.oif is set, but not for global address.
>
> [...]
>
>         fl6.flowi6_proto = IPPROTO_TCP;
> -       if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
> +       if (rt6_need_strict(&fl6.daddr) || !oif)
>                 fl6.flowi6_oif = inet6_iif(skb);

> +       else
> +               fl6.flowi6_oif = oif;

Shouldn't this be && !oif instead of || !oif? It seems to me that the
logic should be:

1. If sk->sk_bound_dev_if is set, use that interface.
2. Otherwise, if the connection came from a link-local address, use
the incoming interface.
3. Otherwise, use whatever route the system happens to have without
special regard to the incoming interface.

If so, then I think the code now does the wrong thing in two cases:

1. If the SYN comes from a global address, and sk->sk_bound_dev_if is
not set, the SYNACK is forced onto/prefers the interface the SYN came
in on instead of just doing a routing lookup with no interface.
2. If the SYN comes from a link-local address, and sk->sk_bound_dev_if
is set, then the SYNACK is forced onto/prefers the incoming interface
instead of the one specified by sk->sk_bound_dev_if.

If I am correct, then I'm happy to send out the trivial patch to fix
this. (Against what? net? net-next when the tree reopens?)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue
  2014-04-10  9:23   ` Lorenzo Colitti
@ 2014-04-10 21:57     ` Hannes Frederic Sowa
  2014-04-11  4:21       ` Lorenzo Colitti
  0 siblings, 1 reply; 8+ messages in thread
From: Hannes Frederic Sowa @ 2014-04-10 21:57 UTC (permalink / raw)
  To: Lorenzo Colitti; +Cc: Wangyufen, David Miller, netdev, Alexey Kuznetsov

Hi Lorenzo!

On Thu, Apr 10, 2014 at 06:23:35PM +0900, Lorenzo Colitti wrote:
> On Sat, Mar 29, 2014 at 10:27 AM, Wangyufen <wangyufen@huawei.com> wrote:
> > The issue raises when adding policy route, specify a particular
> > NIC as oif, the policy route did not take effect. The reason is
> > that fl6.oif is not set and route map failed. From the
> > tcp_v6_send_response function, if the binding address is linklocal,
> > fl6.oif is set, but not for global address.
> >
> > [...]
> >
> >         fl6.flowi6_proto = IPPROTO_TCP;
> > -       if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
> > +       if (rt6_need_strict(&fl6.daddr) || !oif)
> >                 fl6.flowi6_oif = inet6_iif(skb);
> 
> > +       else
> > +               fl6.flowi6_oif = oif;
> 
> Shouldn't this be && !oif instead of || !oif? It seems to me that the
> logic should be:
> 
> 1. If sk->sk_bound_dev_if is set, use that interface.
> 2. Otherwise, if the connection came from a link-local address, use
> the incoming interface.
> 3. Otherwise, use whatever route the system happens to have without
> special regard to the incoming interface.
> 
> If so, then I think the code now does the wrong thing in two cases:
> 
> 1. If the SYN comes from a global address, and sk->sk_bound_dev_if is
> not set, the SYNACK is forced onto/prefers the interface the SYN came
> in on instead of just doing a routing lookup with no interface.

First a rule lookup is done on the oif (if needed). After that a address
lookup is done in the fib and only if rt6_need_strict evaluates to
true in routing code we take flowi6_oif match as mandatory (we may
evaluate sk_bound_dev_if!=0 there to make sure we really only use the
bounded interface for global addresses but keep the interface id which
is set in above code).

So we still would send out the syn packet on the path the global address
dictates in most cases (or in case of multipath routes, prefer the
incoming interface).  We differ if bound_dev is set or policy routes
are in place.

So it depends on what we give precedence and I have to agree, I would
prefer sk_bound_dev_if as we do in other output paths. I misjudged that
when I proposed the code snippet. Thanks for the heads-up.

> 2. If the SYN comes from a link-local address, and sk->sk_bound_dev_if
> is set, then the SYNACK is forced onto/prefers the incoming interface
> instead of the one specified by sk->sk_bound_dev_if.
> 
> If I am correct, then I'm happy to send out the trivial patch to fix
> this. (Against what? net? net-next when the tree reopens?)

-net tree is always open and I would welcome a patch very much.

Thank you,

  Hannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue
  2014-04-10 21:57     ` Hannes Frederic Sowa
@ 2014-04-11  4:21       ` Lorenzo Colitti
  0 siblings, 0 replies; 8+ messages in thread
From: Lorenzo Colitti @ 2014-04-11  4:21 UTC (permalink / raw)
  To: Lorenzo Colitti, Wangyufen, David Miller, netdev, Alexey Kuznetsov

On Fri, Apr 11, 2014 at 6:57 AM, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> > If I am correct, then I'm happy to send out the trivial patch to fix
> > this. (Against what? net? net-next when the tree reopens?)
>
> -net tree is always open and I would welcome a patch very much.

Ack. I sent out http://patchwork.ozlabs.org/patch/338343/ .

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-04-11  4:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-29  1:27 [PATCH net-next v6 0/3] ipv6: tcp_ipv6 policy route issue Wangyufen
2014-03-29  1:27 ` [PATCH net-next v6 1/3] ipv6: tcp_ipv6 do some cleanup Wangyufen
2014-03-29  1:27 ` [PATCH net-next v6 2/3] ipv6: reuse rt6_need_strict Wangyufen
2014-03-29  1:27 ` [PATCH net-next v6 3/3] ipv6: tcp_ipv6 policy route issue Wangyufen
2014-04-10  9:23   ` Lorenzo Colitti
2014-04-10 21:57     ` Hannes Frederic Sowa
2014-04-11  4:21       ` Lorenzo Colitti
2014-03-31 20:16 ` [PATCH net-next v6 0/3] " David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.