]>
Commit | Line | Data |
---|---|---|
d3e91060 SL |
1 | From 257403f2ebbab92d7c57c12e3439c3866a52bd51 Mon Sep 17 00:00:00 2001 |
2 | From: yupeng <yupeng0921@gmail.com> | |
3 | Date: Wed, 5 Dec 2018 18:56:28 -0800 | |
4 | Subject: net: call sk_dst_reset when set SO_DONTROUTE | |
5 | ||
6 | [ Upstream commit 0fbe82e628c817e292ff588cd5847fc935e025f2 ] | |
7 | ||
8 | after set SO_DONTROUTE to 1, the IP layer should not route packets if | |
9 | the dest IP address is not in link scope. But if the socket has cached | |
10 | the dst_entry, such packets would be routed until the sk_dst_cache | |
11 | expires. So we should clean the sk_dst_cache when a user set | |
12 | SO_DONTROUTE option. Below are server/client python scripts which | |
13 | could reprodue this issue: | |
14 | ||
15 | server side code: | |
16 | ||
17 | ========================================================================== | |
18 | import socket | |
19 | import struct | |
20 | import time | |
21 | ||
22 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
23 | s.bind(('0.0.0.0', 9000)) | |
24 | s.listen(1) | |
25 | sock, addr = s.accept() | |
26 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_DONTROUTE, struct.pack('i', 1)) | |
27 | while True: | |
28 | sock.send(b'foo') | |
29 | time.sleep(1) | |
30 | ========================================================================== | |
31 | ||
32 | client side code: | |
33 | ========================================================================== | |
34 | import socket | |
35 | import time | |
36 | ||
37 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
38 | s.connect(('server_address', 9000)) | |
39 | while True: | |
40 | data = s.recv(1024) | |
41 | print(data) | |
42 | ========================================================================== | |
43 | ||
44 | Signed-off-by: yupeng <yupeng0921@gmail.com> | |
45 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
46 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
47 | --- | |
48 | net/core/sock.c | 1 + | |
49 | 1 file changed, 1 insertion(+) | |
50 | ||
51 | diff --git a/net/core/sock.c b/net/core/sock.c | |
52 | index 9fb1c073d0c4..8aa4a5f89572 100644 | |
53 | --- a/net/core/sock.c | |
54 | +++ b/net/core/sock.c | |
55 | @@ -732,6 +732,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | |
56 | break; | |
57 | case SO_DONTROUTE: | |
58 | sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool); | |
59 | + sk_dst_reset(sk); | |
60 | break; | |
61 | case SO_BROADCAST: | |
62 | sock_valbool_flag(sk, SOCK_BROADCAST, valbool); | |
63 | -- | |
64 | 2.19.1 | |
65 |