github.com/flowerwrong/netstack@v0.0.0-20191009141956-e5848263af28/tcpip/network/ipv6/ipv6_test.go (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ipv6 16 17 import ( 18 "testing" 19 20 "github.com/FlowerWrong/netstack/tcpip" 21 "github.com/FlowerWrong/netstack/tcpip/buffer" 22 "github.com/FlowerWrong/netstack/tcpip/header" 23 "github.com/FlowerWrong/netstack/tcpip/link/channel" 24 "github.com/FlowerWrong/netstack/tcpip/stack" 25 "github.com/FlowerWrong/netstack/tcpip/transport/icmp" 26 "github.com/FlowerWrong/netstack/tcpip/transport/udp" 27 "github.com/FlowerWrong/netstack/waiter" 28 ) 29 30 const ( 31 addr1 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" 32 addr2 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" 33 // The least significant 3 bytes are the same as addr2 so both addr2 and 34 // addr3 will have the same solicited-node address. 35 addr3 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x02" 36 ) 37 38 // testReceiveICMP tests receiving an ICMP packet from src to dst. want is the 39 // expected Neighbor Advertisement received count after receiving the packet. 40 func testReceiveICMP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) { 41 t.Helper() 42 43 // Receive ICMP packet. 44 hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) 45 pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) 46 pkt.SetType(header.ICMPv6NeighborAdvert) 47 pkt.SetChecksum(header.ICMPv6Checksum(pkt, src, dst, buffer.VectorisedView{})) 48 payloadLength := hdr.UsedLength() 49 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 50 ip.Encode(&header.IPv6Fields{ 51 PayloadLength: uint16(payloadLength), 52 NextHeader: uint8(header.ICMPv6ProtocolNumber), 53 HopLimit: 255, 54 SrcAddr: src, 55 DstAddr: dst, 56 }) 57 58 e.Inject(ProtocolNumber, hdr.View().ToVectorisedView()) 59 60 stats := s.Stats().ICMP.V6PacketsReceived 61 62 if got := stats.NeighborAdvert.Value(); got != want { 63 t.Fatalf("got NeighborAdvert = %d, want = %d", got, want) 64 } 65 } 66 67 // testReceiveICMP tests receiving a UDP packet from src to dst. want is the 68 // expected UDP received count after receiving the packet. 69 func testReceiveUDP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) { 70 t.Helper() 71 72 wq := waiter.Queue{} 73 we, ch := waiter.NewChannelEntry(nil) 74 wq.EventRegister(&we, waiter.EventIn) 75 defer wq.EventUnregister(&we) 76 defer close(ch) 77 78 ep, err := s.NewEndpoint(udp.ProtocolNumber, ProtocolNumber, &wq) 79 if err != nil { 80 t.Fatalf("NewEndpoint failed: %v", err) 81 } 82 defer ep.Close() 83 84 if err := ep.Bind(tcpip.FullAddress{Addr: dst, Port: 80}); err != nil { 85 t.Fatalf("ep.Bind(...) failed: %v", err) 86 } 87 88 // Receive UDP Packet. 89 hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.UDPMinimumSize) 90 u := header.UDP(hdr.Prepend(header.UDPMinimumSize)) 91 u.Encode(&header.UDPFields{ 92 SrcPort: 5555, 93 DstPort: 80, 94 Length: header.UDPMinimumSize, 95 }) 96 97 // UDP pseudo-header checksum. 98 sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, src, dst, header.UDPMinimumSize) 99 100 // UDP checksum 101 sum = header.Checksum(header.UDP([]byte{}), sum) 102 u.SetChecksum(^u.CalculateChecksum(sum)) 103 104 payloadLength := hdr.UsedLength() 105 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 106 ip.Encode(&header.IPv6Fields{ 107 PayloadLength: uint16(payloadLength), 108 NextHeader: uint8(udp.ProtocolNumber), 109 HopLimit: 255, 110 SrcAddr: src, 111 DstAddr: dst, 112 }) 113 114 e.Inject(ProtocolNumber, hdr.View().ToVectorisedView()) 115 116 stat := s.Stats().UDP.PacketsReceived 117 118 if got := stat.Value(); got != want { 119 t.Fatalf("got UDPPacketsReceived = %d, want = %d", got, want) 120 } 121 } 122 123 // TestReceiveOnAllNodesMulticastAddr tests that IPv6 endpoints receive ICMP and 124 // UDP packets destined to the IPv6 link-local all-nodes multicast address. 125 func TestReceiveOnAllNodesMulticastAddr(t *testing.T) { 126 tests := []struct { 127 name string 128 protocolFactory stack.TransportProtocol 129 rxf func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) 130 }{ 131 {"ICMP", icmp.NewProtocol6(), testReceiveICMP}, 132 {"UDP", udp.NewProtocol(), testReceiveUDP}, 133 } 134 135 for _, test := range tests { 136 t.Run(test.name, func(t *testing.T) { 137 s := stack.New(stack.Options{ 138 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 139 TransportProtocols: []stack.TransportProtocol{test.protocolFactory}, 140 }) 141 e := channel.New(10, 1280, linkAddr1) 142 if err := s.CreateNIC(1, e); err != nil { 143 t.Fatalf("CreateNIC(_) = %s", err) 144 } 145 146 // Should receive a packet destined to the all-nodes 147 // multicast address. 148 test.rxf(t, s, e, addr1, header.IPv6AllNodesMulticastAddress, 1) 149 }) 150 } 151 } 152 153 // TestReceiveOnSolicitedNodeAddr tests that IPv6 endpoints receive ICMP and UDP 154 // packets destined to the IPv6 solicited-node address of an assigned IPv6 155 // address. 156 func TestReceiveOnSolicitedNodeAddr(t *testing.T) { 157 tests := []struct { 158 name string 159 protocolFactory stack.TransportProtocol 160 rxf func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) 161 }{ 162 {"ICMP", icmp.NewProtocol6(), testReceiveICMP}, 163 {"UDP", udp.NewProtocol(), testReceiveUDP}, 164 } 165 166 snmc := header.SolicitedNodeAddr(addr2) 167 168 for _, test := range tests { 169 t.Run(test.name, func(t *testing.T) { 170 s := stack.New(stack.Options{ 171 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 172 TransportProtocols: []stack.TransportProtocol{test.protocolFactory}, 173 }) 174 e := channel.New(10, 1280, linkAddr1) 175 if err := s.CreateNIC(1, e); err != nil { 176 t.Fatalf("CreateNIC(_) = %s", err) 177 } 178 179 // Should not receive a packet destined to the solicited 180 // node address of addr2/addr3 yet as we haven't added 181 // those addresses. 182 test.rxf(t, s, e, addr1, snmc, 0) 183 184 if err := s.AddAddress(1, ProtocolNumber, addr2); err != nil { 185 t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, addr2, err) 186 } 187 188 // Should receive a packet destined to the solicited 189 // node address of addr2/addr3 now that we have added 190 // added addr2. 191 test.rxf(t, s, e, addr1, snmc, 1) 192 193 if err := s.AddAddress(1, ProtocolNumber, addr3); err != nil { 194 t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, addr3, err) 195 } 196 197 // Should still receive a packet destined to the 198 // solicited node address of addr2/addr3 now that we 199 // have added addr3. 200 test.rxf(t, s, e, addr1, snmc, 2) 201 202 if err := s.RemoveAddress(1, addr2); err != nil { 203 t.Fatalf("RemoveAddress(_, %s) = %s", addr2, err) 204 } 205 206 // Should still receive a packet destined to the 207 // solicited node address of addr2/addr3 now that we 208 // have removed addr2. 209 test.rxf(t, s, e, addr1, snmc, 3) 210 211 if err := s.RemoveAddress(1, addr3); err != nil { 212 t.Fatalf("RemoveAddress(_, %s) = %s", addr3, err) 213 } 214 215 // Should not receive a packet destined to the solicited 216 // node address of addr2/addr3 yet as both of them got 217 // removed. 218 test.rxf(t, s, e, addr1, snmc, 3) 219 }) 220 } 221 } 222 223 // TestAddIpv6Address tests adding IPv6 addresses. 224 func TestAddIpv6Address(t *testing.T) { 225 tests := []struct { 226 name string 227 addr tcpip.Address 228 }{ 229 // This test is in response to b/140943433. 230 { 231 "Nil", 232 tcpip.Address([]byte(nil)), 233 }, 234 { 235 "ValidUnicast", 236 addr1, 237 }, 238 { 239 "ValidLinkLocalUnicast", 240 lladdr0, 241 }, 242 } 243 244 for _, test := range tests { 245 t.Run(test.name, func(t *testing.T) { 246 s := stack.New(stack.Options{ 247 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 248 }) 249 if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil { 250 t.Fatalf("CreateNIC(_) = %s", err) 251 } 252 253 if err := s.AddAddress(1, ProtocolNumber, test.addr); err != nil { 254 t.Fatalf("AddAddress(_, %d, nil) = %s", ProtocolNumber, err) 255 } 256 257 addr, err := s.GetMainNICAddress(1, header.IPv6ProtocolNumber) 258 if err != nil { 259 t.Fatalf("stack.GetMainNICAddress(_, _) err = %s", err) 260 } 261 if addr.Address != test.addr { 262 t.Fatalf("got stack.GetMainNICAddress(_, _) = %s, want = %s", addr.Address, test.addr) 263 } 264 }) 265 } 266 }