8000 extmod/lwip-include: Consolidate IPv6 settings and enable auto-detect… · micropython/micropython@e17730a · GitHub
[go: up one dir, main page]

Skip to content

Commit e17730a

Browse files
committed
extmod/lwip-include: Consolidate IPv6 settings and enable auto-detection.
Enable IPv6 support when ROM level is at least EXTRA and consolidate IPv6 configuration settings in the common LWIP configuration: - LWIP_IPV6=MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA - LWIP_IPV6_AUTOCONFIG=1: Enable IPv6 autoconfiguration - LWIP_IPV6_MLD=1: Enable IPv6 Multicast Listener Discovery - LWIP_ND6_NUM_DESTINATIONS=4: Set neighbor discovery cache size - LWIP_ND6_QUEUEING=0: Disable ND6 queueing to reduce RAM usage Also includes atoi declaration and redirect for LWIP compatibility. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
1 parent 84ce69e commit e17730a

File tree

9 files changed

+316
-1
lines changed

9 files changed

+316
-1
lines changed

extmod/lwip-include/lwipopts_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ int lwip_atoi(const char *str);
6464
#define LWIP_IGMP 1
6565

6666
#ifndef LWIP_IPV6
67-
#define LWIP_IPV6 1
67+
#define LWIP_IPV6 MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA
6868
#endif
6969

7070
#if LWIP_IPV6

tests/extmod/socket_ipv6_basic.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Test basic IPv6 socket functionality
2+
3+
try:
4+
import socket, errno
5+
except ImportError:
6+
print("SKIP")
7+
raise SystemExit
8+
9+
# Check if IPv6 is supported
10+
try:
11+
socket.AF_INET6
12+
except AttributeError:
13+
print("SKIP")
14+
raise SystemExit
15+
16+
# Test IPv6 socket creation
17+
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
18+
print("IPv6 TCP socket created")
19+
20+
# Test IPv6 UDP socket creation
21+
u = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
22+
print("IPv6 UDP socket created")
23+
24+
# Test binding to IPv6 localhost
25+
try:
26+
s.bind(socket.getaddrinfo("::1", 0, socket.AF_INET6)[0][-1])
27+
print("IPv6 TCP bind successful")
28+
except OSError as e:
29+
print("IPv6 TCP bind failed:", e)
30+
31+
try:
32+
u.bind(socket.getaddrinfo("::1", 0, socket.AF_INET6)[0][-1])
33+
print("IPv6 UDP bind successful")
34+
except OSError as e:
35+
print("IPv6 UDP bind failed:", e)
36+
37+
# Test binding to IPv6 wildcard address
38+
s2 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
39+
u2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
40+
41+
try:
42+
s2.bind(socket.getaddrinfo("::", 0, socket.AF_INET6)[0][-1])
43+
print("IPv6 TCP wildcard bind successful")
44+
except OSError as e:
45+
print("IPv6 TCP wildcard bind failed:", e)
46+
47+
try:
48+
u2.bind(socket.getaddrinfo("::", 0, socket.AF_INET6)[0][-1])
49+
print("IPv6 UDP wildcard bind successful")
50+
except OSError as e:
51+
print("IPv6 UDP wildcard bind failed:", e)
52+
53+
# recv() on a fresh IPv6 socket should raise ENOTCONN
54+
s3 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
55+
try:
56+
s3.recv(1)
57+
except OSError as er:
58+
print("IPv6 ENOTCONN:", er.errno == errno.ENOTCONN)
59+
60+
# Clean up
61+
s.close()
62+
u.close()
63+
s2.close()
64+
u2.close()
65+
s3.close()

tests/extmod/socket_ipv6_basic.py.exp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
IPv6 TCP socket created
2+
IPv6 UDP socket created
3+
IPv6 TCP bind successful
4+
IPv6 UDP bind successful
5+
IPv6 TCP wildcard bind successful
6+
IPv6 UDP wildcard bind successful
7+
IPv6 ENOTCONN: True

tests/multi_net/tcp_data_ipv6.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Simple test of IPv6 TCP server and client transferring data
2+
3+
import socket
4+
5+
PORT = 8000
6+
7+
8+
def check_ipv6_support():
9+
try:
10+
socket.AF_INET6
11+
# Try to create an IPv6 socket to verify support
12+
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
13+
s.close()
14+
return True
15+
except (AttributeError, OSError):
16+
return False
17+
18+
19+
if not check_ipv6_support():
20+
print("SKIP")
21+
raise SystemExit
22+
23+
24+
# Server
25+
def instance0():
26+
multitest.globals(IP="::1")
27+
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
28+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
29+
s.bind(socket.getaddrinfo("::", PORT, socket.AF_INET6)[0][-1])
30+
s.listen()
31+
multitest.next()
32+
s2, _ = s.accept()
33+
print(s2.recv(16))
34+
s2.send(b"server to client")
35+
s2.close()
36+
s.close()
37+
38+
39+
# Client
40+
def instance1():
41+
multitest.next()
42+
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
43+
s.connect(socket.getaddrinfo(IP, PORT, socket.AF_INET6)[0][-1])
44+
s.send(b"client to server")
45+
print(s.recv(16))
46+
s.close()

tests/multi_net/tcp_data_ipv6.py.exp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--- instance0 ---
2+
b'client to server'
3+
--- instance1 ---
4+
b'server to client'

tests/multi_net/udp_data_ipv6.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Simple test of IPv6 UDP server and client transferring data
2+
3+
import socket
4+
5+
NUM_NEW_SOCKETS = 4
6+
NUM_TRANSFERS = 10
7+
TOTAL_PACKETS = NUM_NEW_SOCKETS * NUM_TRANSFERS
8+
# If more than 75% of packets are lost, the test fails.
9+
PACKET_LOSS_THRESH = 0.75 * TOTAL_PACKETS
10+
PORT = 8000
11+
12+
13+
def check_ipv6_support():
14+
try:
15+
socket.AF_INET6
16+
# Try to create an IPv6 socket to verify support
17+
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
18+
s.close()
19+
return True
20+
except (AttributeError, OSError):
21+
return False
22+
23+
24+
if not check_ipv6_support():
25+
print("SKIP")
26+
raise SystemExit
27+
28+
29+
def print_stats(seq):
30+
if (TOTAL_PACKETS - seq) > PACKET_LOSS_THRESH:
31+
print(
32+
"packet loss %.1f%% %d/%d"
33+
% (((TOTAL_PACKETS - seq) / TOTAL_PACKETS * 100), seq, TOTAL_PACKETS)
34+
)
35+
else:
36+
print("pass")
37+
38+
39+
# Server
40+
def instance0():
41+
seq = 0
42+
multitest.globals(IP="::1")
43+
multitest.next()
44+
for i in range(NUM_NEW_SOCKETS):
45+
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
46+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
47+
s.bind(socket.getaddrinfo("::", PORT + i, socket.AF_INET6)[0][-1])
48+
s.settimeout(0.250)
49+
multitest.broadcast("server ready")
50+
for j in range(NUM_TRANSFERS):
51+
try:
52+
data, addr = s.recvfrom(1000)
53+
except:
54+
continue
55+
if int(data) == seq:
56+
if seq < (TOTAL_PACKETS - PACKET_LOSS_THRESH):
57+
print(seq)
58+
seq += 1
59+
s.sendto(b"%d" % (seq), addr)
60+
s.close()
61+
62+
print_stats(seq)
63+
64+
65+
# Client
66+
def instance1():
67+
seq = 0
68+
multitest.next()
69+
for i in range(NUM_NEW_SOCKETS):
70+
ai = socket.getaddrinfo(IP, PORT + i, socket.AF_INET6)[0][-1]
71+
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
72+
s.settimeout(0.250)
73 10000 +
multitest.wait("server ready")
74+
for j in range(NUM_TRANSFERS):
75+
s.sendto(b"%d" % (seq), ai)
76+
try:
77+
data, addr = s.recvfrom(1000)
78+
except:
79+
continue
80+
if int(data) == seq + 1:
81+
if seq < (TOTAL_PACKETS - PACKET_LOSS_THRESH):
82+
print(seq)
83+
seq += 1
84+
s.close()
85+
86+
print_stats(seq)

tests/multi_net/udp_data_ipv6.py.exp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--- instance0 ---
2+
0
3+
1
4+
2
5+
3
6+
4
7+
5
8+
6
9+
7
10+
8
11+
9
12+
pass
13+
--- instance1 ---
14+
0
15+
1
16+
2
17+
3
18+
4
19+
5
20+
6
21+
7
22+
8
23+
9
24+
pass

tests/net_inet/getaddrinfo_ipv6.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import socket, sys
2+
3+
4+
def check_ipv6_support():
5+
try:
6+
socket.AF_INET6
7+
return True
8+
except AttributeError:
9+
return False
10+
11+
12+
if not check_ipv6_support():
13+
print("SKIP")
14+
raise SystemExit
15+
16+
17+
def test_ipv6_localhost():
18+
try:
19+
res = socket.getaddrinfo("::1", 80, socket.AF_INET6)
20+
print("IPv6 localhost getaddrinfo returned resolutions")
21+
except Exception as e:
22+
print("IPv6 localhost getaddrinfo raised", e)
23+
24+
25+
def test_ipv6_wildcard():
26+
try:
27+
res = socket.getaddrinfo("::", 80, socket.AF_INET6)
28+
print("IPv6 wildcard getaddrinfo returned resolutions")
29+
except Exception as e:
30+
print("IPv6 wildcard getaddrinfo raised", e)
31+
32+
33+
def test_ipv6_address():
34+
try:
35+
res = socket.getaddrinfo("2001:db8::1", 80, socket.AF_INET6)
36+
print("IPv6 address getaddrinfo returned resolutions")
37+
except Exception as e:
38+
print("IPv6 address getaddrinfo raised", e)
39+
40+
41+
def test_dual_stack():
42+
try:
43+
# Test that both IPv4 and IPv6 can be resolved
44+
res4 = socket.getaddrinfo("127.0.0.1", 80, socket.AF_INET)
45+
res6 = socket.getaddrinfo("::1", 80, socket.AF_INET6)
46+
print("Dual stack getaddrinfo returned resolutions")
47+
except Exception as e:
48+
print("Dual stack getaddrinfo raised", e)
49+
50+
51+
def test_family_unspec():
52+
try:
53+
# Test unspecified family (should return both IPv4 and IPv6 if available)
54+
res = socket.getaddrinfo("localhost", 80)
55+
has_ipv4 = any(addr[0] == socket.AF_INET for addr in res)
56+
has_ipv6 = any(addr[0] == socket.AF_INET6 for addr in res)
57+
if has_ipv4 or has_ipv6:
58+
print("Unspecified family getaddrinfo returned resolutions")
59+
else:
60+
print("Unspecified family getaddrinfo returned empty")
61+
except Exception as e:
62+
print("Unspecified family getaddrinfo raised", e)
63+
64+
65+
def test_ipv6_domain():
66+
try:
67+
# Try to resolve a domain name with IPv6
68+
res = socket.getaddrinfo("google.com", 80, socket.AF_INET6)
69+
print("IPv6 domain getaddrinfo returned resolutions")
70+
except Exception as e:
71+
print("IPv6 domain getaddrinfo raised", e)
72+
73+
74+
test_funs = [n for n in dir() if n.startswith("test_")]
75+
for f in sorted(test_funs):
76+
print("--", f, end=": ")
77+
eval(f + "()")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- test_dual_stack: Dual stack getaddrinfo returned resolutions
2+
-- test_family_unspec: Unspecified family getaddrinfo returned resolutions
3+
-- test_ipv6_address: IPv6 address getaddrinfo returned resolutions
4+
-- test_ipv6_domain: IPv6 domain getaddrinfo returned resolutions
5+
-- test_ipv6_localhost: IPv6 localhost getaddrinfo returned resolutions
6+
-- test_ipv6_wildcard: IPv6 wildcard getaddrinfo returned resolutions

0 commit comments

Comments
 (0)
0