github.com/google/netstack@v0.0.0-20191123085552-55fcc16cd0eb/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/google/netstack/tcpip" 21 "github.com/google/netstack/tcpip/buffer" 22 "github.com/google/netstack/tcpip/header" 23 "github.com/google/netstack/tcpip/link/channel" 24 "github.com/google/netstack/tcpip/stack" 25 "github.com/google/netstack/tcpip/transport/icmp" 26 "github.com/google/netstack/tcpip/transport/udp" 27 "github.com/google/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.InjectInbound(ProtocolNumber, tcpip.PacketBuffer{ 59 Data: hdr.View().ToVectorisedView(), 60 }) 61 62 stats := s.Stats().ICMP.V6PacketsReceived 63 64 if got := stats.NeighborAdvert.Value(); got != want { 65 t.Fatalf("got NeighborAdvert = %d, want = %d", got, want) 66 } 67 } 68 69 // testReceiveUDP tests receiving a UDP packet from src to dst. want is the 70 // expected UDP received count after receiving the packet. 71 func testReceiveUDP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) { 72 t.Helper() 73 74 wq := waiter.Queue{} 75 we, ch := waiter.NewChannelEntry(nil) 76 wq.EventRegister(&we, waiter.EventIn) 77 defer wq.EventUnregister(&we) 78 defer close(ch) 79 80 ep, err := s.NewEndpoint(udp.ProtocolNumber, ProtocolNumber, &wq) 81 if err != nil { 82 t.Fatalf("NewEndpoint failed: %v", err) 83 } 84 defer ep.Close() 85 86 if err := ep.Bind(tcpip.FullAddress{Addr: dst, Port: 80}); err != nil { 87 t.Fatalf("ep.Bind(...) failed: %v", err) 88 } 89 90 // Receive UDP Packet. 91 hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.UDPMinimumSize) 92 u := header.UDP(hdr.Prepend(header.UDPMinimumSize)) 93 u.Encode(&header.UDPFields{ 94 SrcPort: 5555, 95 DstPort: 80, 96 Length: header.UDPMinimumSize, 97 }) 98 99 // UDP pseudo-header checksum. 100 sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, src, dst, header.UDPMinimumSize) 101 102 // UDP checksum 103 sum = header.Checksum(header.UDP([]byte{}), sum) 104 u.SetChecksum(^u.CalculateChecksum(sum)) 105 106 payloadLength := hdr.UsedLength() 107 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 108 ip.Encode(&header.IPv6Fields{ 109 PayloadLength: uint16(payloadLength), 110 NextHeader: uint8(udp.ProtocolNumber), 111 HopLimit: 255, 112 SrcAddr: src, 113 DstAddr: dst, 114 }) 115 116 e.InjectInbound(ProtocolNumber, tcpip.PacketBuffer{ 117 Data: hdr.View().ToVectorisedView(), 118 }) 119 120 stat := s.Stats().UDP.PacketsReceived 121 122 if got := stat.Value(); got != want { 123 t.Fatalf("got UDPPacketsReceived = %d, want = %d", got, want) 124 } 125 } 126 127 // TestReceiveOnAllNodesMulticastAddr tests that IPv6 endpoints receive ICMP and 128 // UDP packets destined to the IPv6 link-local all-nodes multicast address. 129 func TestReceiveOnAllNodesMulticastAddr(t *testing.T) { 130 tests := []struct { 131 name string 132 protocolFactory stack.TransportProtocol 133 rxf func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) 134 }{ 135 {"ICMP", icmp.NewProtocol6(), testReceiveICMP}, 136 {"UDP", udp.NewProtocol(), testReceiveUDP}, 137 } 138 139 for _, test := range tests { 140 t.Run(test.name, func(t *testing.T) { 141 s := stack.New(stack.Options{ 142 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 143 TransportProtocols: []stack.TransportProtocol{test.protocolFactory}, 144 }) 145 e := channel.New(10, 1280, linkAddr1) 146 if err := s.CreateNIC(1, e); err != nil { 147 t.Fatalf("CreateNIC(_) = %s", err) 148 } 149 150 // Should receive a packet destined to the all-nodes 151 // multicast address. 152 test.rxf(t, s, e, addr1, header.IPv6AllNodesMulticastAddress, 1) 153 }) 154 } 155 } 156 157 // TestReceiveOnSolicitedNodeAddr tests that IPv6 endpoints receive ICMP and UDP 158 // packets destined to the IPv6 solicited-node address of an assigned IPv6 159 // address. 160 func TestReceiveOnSolicitedNodeAddr(t *testing.T) { 161 tests := []struct { 162 name string 163 protocolFactory stack.TransportProtocol 164 rxf func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) 165 }{ 166 {"ICMP", icmp.NewProtocol6(), testReceiveICMP}, 167 {"UDP", udp.NewProtocol(), testReceiveUDP}, 168 } 169 170 snmc := header.SolicitedNodeAddr(addr2) 171 172 for _, test := range tests { 173 t.Run(test.name, func(t *testing.T) { 174 s := stack.New(stack.Options{ 175 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 176 TransportProtocols: []stack.TransportProtocol{test.protocolFactory}, 177 }) 178 e := channel.New(10, 1280, linkAddr1) 179 if err := s.CreateNIC(1, e); err != nil { 180 t.Fatalf("CreateNIC(_) = %s", err) 181 } 182 183 // Should not receive a packet destined to the solicited 184 // node address of addr2/addr3 yet as we haven't added 185 // those addresses. 186 test.rxf(t, s, e, addr1, snmc, 0) 187 188 if err := s.AddAddress(1, ProtocolNumber, addr2); err != nil { 189 t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, addr2, err) 190 } 191 192 // Should receive a packet destined to the solicited 193 // node address of addr2/addr3 now that we have added 194 // added addr2. 195 test.rxf(t, s, e, addr1, snmc, 1) 196 197 if err := s.AddAddress(1, ProtocolNumber, addr3); err != nil { 198 t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, addr3, err) 199 } 200 201 // Should still receive a packet destined to the 202 // solicited node address of addr2/addr3 now that we 203 // have added addr3. 204 test.rxf(t, s, e, addr1, snmc, 2) 205 206 if err := s.RemoveAddress(1, addr2); err != nil { 207 t.Fatalf("RemoveAddress(_, %s) = %s", addr2, err) 208 } 209 210 // Should still receive a packet destined to the 211 // solicited node address of addr2/addr3 now that we 212 // have removed addr2. 213 test.rxf(t, s, e, addr1, snmc, 3) 214 215 if err := s.RemoveAddress(1, addr3); err != nil { 216 t.Fatalf("RemoveAddress(_, %s) = %s", addr3, err) 217 } 218 219 // Should not receive a packet destined to the solicited 220 // node address of addr2/addr3 yet as both of them got 221 // removed. 222 test.rxf(t, s, e, addr1, snmc, 3) 223 }) 224 } 225 } 226 227 // TestAddIpv6Address tests adding IPv6 addresses. 228 func TestAddIpv6Address(t *testing.T) { 229 tests := []struct { 230 name string 231 addr tcpip.Address 232 }{ 233 // This test is in response to b/140943433. 234 { 235 "Nil", 236 tcpip.Address([]byte(nil)), 237 }, 238 { 239 "ValidUnicast", 240 addr1, 241 }, 242 { 243 "ValidLinkLocalUnicast", 244 lladdr0, 245 }, 246 } 247 248 for _, test := range tests { 249 t.Run(test.name, func(t *testing.T) { 250 s := stack.New(stack.Options{ 251 NetworkProtocols: []stack.NetworkProtocol{NewProtocol()}, 252 }) 253 if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil { 254 t.Fatalf("CreateNIC(_) = %s", err) 255 } 256 257 if err := s.AddAddress(1, ProtocolNumber, test.addr); err != nil { 258 t.Fatalf("AddAddress(_, %d, nil) = %s", ProtocolNumber, err) 259 } 260 261 addr, err := s.GetMainNICAddress(1, header.IPv6ProtocolNumber) 262 if err != nil { 263 t.Fatalf("stack.GetMainNICAddress(_, _) err = %s", err) 264 } 265 if addr.Address != test.addr { 266 t.Fatalf("got stack.GetMainNICAddress(_, _) = %s, want = %s", addr.Address, test.addr) 267 } 268 }) 269 } 270 }