diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2017-08-24 14:43:02 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-08-24 14:43:02 +0000 |
commit | ddc9df77efa3e8ebc8277a98622f0b0ce098bd9f (patch) | |
tree | c6f315cc9ae083dede4c0ea78d2faa8b5d20f379 | |
parent | 7502e4eb60c77e6b5d965223ec6098180e3f9c3a (diff) | |
parent | d6cdfebebe6cfedb7f53391ef23cfc3432f1de90 (diff) | |
download | tests-ddc9df77efa3e8ebc8277a98622f0b0ce098bd9f.tar.gz |
Merge "forwarding_test: Add a test for forwarding UDPv6"android-o-mr1-preview-2android-o-mr1-preview-1
-rwxr-xr-x | net/test/forwarding_test.py | 89 | ||||
-rw-r--r-- | net/test/packets.py | 6 |
2 files changed, 75 insertions, 20 deletions
diff --git a/net/test/forwarding_test.py b/net/test/forwarding_test.py index cf00af1..34394cd 100755 --- a/net/test/forwarding_test.py +++ b/net/test/forwarding_test.py @@ -24,21 +24,7 @@ import multinetwork_base import net_test import packets - class ForwardingTest(multinetwork_base.MultiNetworkBaseTest): - """Checks that IPv6 forwarding doesn't crash the system. - - Relevant kernel commits: - upstream net-next: - e7eadb4 ipv6: inet6_sk() should use sk_fullsock() - android-3.10: - feee3c1 ipv6: inet6_sk() should use sk_fullsock() - cdab04e net: add sk_fullsock() helper - android-3.18: - 8246f18 ipv6: inet6_sk() should use sk_fullsock() - bea19db net: add sk_fullsock() helper - """ - TCP_TIME_WAIT = 6 def ForwardBetweenInterfaces(self, enabled, iface1, iface2): @@ -52,7 +38,63 @@ class ForwardingTest(multinetwork_base.MultiNetworkBaseTest): def tearDown(self): self.SetSysctl("/proc/sys/net/ipv6/conf/all/forwarding", 0) - def CheckForwardingCrash(self, netid, iface1, iface2): + """Checks that IPv6 forwarding works for UDP packets and is not broken by early demux. + + Relevant kernel commits: + upstream: + 5425077d73e0c8e net: ipv6: Add early demux handler for UDP unicast + 0bd84065b19bca1 net: ipv6: Fix UDP early demux lookup with udp_l3mdev_accept=0 + Ifa9c2ddfaa5b51 net: ipv6: reset daddr and dport in sk if connect() fails + """ + def CheckForwardingUdp(self, netid, iface1, iface2): + # TODO: Make a test for IPv4 + # 1. Make version as an argument. Pick address to bind from array based + # on version. + # 2. The prefix length of the address is hardcoded to /64. Use the subnet + # mask there instead. + # 3. We recreate the address with SendRA, which obviously only works for + # IPv6. Use AddAddress for IPv4. + + # Create a UDP socket and bind to it + version = 6 + s = net_test.UDPSocket(AF_INET6) + self.SetSocketMark(s, netid) + s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) + s.bind(("::", 53)) + + remoteaddr = self.GetRemoteAddress(version) + myaddr = self.MyAddress(version, netid) + + try: + # Delete address and check if packet is forwarded + # (and not dropped because an incorrect socket match happened) + self.iproute.DelAddress(myaddr, 64, self.ifindices[netid]) + hoplimit = 39 + desc, udp_pkt = packets.UDPWithOptions(version, myaddr, remoteaddr, 53) + # Decrements the hoplimit of a packet to simulate forwarding. + desc_fwded, udp_fwd = packets.UDPWithOptions(version, myaddr, remoteaddr, + 53, hoplimit - 1) + msg = "Sent %s, expected %s" % (desc, desc_fwded) + self.ReceivePacketOn(iface1, udp_pkt) + self.ExpectPacketOn(iface2, msg, udp_fwd) + finally: + # Recreate the address. + self.SendRA(netid) + s.close() + + """Checks that IPv6 forwarding doesn't crash the system. + + Relevant kernel commits: + upstream net-next: + e7eadb4 ipv6: inet6_sk() should use sk_fullsock() + android-3.10: + feee3c1 ipv6: inet6_sk() should use sk_fullsock() + cdab04e net: add sk_fullsock() helper + android-3.18: + 8246f18 ipv6: inet6_sk() should use sk_fullsock() + bea19db net: add sk_fullsock() helper + """ + def CheckForwardingCrashTcp(self, netid, iface1, iface2): version = 6 listensocket = net_test.IPv6TCPSocket() self.SetSocketMark(listensocket, netid) @@ -101,17 +143,30 @@ class ForwardingTest(multinetwork_base.MultiNetworkBaseTest): self.SendRA(netid) listensocket.close() - def testCrash(self): + def CheckForwardingHandlerByProto(self, protocol, netid, iif, oif): + if protocol == IPPROTO_UDP: + self.CheckForwardingUdp(netid, iif, oif) + elif protocol == IPPROTO_TCP: + self.CheckForwardingCrashTcp(netid, iif, oif) + else: + raise NotImplementedError + + def CheckForwardingByProto(self, proto): # Run the test a few times as it doesn't crash/hang the first time. for netids in itertools.permutations(self.tuns): # Pick an interface to send traffic on and two to forward traffic between. netid, iface1, iface2 = random.sample(netids, 3) self.ForwardBetweenInterfaces(True, iface1, iface2) try: - self.CheckForwardingCrash(netid, iface1, iface2) + self.CheckForwardingHandlerByProto(proto, netid, iface1, iface2) finally: self.ForwardBetweenInterfaces(False, iface1, iface2) + def testForwardingUdp(self): + self.CheckForwardingByProto(IPPROTO_UDP) + + def testForwardingCrashTcp(self): + self.CheckForwardingByProto(IPPROTO_TCP) if __name__ == "__main__": unittest.main() diff --git a/net/test/packets.py b/net/test/packets.py index c36efe8..7ad77bb 100644 --- a/net/test/packets.py +++ b/net/test/packets.py @@ -61,14 +61,14 @@ def UDP(version, srcaddr, dstaddr, sport=0): ip(src=srcaddr, dst=dstaddr) / scapy.UDP(sport=sport, dport=53) / UDP_PAYLOAD) -def UDPWithOptions(version, srcaddr, dstaddr, sport=0): +def UDPWithOptions(version, srcaddr, dstaddr, sport=0, lifetime=39): if version == 4: - packet = (scapy.IP(src=srcaddr, dst=dstaddr, ttl=39, tos=0x83) / + packet = (scapy.IP(src=srcaddr, dst=dstaddr, ttl=lifetime, tos=0x83) / scapy.UDP(sport=sport, dport=53) / UDP_PAYLOAD) else: packet = (scapy.IPv6(src=srcaddr, dst=dstaddr, - fl=0xbeef, hlim=39, tc=0x83) / + fl=0xbeef, hlim=lifetime, tc=0x83) / scapy.UDP(sport=sport, dport=53) / UDP_PAYLOAD) return ("UDPv%d packet with options" % version, packet) |