* [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
2018-03-29 17:37 [PATCH net v3 0/3] ipv6: udp6: set dst cache for a connected sk if current not valid Alexey Kodanev
@ 2018-03-29 17:37 ` Alexey Kodanev
2018-03-30 10:14 ` kbuild test robot
2018-03-30 15:58 ` kbuild test robot
2018-03-29 17:37 ` [PATCH net v3 2/3] ipv6: allow to cache dst for connected sk in ip6_sk_dst_lookup_flow() Alexey Kodanev
2018-03-29 17:37 ` [PATCH net v3 3/3] ipv6: udp6: set dst cache for a connected sk if current not valid Alexey Kodanev
2 siblings, 2 replies; 7+ messages in thread
From: Alexey Kodanev @ 2018-03-29 17:37 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet, Martin KaFai Lau, David Miller, Alexey Kodanev
Move commonly used pattern of ip6_dst_store() usage to a separate
function - ip6_dst_store_flow(), which will check the addresses
for equality before saving them.
There is no functional changes in this patch, the new wrapper
will be used in the next patch, in ip6_sk_dst_lookup_flow().
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
include/net/ip6_route.h | 17 +++++++++++++++++
net/ipv6/datagram.c | 9 +--------
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index ac0866b..36c3946 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -210,6 +210,23 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
#endif
}
+static inline void ip6_dst_store_flow(struct sock *sk, struct dst_entry *dst,
+ struct flowi6 *fl6)
+{
+#ifdef CONFIG_IPV6_SUBTREES
+ struct ipv6_pinfo *np = inet6_sk(sk);
+#endif
+
+ ip6_dst_store(sk, dst,
+ ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
+ &sk->sk_v6_daddr : NULL,
+#ifdef CONFIG_IPV6_SUBTREES
+ ipv6_addr_equal(&fl6->saddr, &np->saddr) ?
+ &np->saddr :
+#endif
+ NULL);
+}
+
static inline bool ipv6_unicast_destination(const struct sk_buff *skb)
{
struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index a9f7eca..8b4fa0c 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -106,14 +106,7 @@ int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr)
}
}
- ip6_dst_store(sk, dst,
- ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
- &sk->sk_v6_daddr : NULL,
-#ifdef CONFIG_IPV6_SUBTREES
- ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
- &np->saddr :
-#endif
- NULL);
+ ip6_dst_store_flow(sk, dst, &fl6);
out:
fl6_sock_release(flowlabel);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
2018-03-29 17:37 ` [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper Alexey Kodanev
@ 2018-03-30 10:14 ` kbuild test robot
2018-03-30 11:36 ` Alexey Kodanev
2018-03-30 15:58 ` kbuild test robot
1 sibling, 1 reply; 7+ messages in thread
From: kbuild test robot @ 2018-03-30 10:14 UTC (permalink / raw)
To: Alexey Kodanev
Cc: kbuild-all, netdev, Eric Dumazet, Martin KaFai Lau, David Miller,
Alexey Kodanev
[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]
Hi Alexey,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Alexey-Kodanev/ipv6-move-ip6_dst_store-calls-with-flowi6-checks-to-a-wrapper/20180330-173050
config: ia64-defconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=ia64
All warnings (new ones prefixed by >>):
In file included from include/linux/tcp.h:23:0,
from include/linux/ipv6.h:87,
from include/net/ipv6.h:16,
from include/net/inetpeer.h:16,
from include/net/route.h:28,
from drivers/infiniband/core/addr.c:43:
include/net/ip6_route.h: In function 'ip6_dst_store_flow':
include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
>> include/net/ip6_route.h:221:43: note: in expansion of macro 'sk_v6_daddr'
ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
^~~~~~~~~~~
include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
include/net/ip6_route.h:222:14: note: in expansion of macro 'sk_v6_daddr'
&sk->sk_v6_daddr : NULL,
^~~~~~~~~~~
vim +/sk_v6_daddr +221 include/net/ip6_route.h
219
220 ip6_dst_store(sk, dst,
> 221 ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
222 &sk->sk_v6_daddr : NULL,
223 #ifdef CONFIG_IPV6_SUBTREES
224 ipv6_addr_equal(&fl6->saddr, &np->saddr) ?
225 &np->saddr :
226 #endif
227 NULL);
228 }
229
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 18690 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
2018-03-30 10:14 ` kbuild test robot
@ 2018-03-30 11:36 ` Alexey Kodanev
0 siblings, 0 replies; 7+ messages in thread
From: Alexey Kodanev @ 2018-03-30 11:36 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, netdev, Eric Dumazet, Martin KaFai Lau, David Miller
On 03/30/2018 01:14 PM, kbuild test robot wrote:
> Hi Alexey,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on net/master]
>
> url: https://github.com/0day-ci/linux/commits/Alexey-Kodanev/ipv6-move-ip6_dst_store-calls-with-flowi6-checks-to-a-wrapper/20180330-173050
> config: ia64-defconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 7.2.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=ia64
>
> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/tcp.h:23:0,
> from include/linux/ipv6.h:87,
> from include/net/ipv6.h:16,
> from include/net/inetpeer.h:16,
> from include/net/route.h:28,
> from drivers/infiniband/core/addr.c:43:
> include/net/ip6_route.h: In function 'ip6_dst_store_flow':
> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
> #define sk_v6_daddr __sk_common.skc_v6_daddr
> ^
>>> include/net/ip6_route.h:221:43: note: in expansion of macro 'sk_v6_daddr'
> ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
> ^~~~~~~~~~~
> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
> #define sk_v6_daddr __sk_common.skc_v6_daddr
> ^
> include/net/ip6_route.h:222:14: note: in expansion of macro 'sk_v6_daddr'
> &sk->sk_v6_daddr : NULL
> ^~~~~~~~~~~
This is because CONFIG_IPV6 is not enabled, no sk_v6_daddr member,
I'll fix it in the new version.
Thanks,
Alexey
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper
2018-03-29 17:37 ` [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper Alexey Kodanev
2018-03-30 10:14 ` kbuild test robot
@ 2018-03-30 15:58 ` kbuild test robot
1 sibling, 0 replies; 7+ messages in thread
From: kbuild test robot @ 2018-03-30 15:58 UTC (permalink / raw)
To: Alexey Kodanev
Cc: kbuild-all, netdev, Eric Dumazet, Martin KaFai Lau, David Miller,
Alexey Kodanev
[-- Attachment #1: Type: text/plain, Size: 10447 bytes --]
Hi Alexey,
I love your patch! Yet something to improve:
[auto build test ERROR on net/master]
url: https://github.com/0day-ci/linux/commits/Alexey-Kodanev/ipv6-move-ip6_dst_store-calls-with-flowi6-checks-to-a-wrapper/20180330-173050
config: x86_64-kexec (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
In file included from include/linux/tcp.h:23:0,
from drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c:33:
include/net/ip6_route.h: In function 'ip6_dst_store_flow':
>> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
include/net/ip6_route.h:221:43: note: in expansion of macro 'sk_v6_daddr'
ipv6_addr_equal(&fl6->daddr, &sk->sk_v6_daddr) ?
^~~~~~~~~~~
>> include/net/sock.h:349:34: error: 'struct sock_common' has no member named 'skc_v6_daddr'; did you mean 'skc_daddr'?
#define sk_v6_daddr __sk_common.skc_v6_daddr
^
include/net/ip6_route.h:222:14: note: in expansion of macro 'sk_v6_daddr'
&sk->sk_v6_daddr : NULL,
^~~~~~~~~~~
vim +349 include/net/sock.h
4dc6dc716 Eric Dumazet 2009-07-15 329
68835aba4 Eric Dumazet 2010-11-30 330 #define sk_dontcopy_begin __sk_common.skc_dontcopy_begin
68835aba4 Eric Dumazet 2010-11-30 331 #define sk_dontcopy_end __sk_common.skc_dontcopy_end
4dc6dc716 Eric Dumazet 2009-07-15 332 #define sk_hash __sk_common.skc_hash
508054668 Eric Dumazet 2013-10-02 333 #define sk_portpair __sk_common.skc_portpair
05dbc7b59 Eric Dumazet 2013-10-03 334 #define sk_num __sk_common.skc_num
05dbc7b59 Eric Dumazet 2013-10-03 335 #define sk_dport __sk_common.skc_dport
508054668 Eric Dumazet 2013-10-02 336 #define sk_addrpair __sk_common.skc_addrpair
508054668 Eric Dumazet 2013-10-02 337 #define sk_daddr __sk_common.skc_daddr
508054668 Eric Dumazet 2013-10-02 338 #define sk_rcv_saddr __sk_common.skc_rcv_saddr
^1da177e4 Linus Torvalds 2005-04-16 339 #define sk_family __sk_common.skc_family
^1da177e4 Linus Torvalds 2005-04-16 340 #define sk_state __sk_common.skc_state
^1da177e4 Linus Torvalds 2005-04-16 341 #define sk_reuse __sk_common.skc_reuse
055dc21a1 Tom Herbert 2013-01-22 342 #define sk_reuseport __sk_common.skc_reuseport
9fe516ba3 Eric Dumazet 2014-06-27 343 #define sk_ipv6only __sk_common.skc_ipv6only
26abe1437 Eric W. Biederman 2015-05-08 344 #define sk_net_refcnt __sk_common.skc_net_refcnt
^1da177e4 Linus Torvalds 2005-04-16 345 #define sk_bound_dev_if __sk_common.skc_bound_dev_if
^1da177e4 Linus Torvalds 2005-04-16 346 #define sk_bind_node __sk_common.skc_bind_node
8feaf0c0a Arnaldo Carvalho de Melo 2005-08-09 347 #define sk_prot __sk_common.skc_prot
07feaebfc Eric W. Biederman 2007-09-12 348 #define sk_net __sk_common.skc_net
efe4208f4 Eric Dumazet 2013-10-03 @349 #define sk_v6_daddr __sk_common.skc_v6_daddr
efe4208f4 Eric Dumazet 2013-10-03 350 #define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
33cf7c90f Eric Dumazet 2015-03-11 351 #define sk_cookie __sk_common.skc_cookie
70da268b5 Eric Dumazet 2015-10-08 352 #define sk_incoming_cpu __sk_common.skc_incoming_cpu
8e5eb54d3 Eric Dumazet 2015-10-08 353 #define sk_flags __sk_common.skc_flags
ed53d0ab7 Eric Dumazet 2015-10-08 354 #define sk_rxhash __sk_common.skc_rxhash
efe4208f4 Eric Dumazet 2013-10-03 355
^1da177e4 Linus Torvalds 2005-04-16 356 socket_lock_t sk_lock;
9115e8cd2 Eric Dumazet 2016-12-03 357 atomic_t sk_drops;
9115e8cd2 Eric Dumazet 2016-12-03 358 int sk_rcvlowat;
9115e8cd2 Eric Dumazet 2016-12-03 359 struct sk_buff_head sk_error_queue;
b178bb3df Eric Dumazet 2010-11-16 360 struct sk_buff_head sk_receive_queue;
fa438ccfd Eric Dumazet 2007-03-04 361 /*
fa438ccfd Eric Dumazet 2007-03-04 362 * The backlog queue is special, it is always used with
fa438ccfd Eric Dumazet 2007-03-04 363 * the per-socket spinlock held and requires low latency
fa438ccfd Eric Dumazet 2007-03-04 364 * access. Therefore we special case it's implementation.
b178bb3df Eric Dumazet 2010-11-16 365 * Note : rmem_alloc is in this structure to fill a hole
b178bb3df Eric Dumazet 2010-11-16 366 * on 64bit arches, not because its logically part of
b178bb3df Eric Dumazet 2010-11-16 367 * backlog.
fa438ccfd Eric Dumazet 2007-03-04 368 */
fa438ccfd Eric Dumazet 2007-03-04 369 struct {
b178bb3df Eric Dumazet 2010-11-16 370 atomic_t rmem_alloc;
b178bb3df Eric Dumazet 2010-11-16 371 int len;
fa438ccfd Eric Dumazet 2007-03-04 372 struct sk_buff *head;
fa438ccfd Eric Dumazet 2007-03-04 373 struct sk_buff *tail;
fa438ccfd Eric Dumazet 2007-03-04 374 } sk_backlog;
b178bb3df Eric Dumazet 2010-11-16 375 #define sk_rmem_alloc sk_backlog.rmem_alloc
2c8c56e15 Eric Dumazet 2014-11-11 376
9115e8cd2 Eric Dumazet 2016-12-03 377 int sk_forward_alloc;
e0d1095ae Cong Wang 2013-08-01 378 #ifdef CONFIG_NET_RX_BUSY_POLL
dafcc4380 Eliezer Tamir 2013-06-14 379 unsigned int sk_ll_usec;
9115e8cd2 Eric Dumazet 2016-12-03 380 /* ===== mostly read cache line ===== */
9115e8cd2 Eric Dumazet 2016-12-03 381 unsigned int sk_napi_id;
060212928 Eliezer Tamir 2013-06-10 382 #endif
b178bb3df Eric Dumazet 2010-11-16 383 int sk_rcvbuf;
b178bb3df Eric Dumazet 2010-11-16 384
b178bb3df Eric Dumazet 2010-11-16 385 struct sk_filter __rcu *sk_filter;
ceb5d58b2 Eric Dumazet 2015-11-29 386 union {
eaefd1105 Eric Dumazet 2011-02-18 387 struct socket_wq __rcu *sk_wq;
ceb5d58b2 Eric Dumazet 2015-11-29 388 struct socket_wq *sk_wq_raw;
ceb5d58b2 Eric Dumazet 2015-11-29 389 };
def8b4faf Alexey Dobriyan 2008-10-28 390 #ifdef CONFIG_XFRM
d188ba86d Eric Dumazet 2015-12-08 391 struct xfrm_policy __rcu *sk_policy[2];
def8b4faf Alexey Dobriyan 2008-10-28 392 #endif
deaa58542 Eric Dumazet 2012-06-24 393 struct dst_entry *sk_rx_dst;
0e36cbb34 Cong Wang 2013-01-22 394 struct dst_entry __rcu *sk_dst_cache;
^1da177e4 Linus Torvalds 2005-04-16 395 atomic_t sk_omem_alloc;
4e07a91c3 Arnaldo Carvalho de Melo 2007-05-29 396 int sk_sndbuf;
9115e8cd2 Eric Dumazet 2016-12-03 397
9115e8cd2 Eric Dumazet 2016-12-03 398 /* ===== cache line for TX ===== */
9115e8cd2 Eric Dumazet 2016-12-03 399 int sk_wmem_queued;
14afee4b6 Reshetova, Elena 2017-06-30 400 refcount_t sk_wmem_alloc;
9115e8cd2 Eric Dumazet 2016-12-03 401 unsigned long sk_tsq_flags;
75c119afe Eric Dumazet 2017-10-05 402 union {
9115e8cd2 Eric Dumazet 2016-12-03 403 struct sk_buff *sk_send_head;
75c119afe Eric Dumazet 2017-10-05 404 struct rb_root tcp_rtx_queue;
75c119afe Eric Dumazet 2017-10-05 405 };
^1da177e4 Linus Torvalds 2005-04-16 406 struct sk_buff_head sk_write_queue;
9115e8cd2 Eric Dumazet 2016-12-03 407 __s32 sk_peek_off;
9115e8cd2 Eric Dumazet 2016-12-03 408 int sk_write_pending;
9b8805a32 Julian Anastasov 2017-02-06 409 __u32 sk_dst_pending_confirm;
218af599f Eric Dumazet 2017-05-16 410 u32 sk_pacing_status; /* see enum sk_pacing */
9115e8cd2 Eric Dumazet 2016-12-03 411 long sk_sndtimeo;
9115e8cd2 Eric Dumazet 2016-12-03 412 struct timer_list sk_timer;
9115e8cd2 Eric Dumazet 2016-12-03 413 __u32 sk_priority;
9115e8cd2 Eric Dumazet 2016-12-03 414 __u32 sk_mark;
9115e8cd2 Eric Dumazet 2016-12-03 415 u32 sk_pacing_rate; /* bytes per second */
9115e8cd2 Eric Dumazet 2016-12-03 416 u32 sk_max_pacing_rate;
9115e8cd2 Eric Dumazet 2016-12-03 417 struct page_frag sk_frag;
9115e8cd2 Eric Dumazet 2016-12-03 418 netdev_features_t sk_route_caps;
9115e8cd2 Eric Dumazet 2016-12-03 419 netdev_features_t sk_route_nocaps;
9115e8cd2 Eric Dumazet 2016-12-03 420 int sk_gso_type;
9115e8cd2 Eric Dumazet 2016-12-03 421 unsigned int sk_gso_max_size;
9115e8cd2 Eric Dumazet 2016-12-03 422 gfp_t sk_allocation;
9115e8cd2 Eric Dumazet 2016-12-03 423 __u32 sk_txhash;
fc64869c4 Andrey Ryabinin 2016-05-18 424
fc64869c4 Andrey Ryabinin 2016-05-18 425 /*
fc64869c4 Andrey Ryabinin 2016-05-18 426 * Because of non atomicity rules, all
fc64869c4 Andrey Ryabinin 2016-05-18 427 * changes are protected by socket lock.
fc64869c4 Andrey Ryabinin 2016-05-18 428 */
aa4c1037a David Ahern 2016-12-01 429 unsigned int __sk_flags_offset[0];
aa4c1037a David Ahern 2016-12-01 430 #ifdef __BIG_ENDIAN_BITFIELD
aa4c1037a David Ahern 2016-12-01 431 #define SK_FL_PROTO_SHIFT 16
aa4c1037a David Ahern 2016-12-01 432 #define SK_FL_PROTO_MASK 0x00ff0000
aa4c1037a David Ahern 2016-12-01 433
:::::: The code at line 349 was first introduced by commit
:::::: efe4208f47f907b86f528788da711e8ab9dea44d ipv6: make lookups simpler and faster
:::::: TO: Eric Dumazet <edumazet@google.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26634 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net v3 2/3] ipv6: allow to cache dst for connected sk in ip6_sk_dst_lookup_flow()
2018-03-29 17:37 [PATCH net v3 0/3] ipv6: udp6: set dst cache for a connected sk if current not valid Alexey Kodanev
2018-03-29 17:37 ` [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper Alexey Kodanev
@ 2018-03-29 17:37 ` Alexey Kodanev
2018-03-29 17:37 ` [PATCH net v3 3/3] ipv6: udp6: set dst cache for a connected sk if current not valid Alexey Kodanev
2 siblings, 0 replies; 7+ messages in thread
From: Alexey Kodanev @ 2018-03-29 17:37 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet, Martin KaFai Lau, David Miller, Alexey Kodanev
Add 'connected' argument to ip6_sk_dst_lookup_flow() and
update the cache only if ip6_sk_dst_check() returns NULL
and a socket is connected.
The function is used as before, the new behavior for UDP
sockets in udpv6_sendmsg() will be enabled in the next
patch.
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
include/net/ipv6.h | 3 ++-
net/ipv6/ip6_output.c | 15 ++++++++++++---
net/ipv6/ping.c | 2 +-
net/ipv6/udp.c | 2 +-
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8606c91..07e94dc 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -977,7 +977,8 @@ int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst);
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
- const struct in6_addr *final_dst);
+ const struct in6_addr *final_dst,
+ int connected);
struct dst_entry *ip6_blackhole_route(struct net *net,
struct dst_entry *orig_dst);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a8a9195..c22017c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1105,23 +1105,32 @@ struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
* @sk: socket which provides the dst cache and route info
* @fl6: flow to lookup
* @final_dst: final destination address for ipsec lookup
+ * @connected: whether @sk is connected or not
*
* This function performs a route lookup on the given flow with the
* possibility of using the cached route in the socket if it is valid.
* It will take the socket dst lock when operating on the dst cache.
* As a result, this function can only be used in process context.
*
+ * In addition, for a connected socket, cache the dst in the socket
+ * if the current cache is not valid.
+ *
* It returns a valid dst pointer on success, or a pointer encoded
* error code.
*/
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
- const struct in6_addr *final_dst)
+ const struct in6_addr *final_dst,
+ int connected)
{
struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
dst = ip6_sk_dst_check(sk, dst, fl6);
- if (!dst)
- dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
+ if (dst)
+ return dst;
+
+ dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
+ if (connected && !IS_ERR(dst))
+ ip6_dst_store_flow(sk, dst_clone(dst), fl6);
return dst;
}
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index d12c55d..546f4a6 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -121,7 +121,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipc6.tclass = np->tclass;
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
- dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr);
+ dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, 0);
if (IS_ERR(dst))
return PTR_ERR(dst);
rt = (struct rt6_info *) dst;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 52e3ea0..e49dac4 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1289,7 +1289,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
- dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p);
+ dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, 0);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net v3 3/3] ipv6: udp6: set dst cache for a connected sk if current not valid
2018-03-29 17:37 [PATCH net v3 0/3] ipv6: udp6: set dst cache for a connected sk if current not valid Alexey Kodanev
2018-03-29 17:37 ` [PATCH net v3 1/3] ipv6: move ip6_dst_store() calls with flowi6 checks to a wrapper Alexey Kodanev
2018-03-29 17:37 ` [PATCH net v3 2/3] ipv6: allow to cache dst for connected sk in ip6_sk_dst_lookup_flow() Alexey Kodanev
@ 2018-03-29 17:37 ` Alexey Kodanev
2 siblings, 0 replies; 7+ messages in thread
From: Alexey Kodanev @ 2018-03-29 17:37 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet, Martin KaFai Lau, David Miller, Alexey Kodanev
A new RTF_CACHE route can be created in udpv6_sendmsg() between
ip6_sk_dst_lookup_flow() and ip6_dst_store() calls when datagram
sending results to ICMPV6_PKT_TOOBIG error:
udp_v6_send_skb(), for example with vti6 tunnel:
vti6_xmit(), get ICMPV6_PKT_TOOBIG error
skb_dst_update_pmtu(), can create a RTF_CACHE clone
icmpv6_send()
...
udpv6_err()
ip6_sk_update_pmtu()
ip6_update_pmtu(), can create a RTF_CACHE clone
...
ip6_datagram_dst_update()
ip6_dst_store()
And after commit 33c162a980fe ("ipv6: datagram: Update dst cache
of a connected datagram sk during pmtu update"), the UDPv6 error
handler can update socket's dst cache, but it can happen before
the update in end of udpv6_sendmsg(), preventing getting updated
dst cache on the next udpv6_sendmsg() calls.
In order to fix it, we should save dst for a connected socket
in udpv6_sendmsg(), only if the previous socket's cache is not
valid.
Fixes: 33c162a980fe ("ipv6: datagram: Update dst cache of a connected datagram sk during pmtu update")
Fixes: 45e4fd26683c ("ipv6: Only create RTF_CACHE routes after encountering pmtu exception")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
net/ipv6/udp.c | 21 ++-------------------
1 file changed, 2 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e49dac4..da13c90 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1289,7 +1289,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
- dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, 0);
+ dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, connected);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
@@ -1314,7 +1314,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
err = PTR_ERR(skb);
if (!IS_ERR_OR_NULL(skb))
err = udp_v6_send_skb(skb, &fl6);
- goto release_dst;
+ goto out;
}
lock_sock(sk);
@@ -1348,23 +1348,6 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
err = np->recverr ? net_xmit_errno(err) : 0;
release_sock(sk);
-release_dst:
- if (dst) {
- if (connected) {
- ip6_dst_store(sk, dst,
- ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
- &sk->sk_v6_daddr : NULL,
-#ifdef CONFIG_IPV6_SUBTREES
- ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
- &np->saddr :
-#endif
- NULL);
- } else {
- dst_release(dst);
- }
- dst = NULL;
- }
-
out:
dst_release(dst);
fl6_sock_release(flowlabel);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 7+ messages in thread