gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/tests/utils/utils.go (about) 1 // Copyright 2020 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 utils holds common testing utilities for tcpip. 16 package utils 17 18 import ( 19 "testing" 20 21 "gvisor.dev/gvisor/pkg/buffer" 22 "gvisor.dev/gvisor/pkg/tcpip" 23 "gvisor.dev/gvisor/pkg/tcpip/checksum" 24 "gvisor.dev/gvisor/pkg/tcpip/header" 25 "gvisor.dev/gvisor/pkg/tcpip/link/channel" 26 "gvisor.dev/gvisor/pkg/tcpip/link/ethernet" 27 "gvisor.dev/gvisor/pkg/tcpip/link/nested" 28 "gvisor.dev/gvisor/pkg/tcpip/link/pipe" 29 "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" 30 "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" 31 "gvisor.dev/gvisor/pkg/tcpip/prependable" 32 "gvisor.dev/gvisor/pkg/tcpip/stack" 33 "gvisor.dev/gvisor/pkg/tcpip/testutil" 34 "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" 35 ) 36 37 // Common NIC IDs used by tests. 38 const ( 39 Host1NICID = 1 40 RouterNICID1 = 2 41 RouterNICID2 = 3 42 Host2NICID = 4 43 ) 44 45 // Common NIC names used by tests. 46 const ( 47 Host1NICName = "host1NIC" 48 RouterNIC1Name = "routerNIC1" 49 RouterNIC2Name = "routerNIC2" 50 Host2NICName = "host2NIC" 51 ) 52 53 // Common link addresses used by tests. 54 const ( 55 LinkAddr1 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x06") 56 LinkAddr2 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x07") 57 LinkAddr3 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x08") 58 LinkAddr4 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x09") 59 ) 60 61 // Common IP addresses used by tests. 62 var ( 63 Ipv4Addr = tcpip.AddressWithPrefix{ 64 Address: testutil.MustParse4("192.168.1.58"), 65 PrefixLen: 24, 66 } 67 Ipv4Subnet = Ipv4Addr.Subnet() 68 Ipv4SubnetBcast = Ipv4Subnet.Broadcast() 69 70 Ipv6Addr = tcpip.AddressWithPrefix{ 71 Address: testutil.MustParse6("200a::1"), 72 PrefixLen: 64, 73 } 74 Ipv6Subnet = Ipv6Addr.Subnet() 75 Ipv6SubnetBcast = Ipv6Subnet.Broadcast() 76 77 Ipv4Addr1 = tcpip.ProtocolAddress{ 78 Protocol: ipv4.ProtocolNumber, 79 AddressWithPrefix: tcpip.AddressWithPrefix{ 80 Address: testutil.MustParse4("192.168.0.1"), 81 PrefixLen: 24, 82 }, 83 } 84 Ipv4Addr2 = tcpip.ProtocolAddress{ 85 Protocol: ipv4.ProtocolNumber, 86 AddressWithPrefix: tcpip.AddressWithPrefix{ 87 Address: testutil.MustParse4("192.168.0.2"), 88 PrefixLen: 8, 89 }, 90 } 91 Ipv4Addr3 = tcpip.ProtocolAddress{ 92 Protocol: ipv4.ProtocolNumber, 93 AddressWithPrefix: tcpip.AddressWithPrefix{ 94 Address: testutil.MustParse4("192.168.0.3"), 95 PrefixLen: 8, 96 }, 97 } 98 Ipv6Addr1 = tcpip.ProtocolAddress{ 99 Protocol: ipv6.ProtocolNumber, 100 AddressWithPrefix: tcpip.AddressWithPrefix{ 101 Address: testutil.MustParse6("a::1"), 102 PrefixLen: 64, 103 }, 104 } 105 Ipv6Addr2 = tcpip.ProtocolAddress{ 106 Protocol: ipv6.ProtocolNumber, 107 AddressWithPrefix: tcpip.AddressWithPrefix{ 108 Address: testutil.MustParse6("a::2"), 109 PrefixLen: 64, 110 }, 111 } 112 Ipv6Addr3 = tcpip.ProtocolAddress{ 113 Protocol: ipv6.ProtocolNumber, 114 AddressWithPrefix: tcpip.AddressWithPrefix{ 115 Address: testutil.MustParse6("a::3"), 116 PrefixLen: 64, 117 }, 118 } 119 120 // Remote addrs. 121 RemoteIPv4Addr = testutil.MustParse4("10.0.0.1") 122 RemoteIPv6Addr = testutil.MustParse6("200b::1") 123 ) 124 125 // Common ports for testing. 126 const ( 127 RemotePort = 5555 128 LocalPort = 80 129 ) 130 131 // Common IP addresses used for testing. 132 var ( 133 Host1IPv4Addr = tcpip.ProtocolAddress{ 134 Protocol: ipv4.ProtocolNumber, 135 AddressWithPrefix: tcpip.AddressWithPrefix{ 136 Address: testutil.MustParse4("192.168.0.2"), 137 PrefixLen: 24, 138 }, 139 } 140 RouterNIC1IPv4Addr = tcpip.ProtocolAddress{ 141 Protocol: ipv4.ProtocolNumber, 142 AddressWithPrefix: tcpip.AddressWithPrefix{ 143 Address: testutil.MustParse4("192.168.0.1"), 144 PrefixLen: 24, 145 }, 146 } 147 RouterNIC2IPv4Addr = tcpip.ProtocolAddress{ 148 Protocol: ipv4.ProtocolNumber, 149 AddressWithPrefix: tcpip.AddressWithPrefix{ 150 Address: testutil.MustParse4("10.0.0.3"), 151 PrefixLen: 8, 152 }, 153 } 154 Host2IPv4Addr = tcpip.ProtocolAddress{ 155 Protocol: ipv4.ProtocolNumber, 156 AddressWithPrefix: tcpip.AddressWithPrefix{ 157 Address: testutil.MustParse4("10.0.0.2"), 158 PrefixLen: 8, 159 }, 160 } 161 Host1IPv6Addr = tcpip.ProtocolAddress{ 162 Protocol: ipv6.ProtocolNumber, 163 AddressWithPrefix: tcpip.AddressWithPrefix{ 164 Address: testutil.MustParse6("a::2"), 165 PrefixLen: 64, 166 }, 167 } 168 RouterNIC1IPv6Addr = tcpip.ProtocolAddress{ 169 Protocol: ipv6.ProtocolNumber, 170 AddressWithPrefix: tcpip.AddressWithPrefix{ 171 Address: testutil.MustParse6("a::1"), 172 PrefixLen: 64, 173 }, 174 } 175 RouterNIC2IPv6Addr = tcpip.ProtocolAddress{ 176 Protocol: ipv6.ProtocolNumber, 177 AddressWithPrefix: tcpip.AddressWithPrefix{ 178 Address: testutil.MustParse6("b::1"), 179 PrefixLen: 64, 180 }, 181 } 182 Host2IPv6Addr = tcpip.ProtocolAddress{ 183 Protocol: ipv6.ProtocolNumber, 184 AddressWithPrefix: tcpip.AddressWithPrefix{ 185 Address: testutil.MustParse6("b::2"), 186 PrefixLen: 64, 187 }, 188 } 189 ) 190 191 // NewEthernetEndpoint returns an ethernet link endpoint that wraps an inner 192 // link endpoint and checks the destination link address before delivering 193 // network packets to the network dispatcher. 194 // 195 // See ethernet.Endpoint for more details. 196 func NewEthernetEndpoint(ep stack.LinkEndpoint) *EndpointWithDestinationCheck { 197 var e EndpointWithDestinationCheck 198 e.Endpoint.Init(ethernet.New(ep), &e) 199 return &e 200 } 201 202 // EndpointWithDestinationCheck is a link endpoint that checks the destination 203 // link address before delivering network packets to the network dispatcher. 204 type EndpointWithDestinationCheck struct { 205 nested.Endpoint 206 } 207 208 var _ stack.NetworkDispatcher = (*EndpointWithDestinationCheck)(nil) 209 var _ stack.LinkEndpoint = (*EndpointWithDestinationCheck)(nil) 210 211 // DeliverNetworkPacket implements stack.NetworkDispatcher. 212 func (e *EndpointWithDestinationCheck) DeliverNetworkPacket(proto tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) { 213 if dst := header.Ethernet(pkt.LinkHeader().Slice()).DestinationAddress(); dst == e.Endpoint.LinkAddress() || dst == header.EthernetBroadcastAddress || header.IsMulticastEthernetAddress(dst) { 214 e.Endpoint.DeliverNetworkPacket(proto, pkt) 215 } 216 } 217 218 // SetupRouterStack creates the NICs, sets forwarding, adds addresses and sets 219 // the route table for a stack that should operate as a router. 220 func SetupRouterStack(t *testing.T, s *stack.Stack, ep1, ep2 stack.LinkEndpoint) { 221 222 if err := s.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true); err != nil { 223 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d): %s", ipv4.ProtocolNumber, err) 224 } 225 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil { 226 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d): %s", ipv6.ProtocolNumber, err) 227 } 228 229 for _, setup := range []struct { 230 nicID tcpip.NICID 231 nicName string 232 ep stack.LinkEndpoint 233 234 addresses [2]tcpip.ProtocolAddress 235 }{ 236 { 237 nicID: RouterNICID1, 238 nicName: RouterNIC1Name, 239 ep: ep1, 240 addresses: [2]tcpip.ProtocolAddress{RouterNIC1IPv4Addr, RouterNIC1IPv6Addr}, 241 }, 242 { 243 nicID: RouterNICID2, 244 nicName: RouterNIC2Name, 245 ep: ep2, 246 addresses: [2]tcpip.ProtocolAddress{RouterNIC2IPv4Addr, RouterNIC2IPv6Addr}, 247 }, 248 } { 249 opts := stack.NICOptions{Name: setup.nicName} 250 if err := s.CreateNICWithOptions(setup.nicID, setup.ep, opts); err != nil { 251 t.Fatalf("s.CreateNICWithOptions(%d, _, %#v): %s", setup.nicID, opts, err) 252 } 253 254 for _, addr := range setup.addresses { 255 if err := s.AddProtocolAddress(setup.nicID, addr, stack.AddressProperties{}); err != nil { 256 t.Fatalf("s.AddProtocolAddress(%d, %#v, {}): %s", setup.nicID, addr, err) 257 } 258 } 259 } 260 261 s.SetRouteTable([]tcpip.Route{ 262 { 263 Destination: RouterNIC1IPv4Addr.AddressWithPrefix.Subnet(), 264 NIC: RouterNICID1, 265 }, 266 { 267 Destination: RouterNIC1IPv6Addr.AddressWithPrefix.Subnet(), 268 NIC: RouterNICID1, 269 }, 270 { 271 Destination: RouterNIC2IPv4Addr.AddressWithPrefix.Subnet(), 272 NIC: RouterNICID2, 273 }, 274 { 275 Destination: RouterNIC2IPv6Addr.AddressWithPrefix.Subnet(), 276 NIC: RouterNICID2, 277 }, 278 }) 279 } 280 281 // SetupRoutedStacks creates the NICs, sets forwarding, adds addresses and sets 282 // the route tables for the passed stacks. 283 func SetupRoutedStacks(t *testing.T, host1Stack, routerStack, host2Stack *stack.Stack) { 284 const maxFrameSize = header.IPv6MinimumMTU + header.EthernetMinimumSize 285 host1NIC, routerNIC1 := pipe.New(LinkAddr1, LinkAddr2, maxFrameSize) 286 routerNIC2, host2NIC := pipe.New(LinkAddr3, LinkAddr4, maxFrameSize) 287 288 SetupRouterStack(t, routerStack, NewEthernetEndpoint(routerNIC1), NewEthernetEndpoint(routerNIC2)) 289 290 { 291 opts := stack.NICOptions{Name: Host1NICName} 292 if err := host1Stack.CreateNICWithOptions(Host1NICID, NewEthernetEndpoint(host1NIC), opts); err != nil { 293 t.Fatalf("host1Stack.CreateNICWithOptions(%d, _, %#v): %s", Host1NICID, opts, err) 294 } 295 } 296 { 297 opts := stack.NICOptions{Name: Host2NICName} 298 if err := host2Stack.CreateNICWithOptions(Host2NICID, NewEthernetEndpoint(host2NIC), opts); err != nil { 299 t.Fatalf("host2Stack.CreateNICWithOptions(%d, _, %#v): %s", Host2NICID, opts, err) 300 } 301 } 302 303 if err := host1Stack.AddProtocolAddress(Host1NICID, Host1IPv4Addr, stack.AddressProperties{}); err != nil { 304 t.Fatalf("host1Stack.AddProtocolAddress(%d, %+v, {}): %s", Host1NICID, Host1IPv4Addr, err) 305 } 306 if err := host2Stack.AddProtocolAddress(Host2NICID, Host2IPv4Addr, stack.AddressProperties{}); err != nil { 307 t.Fatalf("host2Stack.AddProtocolAddress(%d, %+v, {}): %s", Host2NICID, Host2IPv4Addr, err) 308 } 309 if err := host1Stack.AddProtocolAddress(Host1NICID, Host1IPv6Addr, stack.AddressProperties{}); err != nil { 310 t.Fatalf("host1Stack.AddProtocolAddress(%d, %+v, {}): %s", Host1NICID, Host1IPv6Addr, err) 311 } 312 if err := host2Stack.AddProtocolAddress(Host2NICID, Host2IPv6Addr, stack.AddressProperties{}); err != nil { 313 t.Fatalf("host2Stack.AddProtocolAddress(%d, %+v, {}): %s", Host2NICID, Host2IPv6Addr, err) 314 } 315 316 host1Stack.SetRouteTable([]tcpip.Route{ 317 { 318 Destination: Host1IPv4Addr.AddressWithPrefix.Subnet(), 319 NIC: Host1NICID, 320 }, 321 { 322 Destination: Host1IPv6Addr.AddressWithPrefix.Subnet(), 323 NIC: Host1NICID, 324 }, 325 { 326 Destination: Host2IPv4Addr.AddressWithPrefix.Subnet(), 327 Gateway: RouterNIC1IPv4Addr.AddressWithPrefix.Address, 328 NIC: Host1NICID, 329 }, 330 { 331 Destination: Host2IPv6Addr.AddressWithPrefix.Subnet(), 332 Gateway: RouterNIC1IPv6Addr.AddressWithPrefix.Address, 333 NIC: Host1NICID, 334 }, 335 }) 336 host2Stack.SetRouteTable([]tcpip.Route{ 337 { 338 Destination: Host2IPv4Addr.AddressWithPrefix.Subnet(), 339 NIC: Host2NICID, 340 }, 341 { 342 Destination: Host2IPv6Addr.AddressWithPrefix.Subnet(), 343 NIC: Host2NICID, 344 }, 345 { 346 Destination: Host1IPv4Addr.AddressWithPrefix.Subnet(), 347 Gateway: RouterNIC2IPv4Addr.AddressWithPrefix.Address, 348 NIC: Host2NICID, 349 }, 350 { 351 Destination: Host1IPv6Addr.AddressWithPrefix.Subnet(), 352 Gateway: RouterNIC2IPv6Addr.AddressWithPrefix.Address, 353 NIC: Host2NICID, 354 }, 355 }) 356 } 357 358 // ICMPv4Echo returns an ICMPv4 echo packet. 359 func ICMPv4Echo(src, dst tcpip.Address, ttl uint8, ty header.ICMPv4Type) []byte { 360 totalLen := header.IPv4MinimumSize + header.ICMPv4MinimumSize 361 hdr := prependable.New(totalLen) 362 pkt := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize)) 363 pkt.SetType(ty) 364 pkt.SetCode(header.ICMPv4UnusedCode) 365 pkt.SetChecksum(0) 366 pkt.SetChecksum(^checksum.Checksum(pkt, 0)) 367 ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) 368 ip.Encode(&header.IPv4Fields{ 369 TotalLength: uint16(totalLen), 370 Protocol: uint8(icmp.ProtocolNumber4), 371 TTL: ttl, 372 SrcAddr: src, 373 DstAddr: dst, 374 }) 375 ip.SetChecksum(^ip.CalculateChecksum()) 376 return hdr.View() 377 } 378 379 // RxICMPv4EchoRequest constructs and injects an ICMPv4 echo request packet on 380 // the provided endpoint. 381 func RxICMPv4EchoRequest(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) { 382 newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 383 Payload: buffer.MakeWithData(ICMPv4Echo(src, dst, ttl, header.ICMPv4Echo)), 384 }) 385 defer newPkt.DecRef() 386 e.InjectInbound(header.IPv4ProtocolNumber, newPkt) 387 } 388 389 // RxICMPv4EchoReply constructs and injects an ICMPv4 echo reply packet on 390 // the provided endpoint. 391 func RxICMPv4EchoReply(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) { 392 newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 393 Payload: buffer.MakeWithData(ICMPv4Echo(src, dst, ttl, header.ICMPv4EchoReply)), 394 }) 395 defer newPkt.DecRef() 396 e.InjectInbound(header.IPv4ProtocolNumber, newPkt) 397 } 398 399 // ICMPv6Echo returns an ICMPv6 echo packet. 400 func ICMPv6Echo(src, dst tcpip.Address, ttl uint8, ty header.ICMPv6Type) []byte { 401 totalLen := header.IPv6MinimumSize + header.ICMPv6MinimumSize 402 hdr := prependable.New(totalLen) 403 pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6MinimumSize)) 404 pkt.SetType(ty) 405 pkt.SetCode(header.ICMPv6UnusedCode) 406 pkt.SetChecksum(0) 407 pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{ 408 Header: pkt, 409 Src: src, 410 Dst: dst, 411 })) 412 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 413 ip.Encode(&header.IPv6Fields{ 414 PayloadLength: header.ICMPv6MinimumSize, 415 TransportProtocol: icmp.ProtocolNumber6, 416 HopLimit: ttl, 417 SrcAddr: src, 418 DstAddr: dst, 419 }) 420 return hdr.View() 421 } 422 423 // RxICMPv6EchoRequest constructs and injects an ICMPv6 echo request packet on 424 // the provided endpoint. 425 func RxICMPv6EchoRequest(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) { 426 newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 427 Payload: buffer.MakeWithData(ICMPv6Echo(src, dst, ttl, header.ICMPv6EchoRequest)), 428 }) 429 defer newPkt.DecRef() 430 e.InjectInbound(header.IPv6ProtocolNumber, newPkt) 431 } 432 433 // RxICMPv6EchoReply constructs and injects an ICMPv6 echo reply packet on 434 // the provided endpoint. 435 func RxICMPv6EchoReply(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) { 436 newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 437 Payload: buffer.MakeWithData(ICMPv6Echo(src, dst, ttl, header.ICMPv6EchoReply)), 438 }) 439 defer newPkt.DecRef() 440 e.InjectInbound(header.IPv6ProtocolNumber, newPkt) 441 }