github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/tests/integration/iptables_test.go (about) 1 // Copyright 2021 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 iptables_test 16 17 import ( 18 "testing" 19 20 "github.com/SagerNet/gvisor/pkg/tcpip" 21 "github.com/SagerNet/gvisor/pkg/tcpip/buffer" 22 "github.com/SagerNet/gvisor/pkg/tcpip/checker" 23 "github.com/SagerNet/gvisor/pkg/tcpip/header" 24 "github.com/SagerNet/gvisor/pkg/tcpip/link/channel" 25 "github.com/SagerNet/gvisor/pkg/tcpip/network/ipv4" 26 "github.com/SagerNet/gvisor/pkg/tcpip/network/ipv6" 27 "github.com/SagerNet/gvisor/pkg/tcpip/stack" 28 "github.com/SagerNet/gvisor/pkg/tcpip/tests/utils" 29 "github.com/SagerNet/gvisor/pkg/tcpip/testutil" 30 "github.com/SagerNet/gvisor/pkg/tcpip/transport/udp" 31 ) 32 33 type inputIfNameMatcher struct { 34 name string 35 } 36 37 var _ stack.Matcher = (*inputIfNameMatcher)(nil) 38 39 func (*inputIfNameMatcher) Name() string { 40 return "inputIfNameMatcher" 41 } 42 43 func (im *inputIfNameMatcher) Match(hook stack.Hook, _ *stack.PacketBuffer, inNicName, _ string) (bool, bool) { 44 return (hook == stack.Input && im.name != "" && im.name == inNicName), false 45 } 46 47 const ( 48 nicID = 1 49 nicName = "nic1" 50 anotherNicName = "nic2" 51 linkAddr = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e") 52 srcAddrV4 = "\x0a\x00\x00\x01" 53 dstAddrV4 = "\x0a\x00\x00\x02" 54 srcAddrV6 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" 55 dstAddrV6 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" 56 payloadSize = 20 57 ) 58 59 func genStackV6(t *testing.T) (*stack.Stack, *channel.Endpoint) { 60 t.Helper() 61 s := stack.New(stack.Options{ 62 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol}, 63 }) 64 e := channel.New(0, header.IPv6MinimumMTU, linkAddr) 65 nicOpts := stack.NICOptions{Name: nicName} 66 if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil { 67 t.Fatalf("CreateNICWithOptions(%d, _, %#v) = %s", nicID, nicOpts, err) 68 } 69 if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, dstAddrV6); err != nil { 70 t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, dstAddrV6, err) 71 } 72 return s, e 73 } 74 75 func genStackV4(t *testing.T) (*stack.Stack, *channel.Endpoint) { 76 t.Helper() 77 s := stack.New(stack.Options{ 78 NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, 79 }) 80 e := channel.New(0, header.IPv4MinimumMTU, linkAddr) 81 nicOpts := stack.NICOptions{Name: nicName} 82 if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil { 83 t.Fatalf("CreateNICWithOptions(%d, _, %#v) = %s", nicID, nicOpts, err) 84 } 85 if err := s.AddAddress(nicID, header.IPv4ProtocolNumber, dstAddrV4); err != nil { 86 t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv4ProtocolNumber, dstAddrV4, err) 87 } 88 return s, e 89 } 90 91 func genPacketV6() *stack.PacketBuffer { 92 pktSize := header.IPv6MinimumSize + payloadSize 93 hdr := buffer.NewPrependable(pktSize) 94 ip := header.IPv6(hdr.Prepend(pktSize)) 95 ip.Encode(&header.IPv6Fields{ 96 PayloadLength: payloadSize, 97 TransportProtocol: 99, 98 HopLimit: 255, 99 SrcAddr: srcAddrV6, 100 DstAddr: dstAddrV6, 101 }) 102 vv := hdr.View().ToVectorisedView() 103 return stack.NewPacketBuffer(stack.PacketBufferOptions{Data: vv}) 104 } 105 106 func genPacketV4() *stack.PacketBuffer { 107 pktSize := header.IPv4MinimumSize + payloadSize 108 hdr := buffer.NewPrependable(pktSize) 109 ip := header.IPv4(hdr.Prepend(pktSize)) 110 ip.Encode(&header.IPv4Fields{ 111 TOS: 0, 112 TotalLength: uint16(pktSize), 113 ID: 1, 114 Flags: 0, 115 FragmentOffset: 16, 116 TTL: 48, 117 Protocol: 99, 118 SrcAddr: srcAddrV4, 119 DstAddr: dstAddrV4, 120 }) 121 ip.SetChecksum(0) 122 ip.SetChecksum(^ip.CalculateChecksum()) 123 vv := hdr.View().ToVectorisedView() 124 return stack.NewPacketBuffer(stack.PacketBufferOptions{Data: vv}) 125 } 126 127 func TestIPTablesStatsForInput(t *testing.T) { 128 tests := []struct { 129 name string 130 setupStack func(*testing.T) (*stack.Stack, *channel.Endpoint) 131 setupFilter func(*testing.T, *stack.Stack) 132 genPacket func() *stack.PacketBuffer 133 proto tcpip.NetworkProtocolNumber 134 expectReceived int 135 expectInputDropped int 136 }{ 137 { 138 name: "IPv6 Accept", 139 setupStack: genStackV6, 140 setupFilter: func(*testing.T, *stack.Stack) { /* no filter */ }, 141 genPacket: genPacketV6, 142 proto: header.IPv6ProtocolNumber, 143 expectReceived: 1, 144 expectInputDropped: 0, 145 }, 146 { 147 name: "IPv4 Accept", 148 setupStack: genStackV4, 149 setupFilter: func(*testing.T, *stack.Stack) { /* no filter */ }, 150 genPacket: genPacketV4, 151 proto: header.IPv4ProtocolNumber, 152 expectReceived: 1, 153 expectInputDropped: 0, 154 }, 155 { 156 name: "IPv6 Drop (input interface matches)", 157 setupStack: genStackV6, 158 setupFilter: func(t *testing.T, s *stack.Stack) { 159 t.Helper() 160 ipt := s.IPTables() 161 filter := ipt.GetTable(stack.FilterID, true /* ipv6 */) 162 ruleIdx := filter.BuiltinChains[stack.Input] 163 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: nicName} 164 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 165 filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{nicName}} 166 // Make sure the packet is not dropped by the next rule. 167 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 168 if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil { 169 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, true, err) 170 } 171 }, 172 genPacket: genPacketV6, 173 proto: header.IPv6ProtocolNumber, 174 expectReceived: 1, 175 expectInputDropped: 1, 176 }, 177 { 178 name: "IPv4 Drop (input interface matches)", 179 setupStack: genStackV4, 180 setupFilter: func(t *testing.T, s *stack.Stack) { 181 t.Helper() 182 ipt := s.IPTables() 183 filter := ipt.GetTable(stack.FilterID, false /* ipv6 */) 184 ruleIdx := filter.BuiltinChains[stack.Input] 185 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: nicName} 186 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 187 filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{nicName}} 188 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 189 if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil { 190 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, false, err) 191 } 192 }, 193 genPacket: genPacketV4, 194 proto: header.IPv4ProtocolNumber, 195 expectReceived: 1, 196 expectInputDropped: 1, 197 }, 198 { 199 name: "IPv6 Accept (input interface does not match)", 200 setupStack: genStackV6, 201 setupFilter: func(t *testing.T, s *stack.Stack) { 202 t.Helper() 203 ipt := s.IPTables() 204 filter := ipt.GetTable(stack.FilterID, true /* ipv6 */) 205 ruleIdx := filter.BuiltinChains[stack.Input] 206 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: anotherNicName} 207 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 208 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 209 if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil { 210 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, true, err) 211 } 212 }, 213 genPacket: genPacketV6, 214 proto: header.IPv6ProtocolNumber, 215 expectReceived: 1, 216 expectInputDropped: 0, 217 }, 218 { 219 name: "IPv4 Accept (input interface does not match)", 220 setupStack: genStackV4, 221 setupFilter: func(t *testing.T, s *stack.Stack) { 222 t.Helper() 223 ipt := s.IPTables() 224 filter := ipt.GetTable(stack.FilterID, false /* ipv6 */) 225 ruleIdx := filter.BuiltinChains[stack.Input] 226 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: anotherNicName} 227 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 228 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 229 if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil { 230 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, false, err) 231 } 232 }, 233 genPacket: genPacketV4, 234 proto: header.IPv4ProtocolNumber, 235 expectReceived: 1, 236 expectInputDropped: 0, 237 }, 238 { 239 name: "IPv6 Drop (input interface does not match but invert is true)", 240 setupStack: genStackV6, 241 setupFilter: func(t *testing.T, s *stack.Stack) { 242 t.Helper() 243 ipt := s.IPTables() 244 filter := ipt.GetTable(stack.FilterID, true /* ipv6 */) 245 ruleIdx := filter.BuiltinChains[stack.Input] 246 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{ 247 InputInterface: anotherNicName, 248 InputInterfaceInvert: true, 249 } 250 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 251 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 252 if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil { 253 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, true, err) 254 } 255 }, 256 genPacket: genPacketV6, 257 proto: header.IPv6ProtocolNumber, 258 expectReceived: 1, 259 expectInputDropped: 1, 260 }, 261 { 262 name: "IPv4 Drop (input interface does not match but invert is true)", 263 setupStack: genStackV4, 264 setupFilter: func(t *testing.T, s *stack.Stack) { 265 t.Helper() 266 ipt := s.IPTables() 267 filter := ipt.GetTable(stack.FilterID, false /* ipv6 */) 268 ruleIdx := filter.BuiltinChains[stack.Input] 269 filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{ 270 InputInterface: anotherNicName, 271 InputInterfaceInvert: true, 272 } 273 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 274 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 275 if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil { 276 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, false, err) 277 } 278 }, 279 genPacket: genPacketV4, 280 proto: header.IPv4ProtocolNumber, 281 expectReceived: 1, 282 expectInputDropped: 1, 283 }, 284 { 285 name: "IPv6 Accept (input interface does not match using a matcher)", 286 setupStack: genStackV6, 287 setupFilter: func(t *testing.T, s *stack.Stack) { 288 t.Helper() 289 ipt := s.IPTables() 290 filter := ipt.GetTable(stack.FilterID, true /* ipv6 */) 291 ruleIdx := filter.BuiltinChains[stack.Input] 292 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 293 filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{anotherNicName}} 294 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 295 if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil { 296 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, true, err) 297 } 298 }, 299 genPacket: genPacketV6, 300 proto: header.IPv6ProtocolNumber, 301 expectReceived: 1, 302 expectInputDropped: 0, 303 }, 304 { 305 name: "IPv4 Accept (input interface does not match using a matcher)", 306 setupStack: genStackV4, 307 setupFilter: func(t *testing.T, s *stack.Stack) { 308 t.Helper() 309 ipt := s.IPTables() 310 filter := ipt.GetTable(stack.FilterID, false /* ipv6 */) 311 ruleIdx := filter.BuiltinChains[stack.Input] 312 filter.Rules[ruleIdx].Target = &stack.DropTarget{} 313 filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{anotherNicName}} 314 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{} 315 if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil { 316 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, false, err) 317 } 318 }, 319 genPacket: genPacketV4, 320 proto: header.IPv4ProtocolNumber, 321 expectReceived: 1, 322 expectInputDropped: 0, 323 }, 324 } 325 326 for _, test := range tests { 327 t.Run(test.name, func(t *testing.T) { 328 s, e := test.setupStack(t) 329 test.setupFilter(t, s) 330 e.InjectInbound(test.proto, test.genPacket()) 331 332 if got := int(s.Stats().IP.PacketsReceived.Value()); got != test.expectReceived { 333 t.Errorf("got PacketReceived = %d, want = %d", got, test.expectReceived) 334 } 335 if got := int(s.Stats().IP.IPTablesInputDropped.Value()); got != test.expectInputDropped { 336 t.Errorf("got IPTablesInputDropped = %d, want = %d", got, test.expectInputDropped) 337 } 338 }) 339 } 340 } 341 342 var _ stack.LinkEndpoint = (*channelEndpointWithoutWritePacket)(nil) 343 344 // channelEndpointWithoutWritePacket is a channel endpoint that does not support 345 // stack.LinkEndpoint.WritePacket. 346 type channelEndpointWithoutWritePacket struct { 347 *channel.Endpoint 348 349 t *testing.T 350 } 351 352 func (c *channelEndpointWithoutWritePacket) WritePacket(stack.RouteInfo, tcpip.NetworkProtocolNumber, *stack.PacketBuffer) tcpip.Error { 353 c.t.Error("unexpectedly called WritePacket; all writes should go through WritePackets") 354 return &tcpip.ErrNotSupported{} 355 } 356 357 var _ stack.Matcher = (*udpSourcePortMatcher)(nil) 358 359 type udpSourcePortMatcher struct { 360 port uint16 361 } 362 363 func (*udpSourcePortMatcher) Name() string { 364 return "udpSourcePortMatcher" 365 } 366 367 func (m *udpSourcePortMatcher) Match(_ stack.Hook, pkt *stack.PacketBuffer, _, _ string) (matches, hotdrop bool) { 368 udp := header.UDP(pkt.TransportHeader().View()) 369 if len(udp) < header.UDPMinimumSize { 370 // Drop immediately as the packet is invalid. 371 return false, true 372 } 373 374 return udp.SourcePort() == m.port, false 375 } 376 377 func TestIPTableWritePackets(t *testing.T) { 378 const ( 379 nicID = 1 380 381 dropLocalPort = utils.LocalPort - 1 382 acceptPackets = 2 383 dropPackets = 3 384 ) 385 386 udpHdr := func(hdr buffer.View, srcAddr, dstAddr tcpip.Address, srcPort, dstPort uint16) { 387 u := header.UDP(hdr) 388 u.Encode(&header.UDPFields{ 389 SrcPort: srcPort, 390 DstPort: dstPort, 391 Length: header.UDPMinimumSize, 392 }) 393 sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, srcAddr, dstAddr, header.UDPMinimumSize) 394 sum = header.Checksum(hdr, sum) 395 u.SetChecksum(^u.CalculateChecksum(sum)) 396 } 397 398 tests := []struct { 399 name string 400 setupFilter func(*testing.T, *stack.Stack) 401 genPacket func(*stack.Route) stack.PacketBufferList 402 proto tcpip.NetworkProtocolNumber 403 remoteAddr tcpip.Address 404 expectSent uint64 405 expectOutputDropped uint64 406 }{ 407 { 408 name: "IPv4 Accept", 409 setupFilter: func(*testing.T, *stack.Stack) { /* no filter */ }, 410 genPacket: func(r *stack.Route) stack.PacketBufferList { 411 var pkts stack.PacketBufferList 412 413 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 414 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 415 }) 416 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 417 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), utils.LocalPort, utils.RemotePort) 418 pkts.PushFront(pkt) 419 420 return pkts 421 }, 422 proto: header.IPv4ProtocolNumber, 423 remoteAddr: dstAddrV4, 424 expectSent: 1, 425 expectOutputDropped: 0, 426 }, 427 { 428 name: "IPv4 Drop Other Port", 429 setupFilter: func(t *testing.T, s *stack.Stack) { 430 t.Helper() 431 432 table := stack.Table{ 433 Rules: []stack.Rule{ 434 { 435 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}, 436 }, 437 { 438 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}, 439 }, 440 { 441 Matchers: []stack.Matcher{&udpSourcePortMatcher{port: dropLocalPort}}, 442 Target: &stack.DropTarget{NetworkProtocol: header.IPv4ProtocolNumber}, 443 }, 444 { 445 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}, 446 }, 447 { 448 Target: &stack.ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}, 449 }, 450 }, 451 BuiltinChains: [stack.NumHooks]int{ 452 stack.Prerouting: stack.HookUnset, 453 stack.Input: 0, 454 stack.Forward: 1, 455 stack.Output: 2, 456 stack.Postrouting: stack.HookUnset, 457 }, 458 Underflows: [stack.NumHooks]int{ 459 stack.Prerouting: stack.HookUnset, 460 stack.Input: 0, 461 stack.Forward: 1, 462 stack.Output: 2, 463 stack.Postrouting: stack.HookUnset, 464 }, 465 } 466 467 if err := s.IPTables().ReplaceTable(stack.FilterID, table, false /* ipv4 */); err != nil { 468 t.Fatalf("ReplaceTable(%d, _, false): %s", stack.FilterID, err) 469 } 470 }, 471 genPacket: func(r *stack.Route) stack.PacketBufferList { 472 var pkts stack.PacketBufferList 473 474 for i := 0; i < acceptPackets; i++ { 475 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 476 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 477 }) 478 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 479 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), utils.LocalPort, utils.RemotePort) 480 pkts.PushFront(pkt) 481 } 482 for i := 0; i < dropPackets; i++ { 483 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 484 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 485 }) 486 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 487 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), dropLocalPort, utils.RemotePort) 488 pkts.PushFront(pkt) 489 } 490 491 return pkts 492 }, 493 proto: header.IPv4ProtocolNumber, 494 remoteAddr: dstAddrV4, 495 expectSent: acceptPackets, 496 expectOutputDropped: dropPackets, 497 }, 498 { 499 name: "IPv6 Accept", 500 setupFilter: func(*testing.T, *stack.Stack) { /* no filter */ }, 501 genPacket: func(r *stack.Route) stack.PacketBufferList { 502 var pkts stack.PacketBufferList 503 504 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 505 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 506 }) 507 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 508 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), utils.LocalPort, utils.RemotePort) 509 pkts.PushFront(pkt) 510 511 return pkts 512 }, 513 proto: header.IPv6ProtocolNumber, 514 remoteAddr: dstAddrV6, 515 expectSent: 1, 516 expectOutputDropped: 0, 517 }, 518 { 519 name: "IPv6 Drop Other Port", 520 setupFilter: func(t *testing.T, s *stack.Stack) { 521 t.Helper() 522 523 table := stack.Table{ 524 Rules: []stack.Rule{ 525 { 526 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}, 527 }, 528 { 529 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}, 530 }, 531 { 532 Matchers: []stack.Matcher{&udpSourcePortMatcher{port: dropLocalPort}}, 533 Target: &stack.DropTarget{NetworkProtocol: header.IPv6ProtocolNumber}, 534 }, 535 { 536 Target: &stack.AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}, 537 }, 538 { 539 Target: &stack.ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}, 540 }, 541 }, 542 BuiltinChains: [stack.NumHooks]int{ 543 stack.Prerouting: stack.HookUnset, 544 stack.Input: 0, 545 stack.Forward: 1, 546 stack.Output: 2, 547 stack.Postrouting: stack.HookUnset, 548 }, 549 Underflows: [stack.NumHooks]int{ 550 stack.Prerouting: stack.HookUnset, 551 stack.Input: 0, 552 stack.Forward: 1, 553 stack.Output: 2, 554 stack.Postrouting: stack.HookUnset, 555 }, 556 } 557 558 if err := s.IPTables().ReplaceTable(stack.FilterID, table, true /* ipv6 */); err != nil { 559 t.Fatalf("ReplaceTable(%d, _, true): %s", stack.FilterID, err) 560 } 561 }, 562 genPacket: func(r *stack.Route) stack.PacketBufferList { 563 var pkts stack.PacketBufferList 564 565 for i := 0; i < acceptPackets; i++ { 566 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 567 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 568 }) 569 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 570 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), utils.LocalPort, utils.RemotePort) 571 pkts.PushFront(pkt) 572 } 573 for i := 0; i < dropPackets; i++ { 574 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 575 ReserveHeaderBytes: int(r.MaxHeaderLength() + header.UDPMinimumSize), 576 }) 577 hdr := pkt.TransportHeader().Push(header.UDPMinimumSize) 578 udpHdr(hdr, r.LocalAddress(), r.RemoteAddress(), dropLocalPort, utils.RemotePort) 579 pkts.PushFront(pkt) 580 } 581 582 return pkts 583 }, 584 proto: header.IPv6ProtocolNumber, 585 remoteAddr: dstAddrV6, 586 expectSent: acceptPackets, 587 expectOutputDropped: dropPackets, 588 }, 589 } 590 591 for _, test := range tests { 592 t.Run(test.name, func(t *testing.T) { 593 s := stack.New(stack.Options{ 594 NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, 595 TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, 596 }) 597 e := channelEndpointWithoutWritePacket{ 598 Endpoint: channel.New(4, header.IPv6MinimumMTU, linkAddr), 599 t: t, 600 } 601 if err := s.CreateNIC(nicID, &e); err != nil { 602 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 603 } 604 if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, srcAddrV6); err != nil { 605 t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, srcAddrV6, err) 606 } 607 if err := s.AddAddress(nicID, header.IPv4ProtocolNumber, srcAddrV4); err != nil { 608 t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv4ProtocolNumber, srcAddrV4, err) 609 } 610 611 s.SetRouteTable([]tcpip.Route{ 612 { 613 Destination: header.IPv4EmptySubnet, 614 NIC: nicID, 615 }, 616 { 617 Destination: header.IPv6EmptySubnet, 618 NIC: nicID, 619 }, 620 }) 621 622 test.setupFilter(t, s) 623 624 r, err := s.FindRoute(nicID, "", test.remoteAddr, test.proto, false) 625 if err != nil { 626 t.Fatalf("FindRoute(%d, '', %s, %d, false): %s", nicID, test.remoteAddr, test.proto, err) 627 } 628 defer r.Release() 629 630 pkts := test.genPacket(r) 631 pktsLen := pkts.Len() 632 if n, err := r.WritePackets(pkts, stack.NetworkHeaderParams{ 633 Protocol: header.UDPProtocolNumber, 634 TTL: 64, 635 }); err != nil { 636 t.Fatalf("WritePackets(...): %s", err) 637 } else if n != pktsLen { 638 t.Fatalf("got WritePackets(...) = %d, want = %d", n, pktsLen) 639 } 640 641 if got := s.Stats().IP.PacketsSent.Value(); got != test.expectSent { 642 t.Errorf("got PacketSent = %d, want = %d", got, test.expectSent) 643 } 644 if got := s.Stats().IP.IPTablesOutputDropped.Value(); got != test.expectOutputDropped { 645 t.Errorf("got IPTablesOutputDropped = %d, want = %d", got, test.expectOutputDropped) 646 } 647 }) 648 } 649 } 650 651 const ttl = 64 652 653 var ( 654 ipv4GlobalMulticastAddr = testutil.MustParse4("224.0.1.10") 655 ipv6GlobalMulticastAddr = testutil.MustParse6("ff0e::a") 656 ) 657 658 func rxICMPv4EchoReply(e *channel.Endpoint, src, dst tcpip.Address) { 659 utils.RxICMPv4EchoReply(e, src, dst, ttl) 660 } 661 662 func rxICMPv6EchoReply(e *channel.Endpoint, src, dst tcpip.Address) { 663 utils.RxICMPv6EchoReply(e, src, dst, ttl) 664 } 665 666 func forwardedICMPv4EchoReplyChecker(t *testing.T, b []byte, src, dst tcpip.Address) { 667 checker.IPv4(t, b, 668 checker.SrcAddr(src), 669 checker.DstAddr(dst), 670 checker.TTL(ttl-1), 671 checker.ICMPv4( 672 checker.ICMPv4Type(header.ICMPv4EchoReply))) 673 } 674 675 func forwardedICMPv6EchoReplyChecker(t *testing.T, b []byte, src, dst tcpip.Address) { 676 checker.IPv6(t, b, 677 checker.SrcAddr(src), 678 checker.DstAddr(dst), 679 checker.TTL(ttl-1), 680 checker.ICMPv6( 681 checker.ICMPv6Type(header.ICMPv6EchoReply))) 682 } 683 684 func boolToInt(v bool) uint64 { 685 if v { 686 return 1 687 } 688 return 0 689 } 690 691 func setupDropFilter(hook stack.Hook, f stack.IPHeaderFilter) func(*testing.T, *stack.Stack, tcpip.NetworkProtocolNumber) { 692 return func(t *testing.T, s *stack.Stack, netProto tcpip.NetworkProtocolNumber) { 693 t.Helper() 694 695 ipv6 := netProto == ipv6.ProtocolNumber 696 697 ipt := s.IPTables() 698 filter := ipt.GetTable(stack.FilterID, ipv6) 699 ruleIdx := filter.BuiltinChains[hook] 700 filter.Rules[ruleIdx].Filter = f 701 filter.Rules[ruleIdx].Target = &stack.DropTarget{NetworkProtocol: netProto} 702 // Make sure the packet is not dropped by the next rule. 703 filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{NetworkProtocol: netProto} 704 if err := ipt.ReplaceTable(stack.FilterID, filter, ipv6); err != nil { 705 t.Fatalf("ipt.ReplaceTable(%d, _, %t): %s", stack.FilterID, ipv6, err) 706 } 707 } 708 } 709 710 func TestForwardingHook(t *testing.T) { 711 const ( 712 nicID1 = 1 713 nicID2 = 2 714 715 nic1Name = "nic1" 716 nic2Name = "nic2" 717 718 otherNICName = "otherNIC" 719 ) 720 721 tests := []struct { 722 name string 723 netProto tcpip.NetworkProtocolNumber 724 local bool 725 srcAddr, dstAddr tcpip.Address 726 rx func(*channel.Endpoint, tcpip.Address, tcpip.Address) 727 checker func(*testing.T, []byte) 728 }{ 729 { 730 name: "IPv4 remote", 731 netProto: ipv4.ProtocolNumber, 732 local: false, 733 srcAddr: utils.RemoteIPv4Addr, 734 dstAddr: utils.Ipv4Addr2.AddressWithPrefix.Address, 735 rx: rxICMPv4EchoReply, 736 checker: func(t *testing.T, b []byte) { 737 forwardedICMPv4EchoReplyChecker(t, b, utils.RemoteIPv4Addr, utils.Ipv4Addr2.AddressWithPrefix.Address) 738 }, 739 }, 740 { 741 name: "IPv4 local", 742 netProto: ipv4.ProtocolNumber, 743 local: true, 744 srcAddr: utils.RemoteIPv4Addr, 745 dstAddr: utils.Ipv4Addr.Address, 746 rx: rxICMPv4EchoReply, 747 }, 748 { 749 name: "IPv6 remote", 750 netProto: ipv6.ProtocolNumber, 751 local: false, 752 srcAddr: utils.RemoteIPv6Addr, 753 dstAddr: utils.Ipv6Addr2.AddressWithPrefix.Address, 754 rx: rxICMPv6EchoReply, 755 checker: func(t *testing.T, b []byte) { 756 forwardedICMPv6EchoReplyChecker(t, b, utils.RemoteIPv6Addr, utils.Ipv6Addr2.AddressWithPrefix.Address) 757 }, 758 }, 759 { 760 name: "IPv6 local", 761 netProto: ipv6.ProtocolNumber, 762 local: true, 763 srcAddr: utils.RemoteIPv6Addr, 764 dstAddr: utils.Ipv6Addr.Address, 765 rx: rxICMPv6EchoReply, 766 }, 767 } 768 769 subTests := []struct { 770 name string 771 setupFilter func(*testing.T, *stack.Stack, tcpip.NetworkProtocolNumber) 772 expectForward bool 773 }{ 774 { 775 name: "Accept", 776 setupFilter: func(*testing.T, *stack.Stack, tcpip.NetworkProtocolNumber) { /* no filter */ }, 777 expectForward: true, 778 }, 779 780 { 781 name: "Drop", 782 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{}), 783 expectForward: false, 784 }, 785 { 786 name: "Drop with input NIC filtering", 787 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: nic1Name}), 788 expectForward: false, 789 }, 790 { 791 name: "Drop with output NIC filtering", 792 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{OutputInterface: nic2Name}), 793 expectForward: false, 794 }, 795 { 796 name: "Drop with input and output NIC filtering", 797 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: nic1Name, OutputInterface: nic2Name}), 798 expectForward: false, 799 }, 800 801 { 802 name: "Drop with other input NIC filtering", 803 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: otherNICName}), 804 expectForward: true, 805 }, 806 { 807 name: "Drop with other output NIC filtering", 808 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{OutputInterface: otherNICName}), 809 expectForward: true, 810 }, 811 { 812 name: "Drop with other input and output NIC filtering", 813 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: otherNICName, OutputInterface: nic2Name}), 814 expectForward: true, 815 }, 816 { 817 name: "Drop with input and other output NIC filtering", 818 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: nic1Name, OutputInterface: otherNICName}), 819 expectForward: true, 820 }, 821 { 822 name: "Drop with other input and other output NIC filtering", 823 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: otherNICName, OutputInterface: otherNICName}), 824 expectForward: true, 825 }, 826 827 { 828 name: "Drop with inverted input NIC filtering", 829 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{InputInterface: nic1Name, InputInterfaceInvert: true}), 830 expectForward: true, 831 }, 832 { 833 name: "Drop with inverted output NIC filtering", 834 setupFilter: setupDropFilter(stack.Forward, stack.IPHeaderFilter{OutputInterface: nic2Name, OutputInterfaceInvert: true}), 835 expectForward: true, 836 }, 837 } 838 839 for _, test := range tests { 840 t.Run(test.name, func(t *testing.T) { 841 for _, subTest := range subTests { 842 t.Run(subTest.name, func(t *testing.T) { 843 s := stack.New(stack.Options{ 844 NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, 845 }) 846 847 subTest.setupFilter(t, s, test.netProto) 848 849 e1 := channel.New(1, header.IPv6MinimumMTU, "") 850 if err := s.CreateNICWithOptions(nicID1, e1, stack.NICOptions{Name: nic1Name}); err != nil { 851 t.Fatalf("s.CreateNICWithOptions(%d, _, _): %s", nicID1, err) 852 } 853 854 e2 := channel.New(1, header.IPv6MinimumMTU, "") 855 if err := s.CreateNICWithOptions(nicID2, e2, stack.NICOptions{Name: nic2Name}); err != nil { 856 t.Fatalf("s.CreateNICWithOptions(%d, _, _): %s", nicID2, err) 857 } 858 859 if err := s.AddAddress(nicID2, ipv4.ProtocolNumber, utils.Ipv4Addr.Address); err != nil { 860 t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID2, ipv4.ProtocolNumber, utils.Ipv4Addr.Address, err) 861 } 862 if err := s.AddAddress(nicID2, ipv6.ProtocolNumber, utils.Ipv6Addr.Address); err != nil { 863 t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID2, ipv6.ProtocolNumber, utils.Ipv6Addr.Address, err) 864 } 865 866 if err := s.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true); err != nil { 867 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d, true): %s", ipv4.ProtocolNumber, err) 868 } 869 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil { 870 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err) 871 } 872 873 s.SetRouteTable([]tcpip.Route{ 874 { 875 Destination: header.IPv4EmptySubnet, 876 NIC: nicID2, 877 }, 878 { 879 Destination: header.IPv6EmptySubnet, 880 NIC: nicID2, 881 }, 882 }) 883 884 test.rx(e1, test.srcAddr, test.dstAddr) 885 886 expectTransmitPacket := subTest.expectForward && !test.local 887 888 ep1, err := s.GetNetworkEndpoint(nicID1, test.netProto) 889 if err != nil { 890 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID1, test.netProto, err) 891 } 892 ep1Stats := ep1.Stats() 893 ipEP1Stats, ok := ep1Stats.(stack.IPNetworkEndpointStats) 894 if !ok { 895 t.Fatalf("got ep1Stats = %T, want = stack.IPNetworkEndpointStats", ep1Stats) 896 } 897 ip1Stats := ipEP1Stats.IPStats() 898 899 if got := ip1Stats.PacketsReceived.Value(); got != 1 { 900 t.Errorf("got ip1Stats.PacketsReceived.Value() = %d, want = 1", got) 901 } 902 if got := ip1Stats.ValidPacketsReceived.Value(); got != 1 { 903 t.Errorf("got ip1Stats.ValidPacketsReceived.Value() = %d, want = 1", got) 904 } 905 if got, want := ip1Stats.IPTablesForwardDropped.Value(), boolToInt(!subTest.expectForward); got != want { 906 t.Errorf("got ip1Stats.IPTablesForwardDropped.Value() = %d, want = %d", got, want) 907 } 908 if got := ip1Stats.PacketsSent.Value(); got != 0 { 909 t.Errorf("got ip1Stats.PacketsSent.Value() = %d, want = 0", got) 910 } 911 912 ep2, err := s.GetNetworkEndpoint(nicID2, test.netProto) 913 if err != nil { 914 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID2, test.netProto, err) 915 } 916 ep2Stats := ep2.Stats() 917 ipEP2Stats, ok := ep2Stats.(stack.IPNetworkEndpointStats) 918 if !ok { 919 t.Fatalf("got ep2Stats = %T, want = stack.IPNetworkEndpointStats", ep2Stats) 920 } 921 ip2Stats := ipEP2Stats.IPStats() 922 if got := ip2Stats.PacketsReceived.Value(); got != 0 { 923 t.Errorf("got ip2Stats.PacketsReceived.Value() = %d, want = 0", got) 924 } 925 if got, want := ip2Stats.ValidPacketsReceived.Value(), boolToInt(subTest.expectForward && test.local); got != want { 926 t.Errorf("got ip2Stats.ValidPacketsReceived.Value() = %d, want = %d", got, want) 927 } 928 if got, want := ip2Stats.PacketsSent.Value(), boolToInt(expectTransmitPacket); got != want { 929 t.Errorf("got ip2Stats.PacketsSent.Value() = %d, want = %d", got, want) 930 } 931 932 p, ok := e2.Read() 933 if ok != expectTransmitPacket { 934 t.Fatalf("got e2.Read() = (%#v, %t), want = (_, %t)", p, ok, expectTransmitPacket) 935 } 936 if expectTransmitPacket { 937 test.checker(t, stack.PayloadSince(p.Pkt.NetworkHeader())) 938 } 939 }) 940 } 941 }) 942 } 943 } 944 945 func TestInputHookWithLocalForwarding(t *testing.T) { 946 const ( 947 nicID1 = 1 948 nicID2 = 2 949 950 nic1Name = "nic1" 951 nic2Name = "nic2" 952 953 otherNICName = "otherNIC" 954 ) 955 956 tests := []struct { 957 name string 958 netProto tcpip.NetworkProtocolNumber 959 rx func(*channel.Endpoint) 960 checker func(*testing.T, []byte) 961 }{ 962 { 963 name: "IPv4", 964 netProto: ipv4.ProtocolNumber, 965 rx: func(e *channel.Endpoint) { 966 utils.RxICMPv4EchoRequest(e, utils.RemoteIPv4Addr, utils.Ipv4Addr2.AddressWithPrefix.Address, ttl) 967 }, 968 checker: func(t *testing.T, b []byte) { 969 checker.IPv4(t, b, 970 checker.SrcAddr(utils.Ipv4Addr2.AddressWithPrefix.Address), 971 checker.DstAddr(utils.RemoteIPv4Addr), 972 checker.ICMPv4( 973 checker.ICMPv4Type(header.ICMPv4EchoReply))) 974 }, 975 }, 976 { 977 name: "IPv6", 978 netProto: ipv6.ProtocolNumber, 979 rx: func(e *channel.Endpoint) { 980 utils.RxICMPv6EchoRequest(e, utils.RemoteIPv6Addr, utils.Ipv6Addr2.AddressWithPrefix.Address, ttl) 981 }, 982 checker: func(t *testing.T, b []byte) { 983 checker.IPv6(t, b, 984 checker.SrcAddr(utils.Ipv6Addr2.AddressWithPrefix.Address), 985 checker.DstAddr(utils.RemoteIPv6Addr), 986 checker.ICMPv6( 987 checker.ICMPv6Type(header.ICMPv6EchoReply))) 988 }, 989 }, 990 } 991 992 subTests := []struct { 993 name string 994 setupFilter func(*testing.T, *stack.Stack, tcpip.NetworkProtocolNumber) 995 expectDrop bool 996 }{ 997 { 998 name: "Accept", 999 setupFilter: func(*testing.T, *stack.Stack, tcpip.NetworkProtocolNumber) { /* no filter */ }, 1000 expectDrop: false, 1001 }, 1002 1003 { 1004 name: "Drop", 1005 setupFilter: setupDropFilter(stack.Input, stack.IPHeaderFilter{}), 1006 expectDrop: true, 1007 }, 1008 { 1009 name: "Drop with input NIC filtering on arrival NIC", 1010 setupFilter: setupDropFilter(stack.Input, stack.IPHeaderFilter{InputInterface: nic1Name}), 1011 expectDrop: true, 1012 }, 1013 { 1014 name: "Drop with input NIC filtering on delivered NIC", 1015 setupFilter: setupDropFilter(stack.Input, stack.IPHeaderFilter{InputInterface: nic2Name}), 1016 expectDrop: false, 1017 }, 1018 1019 { 1020 name: "Drop with input NIC filtering on other NIC", 1021 setupFilter: setupDropFilter(stack.Input, stack.IPHeaderFilter{InputInterface: otherNICName}), 1022 expectDrop: false, 1023 }, 1024 } 1025 1026 for _, test := range tests { 1027 t.Run(test.name, func(t *testing.T) { 1028 for _, subTest := range subTests { 1029 t.Run(subTest.name, func(t *testing.T) { 1030 s := stack.New(stack.Options{ 1031 NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, 1032 }) 1033 1034 subTest.setupFilter(t, s, test.netProto) 1035 1036 e1 := channel.New(1, header.IPv6MinimumMTU, "") 1037 if err := s.CreateNICWithOptions(nicID1, e1, stack.NICOptions{Name: nic1Name}); err != nil { 1038 t.Fatalf("s.CreateNICWithOptions(%d, _, _): %s", nicID1, err) 1039 } 1040 if err := s.AddProtocolAddress(nicID1, utils.Ipv4Addr1); err != nil { 1041 t.Fatalf("s.AddProtocolAddress(%d, %#v): %s", nicID1, utils.Ipv4Addr1, err) 1042 } 1043 if err := s.AddProtocolAddress(nicID1, utils.Ipv6Addr1); err != nil { 1044 t.Fatalf("s.AddProtocolAddress(%d, %#v): %s", nicID1, utils.Ipv6Addr1, err) 1045 } 1046 1047 e2 := channel.New(1, header.IPv6MinimumMTU, "") 1048 if err := s.CreateNICWithOptions(nicID2, e2, stack.NICOptions{Name: nic2Name}); err != nil { 1049 t.Fatalf("s.CreateNICWithOptions(%d, _, _): %s", nicID2, err) 1050 } 1051 if err := s.AddProtocolAddress(nicID2, utils.Ipv4Addr2); err != nil { 1052 t.Fatalf("s.AddProtocolAddress(%d, %#v): %s", nicID2, utils.Ipv4Addr2, err) 1053 } 1054 if err := s.AddProtocolAddress(nicID2, utils.Ipv6Addr2); err != nil { 1055 t.Fatalf("s.AddProtocolAddress(%d, %#v): %s", nicID2, utils.Ipv6Addr2, err) 1056 } 1057 1058 if err := s.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true); err != nil { 1059 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d, true): %s", ipv4.ProtocolNumber, err) 1060 } 1061 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil { 1062 t.Fatalf("s.SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err) 1063 } 1064 1065 s.SetRouteTable([]tcpip.Route{ 1066 { 1067 Destination: header.IPv4EmptySubnet, 1068 NIC: nicID1, 1069 }, 1070 { 1071 Destination: header.IPv6EmptySubnet, 1072 NIC: nicID1, 1073 }, 1074 }) 1075 1076 test.rx(e1) 1077 1078 ep1, err := s.GetNetworkEndpoint(nicID1, test.netProto) 1079 if err != nil { 1080 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID1, test.netProto, err) 1081 } 1082 ep1Stats := ep1.Stats() 1083 ipEP1Stats, ok := ep1Stats.(stack.IPNetworkEndpointStats) 1084 if !ok { 1085 t.Fatalf("got ep1Stats = %T, want = stack.IPNetworkEndpointStats", ep1Stats) 1086 } 1087 ip1Stats := ipEP1Stats.IPStats() 1088 1089 if got := ip1Stats.PacketsReceived.Value(); got != 1 { 1090 t.Errorf("got ip1Stats.PacketsReceived.Value() = %d, want = 1", got) 1091 } 1092 if got := ip1Stats.ValidPacketsReceived.Value(); got != 1 { 1093 t.Errorf("got ip1Stats.ValidPacketsReceived.Value() = %d, want = 1", got) 1094 } 1095 if got, want := ip1Stats.PacketsSent.Value(), boolToInt(!subTest.expectDrop); got != want { 1096 t.Errorf("got ip1Stats.PacketsSent.Value() = %d, want = %d", got, want) 1097 } 1098 1099 ep2, err := s.GetNetworkEndpoint(nicID2, test.netProto) 1100 if err != nil { 1101 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID2, test.netProto, err) 1102 } 1103 ep2Stats := ep2.Stats() 1104 ipEP2Stats, ok := ep2Stats.(stack.IPNetworkEndpointStats) 1105 if !ok { 1106 t.Fatalf("got ep2Stats = %T, want = stack.IPNetworkEndpointStats", ep2Stats) 1107 } 1108 ip2Stats := ipEP2Stats.IPStats() 1109 if got := ip2Stats.PacketsReceived.Value(); got != 0 { 1110 t.Errorf("got ip2Stats.PacketsReceived.Value() = %d, want = 0", got) 1111 } 1112 if got := ip2Stats.ValidPacketsReceived.Value(); got != 1 { 1113 t.Errorf("got ip2Stats.ValidPacketsReceived.Value() = %d, want = 1", got) 1114 } 1115 if got, want := ip2Stats.IPTablesInputDropped.Value(), boolToInt(subTest.expectDrop); got != want { 1116 t.Errorf("got ip2Stats.IPTablesInputDropped.Value() = %d, want = %d", got, want) 1117 } 1118 if got := ip2Stats.PacketsSent.Value(); got != 0 { 1119 t.Errorf("got ip2Stats.PacketsSent.Value() = %d, want = 0", got) 1120 } 1121 1122 if p, ok := e1.Read(); ok == subTest.expectDrop { 1123 t.Errorf("got e1.Read() = (%#v, %t), want = (_, %t)", p, ok, !subTest.expectDrop) 1124 } else if !subTest.expectDrop { 1125 test.checker(t, stack.PayloadSince(p.Pkt.NetworkHeader())) 1126 } 1127 if p, ok := e2.Read(); ok { 1128 t.Errorf("got e1.Read() = (%#v, true), want = (_, false)", p) 1129 } 1130 }) 1131 } 1132 }) 1133 } 1134 }