github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/network/ipv6/ipv6.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 ipv6 contains the implementation of the ipv6 network protocol. 16 package ipv6 17 18 import ( 19 "encoding/binary" 20 "fmt" 21 "hash/fnv" 22 "math" 23 "reflect" 24 "sort" 25 "sync/atomic" 26 "time" 27 28 "github.com/SagerNet/gvisor/pkg/sync" 29 "github.com/SagerNet/gvisor/pkg/tcpip" 30 "github.com/SagerNet/gvisor/pkg/tcpip/buffer" 31 "github.com/SagerNet/gvisor/pkg/tcpip/header" 32 "github.com/SagerNet/gvisor/pkg/tcpip/header/parse" 33 "github.com/SagerNet/gvisor/pkg/tcpip/network/hash" 34 "github.com/SagerNet/gvisor/pkg/tcpip/network/internal/fragmentation" 35 "github.com/SagerNet/gvisor/pkg/tcpip/network/internal/ip" 36 "github.com/SagerNet/gvisor/pkg/tcpip/stack" 37 ) 38 39 const ( 40 // ReassembleTimeout controls how long a fragment will be held. 41 // As per RFC 8200 section 4.5: 42 // 43 // If insufficient fragments are received to complete reassembly of a packet 44 // within 60 seconds of the reception of the first-arriving fragment of that 45 // packet, reassembly of that packet must be abandoned. 46 // 47 // Linux also uses 60 seconds for reassembly timeout: 48 // https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/include/net/ipv6.h#L456 49 ReassembleTimeout = 60 * time.Second 50 51 // ProtocolNumber is the ipv6 protocol number. 52 ProtocolNumber = header.IPv6ProtocolNumber 53 54 // maxPayloadSize is the maximum size that can be encoded in the 16-bit 55 // PayloadLength field of the ipv6 header. 56 maxPayloadSize = 0xffff 57 58 // DefaultTTL is the default hop limit for IPv6 Packets egressed by 59 // Netstack. 60 DefaultTTL = 64 61 62 // buckets for fragment identifiers 63 buckets = 2048 64 ) 65 66 const ( 67 forwardingDisabled = 0 68 forwardingEnabled = 1 69 ) 70 71 // policyTable is the default policy table defined in RFC 6724 section 2.1. 72 // 73 // A more human-readable version: 74 // 75 // Prefix Precedence Label 76 // ::1/128 50 0 77 // ::/0 40 1 78 // ::ffff:0:0/96 35 4 79 // 2002::/16 30 2 80 // 2001::/32 5 5 81 // fc00::/7 3 13 82 // ::/96 1 3 83 // fec0::/10 1 11 84 // 3ffe::/16 1 12 85 // 86 // The table is sorted by prefix length so longest-prefix match can be easily 87 // achieved. 88 // 89 // We willingly left out ::/96, fec0::/10 and 3ffe::/16 since those prefix 90 // assignments are deprecated. 91 // 92 // As per RFC 4291 section 2.5.5.1 (for ::/96), 93 // 94 // The "IPv4-Compatible IPv6 address" is now deprecated because the 95 // current IPv6 transition mechanisms no longer use these addresses. 96 // New or updated implementations are not required to support this 97 // address type. 98 // 99 // As per RFC 3879 section 4 (for fec0::/10), 100 // 101 // This document formally deprecates the IPv6 site-local unicast prefix 102 // defined in [RFC3513], i.e., 1111111011 binary or FEC0::/10. 103 // 104 // As per RFC 3701 section 1 (for 3ffe::/16), 105 // 106 // As clearly stated in [TEST-NEW], the addresses for the 6bone are 107 // temporary and will be reclaimed in the future. It further states 108 // that all users of these addresses (within the 3FFE::/16 prefix) will 109 // be required to renumber at some time in the future. 110 // 111 // and section 2, 112 // 113 // Thus after the pTLA allocation cutoff date January 1, 2004, it is 114 // REQUIRED that no new 6bone 3FFE pTLAs be allocated. 115 // 116 // MUST NOT BE MODIFIED. 117 var policyTable = [...]struct { 118 subnet tcpip.Subnet 119 120 label uint8 121 }{ 122 // ::1/128 123 { 124 subnet: header.IPv6Loopback.WithPrefix().Subnet(), 125 label: 0, 126 }, 127 // ::ffff:0:0/96 128 { 129 subnet: header.IPv4MappedIPv6Subnet, 130 label: 4, 131 }, 132 // 2001::/32 (Teredo prefix as per RFC 4380 section 2.6). 133 { 134 subnet: tcpip.AddressWithPrefix{ 135 Address: "\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 136 PrefixLen: 32, 137 }.Subnet(), 138 label: 5, 139 }, 140 // 2002::/16 (6to4 prefix as per RFC 3056 section 2). 141 { 142 subnet: tcpip.AddressWithPrefix{ 143 Address: "\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 144 PrefixLen: 16, 145 }.Subnet(), 146 label: 2, 147 }, 148 // fc00::/7 (Unique local addresses as per RFC 4193 section 3.1). 149 { 150 subnet: tcpip.AddressWithPrefix{ 151 Address: "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 152 PrefixLen: 7, 153 }.Subnet(), 154 label: 13, 155 }, 156 // ::/0 157 { 158 subnet: header.IPv6EmptySubnet, 159 label: 1, 160 }, 161 } 162 163 func getLabel(addr tcpip.Address) uint8 { 164 for _, p := range policyTable { 165 if p.subnet.Contains(addr) { 166 return p.label 167 } 168 } 169 170 panic(fmt.Sprintf("should have a label for address = %s", addr)) 171 } 172 173 var _ stack.DuplicateAddressDetector = (*endpoint)(nil) 174 var _ stack.LinkAddressResolver = (*endpoint)(nil) 175 var _ stack.LinkResolvableNetworkEndpoint = (*endpoint)(nil) 176 var _ stack.ForwardingNetworkEndpoint = (*endpoint)(nil) 177 var _ stack.GroupAddressableEndpoint = (*endpoint)(nil) 178 var _ stack.AddressableEndpoint = (*endpoint)(nil) 179 var _ stack.NetworkEndpoint = (*endpoint)(nil) 180 var _ stack.NDPEndpoint = (*endpoint)(nil) 181 var _ NDPEndpoint = (*endpoint)(nil) 182 183 type endpoint struct { 184 nic stack.NetworkInterface 185 dispatcher stack.TransportDispatcher 186 protocol *protocol 187 stats sharedStats 188 189 // enabled is set to 1 when the endpoint is enabled and 0 when it is 190 // disabled. 191 // 192 // Must be accessed using atomic operations. 193 enabled uint32 194 195 // forwarding is set to forwardingEnabled when the endpoint has forwarding 196 // enabled and forwardingDisabled when it is disabled. 197 // 198 // Must be accessed using atomic operations. 199 forwarding uint32 200 201 mu struct { 202 sync.RWMutex 203 204 addressableEndpointState stack.AddressableEndpointState 205 ndp ndpState 206 mld mldState 207 } 208 209 // dad is used to check if an arbitrary address is already assigned to some 210 // neighbor. 211 // 212 // Note: this is different from mu.ndp.dad which is used to perform DAD for 213 // addresses that are assigned to the interface. Removing an address aborts 214 // DAD; if we had used the same state, handlers for a removed address would 215 // not be called with the actual DAD result. 216 // 217 // LOCK ORDERING: mu > dad.mu. 218 dad struct { 219 mu struct { 220 sync.Mutex 221 222 dad ip.DAD 223 } 224 } 225 } 226 227 // NICNameFromID is a function that returns a stable name for the specified NIC, 228 // even if different NIC IDs are used to refer to the same NIC in different 229 // program runs. It is used when generating opaque interface identifiers (IIDs). 230 // If the NIC was created with a name, it is passed to NICNameFromID. 231 // 232 // NICNameFromID SHOULD return unique NIC names so unique opaque IIDs are 233 // generated for the same prefix on different NICs. 234 type NICNameFromID func(tcpip.NICID, string) string 235 236 // OpaqueInterfaceIdentifierOptions holds the options related to the generation 237 // of opaque interface identifiers (IIDs) as defined by RFC 7217. 238 type OpaqueInterfaceIdentifierOptions struct { 239 // NICNameFromID is a function that returns a stable name for a specified NIC, 240 // even if the NIC ID changes over time. 241 // 242 // Must be specified to generate the opaque IID. 243 NICNameFromID NICNameFromID 244 245 // SecretKey is a pseudo-random number used as the secret key when generating 246 // opaque IIDs as defined by RFC 7217. The key SHOULD be at least 247 // header.OpaqueIIDSecretKeyMinBytes bytes and MUST follow minimum randomness 248 // requirements for security as outlined by RFC 4086. SecretKey MUST NOT 249 // change between program runs, unless explicitly changed. 250 // 251 // OpaqueInterfaceIdentifierOptions takes ownership of SecretKey. SecretKey 252 // MUST NOT be modified after Stack is created. 253 // 254 // May be nil, but a nil value is highly discouraged to maintain 255 // some level of randomness between nodes. 256 SecretKey []byte 257 } 258 259 // CheckDuplicateAddress implements stack.DuplicateAddressDetector. 260 func (e *endpoint) CheckDuplicateAddress(addr tcpip.Address, h stack.DADCompletionHandler) stack.DADCheckAddressDisposition { 261 e.dad.mu.Lock() 262 defer e.dad.mu.Unlock() 263 return e.dad.mu.dad.CheckDuplicateAddressLocked(addr, h) 264 } 265 266 // SetDADConfigurations implements stack.DuplicateAddressDetector. 267 func (e *endpoint) SetDADConfigurations(c stack.DADConfigurations) { 268 e.mu.Lock() 269 defer e.mu.Unlock() 270 e.dad.mu.Lock() 271 defer e.dad.mu.Unlock() 272 273 e.mu.ndp.dad.SetConfigsLocked(c) 274 e.dad.mu.dad.SetConfigsLocked(c) 275 } 276 277 // DuplicateAddressProtocol implements stack.DuplicateAddressDetector. 278 func (*endpoint) DuplicateAddressProtocol() tcpip.NetworkProtocolNumber { 279 return ProtocolNumber 280 } 281 282 // HandleLinkResolutionFailure implements stack.LinkResolvableNetworkEndpoint. 283 func (e *endpoint) HandleLinkResolutionFailure(pkt *stack.PacketBuffer) { 284 // If we are operating as a router, we should return an ICMP error to the 285 // original packet's sender. 286 if pkt.NetworkPacketInfo.IsForwardedPacket { 287 // TODO(github.com/SagerNet/issue/6005): Propagate asynchronously generated ICMP 288 // errors to local endpoints. 289 e.protocol.returnError(&icmpReasonHostUnreachable{}, pkt) 290 e.stats.ip.Forwarding.Errors.Increment() 291 e.stats.ip.Forwarding.HostUnreachable.Increment() 292 return 293 } 294 // handleControl expects the entire offending packet to be in the packet 295 // buffer's data field. 296 pkt = stack.NewPacketBuffer(stack.PacketBufferOptions{ 297 Data: buffer.NewVectorisedView(pkt.Size(), pkt.Views()), 298 }) 299 pkt.NICID = e.nic.ID() 300 pkt.NetworkProtocolNumber = ProtocolNumber 301 e.handleControl(&icmpv6DestinationAddressUnreachableSockError{}, pkt) 302 } 303 304 // onAddressAssignedLocked handles an address being assigned. 305 // 306 // Precondition: e.mu must be exclusively locked. 307 func (e *endpoint) onAddressAssignedLocked(addr tcpip.Address) { 308 // As per RFC 2710 section 3, 309 // 310 // All MLD messages described in this document are sent with a link-local 311 // IPv6 Source Address, ... 312 // 313 // If we just completed DAD for a link-local address, then attempt to send any 314 // queued MLD reports. Note, we may have sent reports already for some of the 315 // groups before we had a valid link-local address to use as the source for 316 // the MLD messages, but that was only so that MLD snooping switches are aware 317 // of our membership to groups - routers would not have handled those reports. 318 // 319 // As per RFC 3590 section 4, 320 // 321 // MLD Report and Done messages are sent with a link-local address as 322 // the IPv6 source address, if a valid address is available on the 323 // interface. If a valid link-local address is not available (e.g., one 324 // has not been configured), the message is sent with the unspecified 325 // address (::) as the IPv6 source address. 326 // 327 // Once a valid link-local address is available, a node SHOULD generate 328 // new MLD Report messages for all multicast addresses joined on the 329 // interface. 330 // 331 // Routers receiving an MLD Report or Done message with the unspecified 332 // address as the IPv6 source address MUST silently discard the packet 333 // without taking any action on the packets contents. 334 // 335 // Snooping switches MUST manage multicast forwarding state based on MLD 336 // Report and Done messages sent with the unspecified address as the 337 // IPv6 source address. 338 if header.IsV6LinkLocalUnicastAddress(addr) { 339 e.mu.mld.sendQueuedReports() 340 } 341 } 342 343 // InvalidateDefaultRouter implements stack.NDPEndpoint. 344 func (e *endpoint) InvalidateDefaultRouter(rtr tcpip.Address) { 345 e.mu.Lock() 346 defer e.mu.Unlock() 347 348 // We represent default routers with a default (off-link) route through the 349 // router. 350 e.mu.ndp.invalidateOffLinkRoute(offLinkRoute{dest: header.IPv6EmptySubnet, router: rtr}) 351 } 352 353 // SetNDPConfigurations implements NDPEndpoint. 354 func (e *endpoint) SetNDPConfigurations(c NDPConfigurations) { 355 c.validate() 356 e.mu.Lock() 357 defer e.mu.Unlock() 358 e.mu.ndp.configs = c 359 } 360 361 // hasTentativeAddr returns true if addr is tentative on e. 362 func (e *endpoint) hasTentativeAddr(addr tcpip.Address) bool { 363 e.mu.RLock() 364 addressEndpoint := e.getAddressRLocked(addr) 365 e.mu.RUnlock() 366 return addressEndpoint != nil && addressEndpoint.GetKind() == stack.PermanentTentative 367 } 368 369 // dupTentativeAddrDetected attempts to inform e that a tentative addr is a 370 // duplicate on a link. 371 // 372 // dupTentativeAddrDetected removes the tentative address if it exists. If the 373 // address was generated via SLAAC, an attempt is made to generate a new 374 // address. 375 func (e *endpoint) dupTentativeAddrDetected(addr tcpip.Address, holderLinkAddr tcpip.LinkAddress, nonce []byte) tcpip.Error { 376 e.mu.Lock() 377 defer e.mu.Unlock() 378 379 addressEndpoint := e.getAddressRLocked(addr) 380 if addressEndpoint == nil { 381 return &tcpip.ErrBadAddress{} 382 } 383 384 if addressEndpoint.GetKind() != stack.PermanentTentative { 385 return &tcpip.ErrInvalidEndpointState{} 386 } 387 388 switch result := e.mu.ndp.dad.ExtendIfNonceEqualLocked(addr, nonce); result { 389 case ip.Extended: 390 // The nonce we got back was the same we sent so we know the message 391 // indicating a duplicate address was likely ours so do not consider 392 // the address duplicate here. 393 return nil 394 case ip.AlreadyExtended: 395 // See Extended. 396 // 397 // Our DAD message was looped back already. 398 return nil 399 case ip.NoDADStateFound: 400 panic(fmt.Sprintf("expected DAD state for tentative address %s", addr)) 401 case ip.NonceDisabled: 402 // If nonce is disabled then we have no way to know if the packet was 403 // looped-back so we have to assume it indicates a duplicate address. 404 fallthrough 405 case ip.NonceNotEqual: 406 // If the address is a SLAAC address, do not invalidate its SLAAC prefix as an 407 // attempt will be made to generate a new address for it. 408 if err := e.removePermanentEndpointLocked(addressEndpoint, false /* allowSLAACInvalidation */, &stack.DADDupAddrDetected{HolderLinkAddress: holderLinkAddr}); err != nil { 409 return err 410 } 411 412 prefix := addressEndpoint.Subnet() 413 414 switch t := addressEndpoint.ConfigType(); t { 415 case stack.AddressConfigStatic: 416 case stack.AddressConfigSlaac: 417 e.mu.ndp.regenerateSLAACAddr(prefix) 418 case stack.AddressConfigSlaacTemp: 419 // Do not reset the generation attempts counter for the prefix as the 420 // temporary address is being regenerated in response to a DAD conflict. 421 e.mu.ndp.regenerateTempSLAACAddr(prefix, false /* resetGenAttempts */) 422 default: 423 panic(fmt.Sprintf("unrecognized address config type = %d", t)) 424 } 425 426 return nil 427 default: 428 panic(fmt.Sprintf("unhandled result = %d", result)) 429 } 430 } 431 432 // Forwarding implements stack.ForwardingNetworkEndpoint. 433 func (e *endpoint) Forwarding() bool { 434 return atomic.LoadUint32(&e.forwarding) == forwardingEnabled 435 } 436 437 // setForwarding sets the forwarding status for the endpoint. 438 // 439 // Returns true if the forwarding status was updated. 440 func (e *endpoint) setForwarding(v bool) bool { 441 forwarding := uint32(forwardingDisabled) 442 if v { 443 forwarding = forwardingEnabled 444 } 445 446 return atomic.SwapUint32(&e.forwarding, forwarding) != forwarding 447 } 448 449 // SetForwarding implements stack.ForwardingNetworkEndpoint. 450 func (e *endpoint) SetForwarding(forwarding bool) { 451 e.mu.Lock() 452 defer e.mu.Unlock() 453 454 if !e.setForwarding(forwarding) { 455 return 456 } 457 458 allRoutersGroups := [...]tcpip.Address{ 459 header.IPv6AllRoutersInterfaceLocalMulticastAddress, 460 header.IPv6AllRoutersLinkLocalMulticastAddress, 461 header.IPv6AllRoutersSiteLocalMulticastAddress, 462 } 463 464 if forwarding { 465 // As per RFC 4291 section 2.8: 466 // 467 // A router is required to recognize all addresses that a host is 468 // required to recognize, plus the following addresses as identifying 469 // itself: 470 // 471 // o The All-Routers multicast addresses defined in Section 2.7.1. 472 // 473 // As per RFC 4291 section 2.7.1, 474 // 475 // All Routers Addresses: FF01:0:0:0:0:0:0:2 476 // FF02:0:0:0:0:0:0:2 477 // FF05:0:0:0:0:0:0:2 478 // 479 // The above multicast addresses identify the group of all IPv6 routers, 480 // within scope 1 (interface-local), 2 (link-local), or 5 (site-local). 481 for _, g := range allRoutersGroups { 482 if err := e.joinGroupLocked(g); err != nil { 483 // joinGroupLocked only returns an error if the group address is not a 484 // valid IPv6 multicast address. 485 panic(fmt.Sprintf("e.joinGroupLocked(%s): %s", g, err)) 486 } 487 } 488 } else { 489 for _, g := range allRoutersGroups { 490 switch err := e.leaveGroupLocked(g).(type) { 491 case nil: 492 case *tcpip.ErrBadLocalAddress: 493 // The endpoint may have already left the multicast group. 494 default: 495 panic(fmt.Sprintf("e.leaveGroupLocked(%s): %s", g, err)) 496 } 497 } 498 } 499 500 e.mu.ndp.forwardingChanged(forwarding) 501 } 502 503 // Enable implements stack.NetworkEndpoint. 504 func (e *endpoint) Enable() tcpip.Error { 505 e.mu.Lock() 506 defer e.mu.Unlock() 507 508 // If the NIC is not enabled, the endpoint can't do anything meaningful so 509 // don't enable the endpoint. 510 if !e.nic.Enabled() { 511 return &tcpip.ErrNotPermitted{} 512 } 513 514 // If the endpoint is already enabled, there is nothing for it to do. 515 if !e.setEnabled(true) { 516 return nil 517 } 518 519 // Groups may have been joined when the endpoint was disabled, or the 520 // endpoint may have left groups from the perspective of MLD when the 521 // endpoint was disabled. Either way, we need to let routers know to 522 // send us multicast traffic. 523 e.mu.mld.initializeAll() 524 525 // Join the IPv6 All-Nodes Multicast group if the stack is configured to 526 // use IPv6. This is required to ensure that this node properly receives 527 // and responds to the various NDP messages that are destined to the 528 // all-nodes multicast address. An example is the Neighbor Advertisement 529 // when we perform Duplicate Address Detection, or Router Advertisement 530 // when we do Router Discovery. See RFC 4862, section 5.4.2 and RFC 4861 531 // section 4.2 for more information. 532 // 533 // Also auto-generate an IPv6 link-local address based on the endpoint's 534 // link address if it is configured to do so. Note, each interface is 535 // required to have IPv6 link-local unicast address, as per RFC 4291 536 // section 2.1. 537 538 // Join the All-Nodes multicast group before starting DAD as responses to DAD 539 // (NDP NS) messages may be sent to the All-Nodes multicast group if the 540 // source address of the NDP NS is the unspecified address, as per RFC 4861 541 // section 7.2.4. 542 if err := e.joinGroupLocked(header.IPv6AllNodesMulticastAddress); err != nil { 543 // joinGroupLocked only returns an error if the group address is not a valid 544 // IPv6 multicast address. 545 panic(fmt.Sprintf("e.joinGroupLocked(%s): %s", header.IPv6AllNodesMulticastAddress, err)) 546 } 547 548 // Perform DAD on the all the unicast IPv6 endpoints that are in the permanent 549 // state. 550 // 551 // Addresses may have already completed DAD but in the time since the endpoint 552 // was last enabled, other devices may have acquired the same addresses. 553 var err tcpip.Error 554 e.mu.addressableEndpointState.ForEachEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 555 addr := addressEndpoint.AddressWithPrefix().Address 556 if !header.IsV6UnicastAddress(addr) { 557 return true 558 } 559 560 switch addressEndpoint.GetKind() { 561 case stack.Permanent: 562 addressEndpoint.SetKind(stack.PermanentTentative) 563 fallthrough 564 case stack.PermanentTentative: 565 err = e.mu.ndp.startDuplicateAddressDetection(addr, addressEndpoint) 566 return err == nil 567 default: 568 return true 569 } 570 }) 571 if err != nil { 572 return err 573 } 574 575 // Do not auto-generate an IPv6 link-local address for loopback devices. 576 if e.protocol.options.AutoGenLinkLocal && !e.nic.IsLoopback() { 577 // The valid and preferred lifetime is infinite for the auto-generated 578 // link-local address. 579 e.mu.ndp.doSLAAC(header.IPv6LinkLocalPrefix.Subnet(), header.NDPInfiniteLifetime, header.NDPInfiniteLifetime) 580 } 581 582 e.mu.ndp.startSolicitingRouters() 583 return nil 584 } 585 586 // Enabled implements stack.NetworkEndpoint. 587 func (e *endpoint) Enabled() bool { 588 return e.nic.Enabled() && e.isEnabled() 589 } 590 591 // isEnabled returns true if the endpoint is enabled, regardless of the 592 // enabled status of the NIC. 593 func (e *endpoint) isEnabled() bool { 594 return atomic.LoadUint32(&e.enabled) == 1 595 } 596 597 // setEnabled sets the enabled status for the endpoint. 598 // 599 // Returns true if the enabled status was updated. 600 func (e *endpoint) setEnabled(v bool) bool { 601 if v { 602 return atomic.SwapUint32(&e.enabled, 1) == 0 603 } 604 return atomic.SwapUint32(&e.enabled, 0) == 1 605 } 606 607 // Disable implements stack.NetworkEndpoint. 608 func (e *endpoint) Disable() { 609 e.mu.Lock() 610 defer e.mu.Unlock() 611 e.disableLocked() 612 } 613 614 func (e *endpoint) disableLocked() { 615 if !e.Enabled() { 616 return 617 } 618 619 e.mu.ndp.stopSolicitingRouters() 620 // Stop DAD for all the tentative unicast addresses. 621 e.mu.addressableEndpointState.ForEachEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 622 if addressEndpoint.GetKind() != stack.PermanentTentative { 623 return true 624 } 625 626 addr := addressEndpoint.AddressWithPrefix().Address 627 if header.IsV6UnicastAddress(addr) { 628 e.mu.ndp.stopDuplicateAddressDetection(addr, &stack.DADAborted{}) 629 } 630 631 return true 632 }) 633 e.mu.ndp.cleanupState() 634 635 // The endpoint may have already left the multicast group. 636 switch err := e.leaveGroupLocked(header.IPv6AllNodesMulticastAddress).(type) { 637 case nil, *tcpip.ErrBadLocalAddress: 638 default: 639 panic(fmt.Sprintf("unexpected error when leaving group = %s: %s", header.IPv6AllNodesMulticastAddress, err)) 640 } 641 642 // Leave groups from the perspective of MLD so that routers know that 643 // we are no longer interested in the group. 644 e.mu.mld.softLeaveAll() 645 646 if !e.setEnabled(false) { 647 panic("should have only done work to disable the endpoint if it was enabled") 648 } 649 } 650 651 // DefaultTTL is the default hop limit for this endpoint. 652 func (e *endpoint) DefaultTTL() uint8 { 653 return e.protocol.DefaultTTL() 654 } 655 656 // MTU implements stack.NetworkEndpoint. It returns the link-layer MTU minus the 657 // network layer max header length. 658 func (e *endpoint) MTU() uint32 { 659 networkMTU, err := calculateNetworkMTU(e.nic.MTU(), header.IPv6MinimumSize) 660 if err != nil { 661 return 0 662 } 663 return networkMTU 664 } 665 666 // MaxHeaderLength returns the maximum length needed by ipv6 headers (and 667 // underlying protocols). 668 func (e *endpoint) MaxHeaderLength() uint16 { 669 // TODO(github.com/SagerNet/issues/5035): The maximum header length returned here does 670 // not open the possibility for the caller to know about size required for 671 // extension headers. 672 return e.nic.MaxHeaderLength() + header.IPv6MinimumSize 673 } 674 675 func addIPHeader(srcAddr, dstAddr tcpip.Address, pkt *stack.PacketBuffer, params stack.NetworkHeaderParams, extensionHeaders header.IPv6ExtHdrSerializer) tcpip.Error { 676 extHdrsLen := extensionHeaders.Length() 677 length := pkt.Size() + extensionHeaders.Length() 678 if length > math.MaxUint16 { 679 return &tcpip.ErrMessageTooLong{} 680 } 681 header.IPv6(pkt.NetworkHeader().Push(header.IPv6MinimumSize + extHdrsLen)).Encode(&header.IPv6Fields{ 682 PayloadLength: uint16(length), 683 TransportProtocol: params.Protocol, 684 HopLimit: params.TTL, 685 TrafficClass: params.TOS, 686 SrcAddr: srcAddr, 687 DstAddr: dstAddr, 688 ExtensionHeaders: extensionHeaders, 689 }) 690 pkt.NetworkProtocolNumber = ProtocolNumber 691 return nil 692 } 693 694 func packetMustBeFragmented(pkt *stack.PacketBuffer, networkMTU uint32) bool { 695 payload := pkt.TransportHeader().View().Size() + pkt.Data().Size() 696 return pkt.GSOOptions.Type == stack.GSONone && uint32(payload) > networkMTU 697 } 698 699 // handleFragments fragments pkt and calls the handler function on each 700 // fragment. It returns the number of fragments handled and the number of 701 // fragments left to be processed. The IP header must already be present in the 702 // original packet. The transport header protocol number is required to avoid 703 // parsing the IPv6 extension headers. 704 func (e *endpoint) handleFragments(r *stack.Route, networkMTU uint32, pkt *stack.PacketBuffer, transProto tcpip.TransportProtocolNumber, handler func(*stack.PacketBuffer) tcpip.Error) (int, int, tcpip.Error) { 705 networkHeader := header.IPv6(pkt.NetworkHeader().View()) 706 707 // TODO(github.com/SagerNet/issue/3912): Once the Authentication or ESP Headers are 708 // supported for outbound packets, their length should not affect the fragment 709 // maximum payload length because they should only be transmitted once. 710 fragmentPayloadLen := (networkMTU - header.IPv6FragmentHeaderSize) &^ 7 711 if fragmentPayloadLen < header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit { 712 // We need at least 8 bytes of space left for the fragmentable part because 713 // the fragment payload must obviously be non-zero and must be a multiple 714 // of 8 as per RFC 8200 section 4.5: 715 // Each complete fragment, except possibly the last ("rightmost") one, is 716 // an integer multiple of 8 octets long. 717 return 0, 1, &tcpip.ErrMessageTooLong{} 718 } 719 720 if fragmentPayloadLen < uint32(pkt.TransportHeader().View().Size()) { 721 // As per RFC 8200 Section 4.5, the Transport Header is expected to be small 722 // enough to fit in the first fragment. 723 return 0, 1, &tcpip.ErrMessageTooLong{} 724 } 725 726 pf := fragmentation.MakePacketFragmenter(pkt, fragmentPayloadLen, calculateFragmentReserve(pkt)) 727 id := atomic.AddUint32(&e.protocol.ids[hashRoute(r, e.protocol.hashIV)%buckets], 1) 728 729 var n int 730 for { 731 fragPkt, more := buildNextFragment(&pf, networkHeader, transProto, id) 732 if err := handler(fragPkt); err != nil { 733 return n, pf.RemainingFragmentCount() + 1, err 734 } 735 n++ 736 if !more { 737 return n, pf.RemainingFragmentCount(), nil 738 } 739 } 740 } 741 742 // WritePacket writes a packet to the given destination address and protocol. 743 func (e *endpoint) WritePacket(r *stack.Route, params stack.NetworkHeaderParams, pkt *stack.PacketBuffer) tcpip.Error { 744 if err := addIPHeader(r.LocalAddress(), r.RemoteAddress(), pkt, params, nil /* extensionHeaders */); err != nil { 745 return err 746 } 747 748 // iptables filtering. All packets that reach here are locally 749 // generated. 750 outNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID()) 751 if ok := e.protocol.stack.IPTables().Check(stack.Output, pkt, r, "" /* preroutingAddr */, "" /* inNicName */, outNicName); !ok { 752 // iptables is telling us to drop the packet. 753 e.stats.ip.IPTablesOutputDropped.Increment() 754 return nil 755 } 756 757 // If the packet is manipulated as per NAT Output rules, handle packet 758 // based on destination address and do not send the packet to link 759 // layer. 760 // 761 // We should do this for every packet, rather than only NATted packets, but 762 // removing this check short circuits broadcasts before they are sent out to 763 // other hosts. 764 if pkt.NatDone { 765 netHeader := header.IPv6(pkt.NetworkHeader().View()) 766 if ep := e.protocol.findEndpointWithAddress(netHeader.DestinationAddress()); ep != nil { 767 // Since we rewrote the packet but it is being routed back to us, we 768 // can safely assume the checksum is valid. 769 ep.handleLocalPacket(pkt, true /* canSkipRXChecksum */) 770 return nil 771 } 772 } 773 774 return e.writePacket(r, pkt, params.Protocol, false /* headerIncluded */) 775 } 776 777 func (e *endpoint) writePacket(r *stack.Route, pkt *stack.PacketBuffer, protocol tcpip.TransportProtocolNumber, headerIncluded bool) tcpip.Error { 778 if r.Loop()&stack.PacketLoop != 0 { 779 // If the packet was generated by the stack (not a raw/packet endpoint 780 // where a packet may be written with the header included), then we can 781 // safely assume the checksum is valid. 782 e.handleLocalPacket(pkt, !headerIncluded /* canSkipRXChecksum */) 783 } 784 if r.Loop()&stack.PacketOut == 0 { 785 return nil 786 } 787 788 // Postrouting NAT can only change the source address, and does not alter the 789 // route or outgoing interface of the packet. 790 outNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID()) 791 if ok := e.protocol.stack.IPTables().Check(stack.Postrouting, pkt, r, "" /* preroutingAddr */, "" /* inNicName */, outNicName); !ok { 792 // iptables is telling us to drop the packet. 793 e.stats.ip.IPTablesPostroutingDropped.Increment() 794 return nil 795 } 796 797 stats := e.stats.ip 798 networkMTU, err := calculateNetworkMTU(e.nic.MTU(), uint32(pkt.NetworkHeader().View().Size())) 799 if err != nil { 800 stats.OutgoingPacketErrors.Increment() 801 return err 802 } 803 804 if packetMustBeFragmented(pkt, networkMTU) { 805 if pkt.NetworkPacketInfo.IsForwardedPacket { 806 // As per RFC 2460, section 4.5: 807 // Unlike IPv4, fragmentation in IPv6 is performed only by source nodes, 808 // not by routers along a packet's delivery path. 809 return &tcpip.ErrMessageTooLong{} 810 } 811 sent, remain, err := e.handleFragments(r, networkMTU, pkt, protocol, func(fragPkt *stack.PacketBuffer) tcpip.Error { 812 // TODO(github.com/SagerNet/issue/3884): Evaluate whether we want to send each 813 // fragment one by one using WritePacket() (current strategy) or if we 814 // want to create a PacketBufferList from the fragments and feed it to 815 // WritePackets(). It'll be faster but cost more memory. 816 return e.nic.WritePacket(r, ProtocolNumber, fragPkt) 817 }) 818 stats.PacketsSent.IncrementBy(uint64(sent)) 819 stats.OutgoingPacketErrors.IncrementBy(uint64(remain)) 820 return err 821 } 822 823 if err := e.nic.WritePacket(r, ProtocolNumber, pkt); err != nil { 824 stats.OutgoingPacketErrors.Increment() 825 return err 826 } 827 828 stats.PacketsSent.Increment() 829 return nil 830 } 831 832 // WritePackets implements stack.NetworkEndpoint. 833 func (e *endpoint) WritePackets(r *stack.Route, pkts stack.PacketBufferList, params stack.NetworkHeaderParams) (int, tcpip.Error) { 834 if r.Loop()&stack.PacketLoop != 0 { 835 panic("not implemented") 836 } 837 if r.Loop()&stack.PacketOut == 0 { 838 return pkts.Len(), nil 839 } 840 841 stats := e.stats.ip 842 linkMTU := e.nic.MTU() 843 for pb := pkts.Front(); pb != nil; pb = pb.Next() { 844 if err := addIPHeader(r.LocalAddress(), r.RemoteAddress(), pb, params, nil /* extensionHeaders */); err != nil { 845 return 0, err 846 } 847 848 networkMTU, err := calculateNetworkMTU(linkMTU, uint32(pb.NetworkHeader().View().Size())) 849 if err != nil { 850 stats.OutgoingPacketErrors.IncrementBy(uint64(pkts.Len())) 851 return 0, err 852 } 853 if packetMustBeFragmented(pb, networkMTU) { 854 // Keep track of the packet that is about to be fragmented so it can be 855 // removed once the fragmentation is done. 856 originalPkt := pb 857 if _, _, err := e.handleFragments(r, networkMTU, pb, params.Protocol, func(fragPkt *stack.PacketBuffer) tcpip.Error { 858 // Modify the packet list in place with the new fragments. 859 pkts.InsertAfter(pb, fragPkt) 860 pb = fragPkt 861 return nil 862 }); err != nil { 863 stats.OutgoingPacketErrors.IncrementBy(uint64(pkts.Len())) 864 return 0, err 865 } 866 // Remove the packet that was just fragmented and process the rest. 867 pkts.Remove(originalPkt) 868 } 869 } 870 871 // iptables filtering. All packets that reach here are locally 872 // generated. 873 outNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID()) 874 outputDropped, natPkts := e.protocol.stack.IPTables().CheckPackets(stack.Output, pkts, r, "" /* inNicName */, outNicName) 875 stats.IPTablesOutputDropped.IncrementBy(uint64(len(outputDropped))) 876 for pkt := range outputDropped { 877 pkts.Remove(pkt) 878 } 879 880 // The NAT-ed packets may now be destined for us. 881 locallyDelivered := 0 882 for pkt := range natPkts { 883 ep := e.protocol.findEndpointWithAddress(header.IPv6(pkt.NetworkHeader().View()).DestinationAddress()) 884 if ep == nil { 885 // The NAT-ed packet is still destined for some remote node. 886 continue 887 } 888 889 // Do not send the locally destined packet out the NIC. 890 pkts.Remove(pkt) 891 892 // Deliver the packet locally. 893 ep.handleLocalPacket(pkt, true /* canSkipRXChecksum */) 894 locallyDelivered++ 895 } 896 897 // We ignore the list of NAT-ed packets here because Postrouting NAT can only 898 // change the source address, and does not alter the route or outgoing 899 // interface of the packet. 900 postroutingDropped, _ := e.protocol.stack.IPTables().CheckPackets(stack.Postrouting, pkts, r, "" /* inNicName */, outNicName) 901 stats.IPTablesPostroutingDropped.IncrementBy(uint64(len(postroutingDropped))) 902 for pkt := range postroutingDropped { 903 pkts.Remove(pkt) 904 } 905 906 // The rest of the packets can be delivered to the NIC as a batch. 907 pktsLen := pkts.Len() 908 written, err := e.nic.WritePackets(r, pkts, ProtocolNumber) 909 stats.PacketsSent.IncrementBy(uint64(written)) 910 stats.OutgoingPacketErrors.IncrementBy(uint64(pktsLen - written)) 911 912 // Dropped packets aren't errors, so include them in the return value. 913 return locallyDelivered + written + len(outputDropped) + len(postroutingDropped), err 914 } 915 916 // WriteHeaderIncludedPacket implements stack.NetworkEndpoint. 917 func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, pkt *stack.PacketBuffer) tcpip.Error { 918 // The packet already has an IP header, but there are a few required checks. 919 h, ok := pkt.Data().PullUp(header.IPv6MinimumSize) 920 if !ok { 921 return &tcpip.ErrMalformedHeader{} 922 } 923 ipH := header.IPv6(h) 924 925 // Always set the payload length. 926 pktSize := pkt.Data().Size() 927 ipH.SetPayloadLength(uint16(pktSize - header.IPv6MinimumSize)) 928 929 // Set the source address when zero. 930 if ipH.SourceAddress() == header.IPv6Any { 931 ipH.SetSourceAddress(r.LocalAddress()) 932 } 933 934 // Populate the packet buffer's network header and don't allow an invalid 935 // packet to be sent. 936 // 937 // Note that parsing only makes sure that the packet is well formed as per the 938 // wire format. We also want to check if the header's fields are valid before 939 // sending the packet. 940 proto, _, _, _, ok := parse.IPv6(pkt) 941 if !ok || !header.IPv6(pkt.NetworkHeader().View()).IsValid(pktSize) { 942 return &tcpip.ErrMalformedHeader{} 943 } 944 945 return e.writePacket(r, pkt, proto, true /* headerIncluded */) 946 } 947 948 // forwardPacket attempts to forward a packet to its final destination. 949 func (e *endpoint) forwardPacket(pkt *stack.PacketBuffer) ip.ForwardingError { 950 h := header.IPv6(pkt.NetworkHeader().View()) 951 952 dstAddr := h.DestinationAddress() 953 // As per RFC 4291 section 2.5.6, 954 // 955 // Routers must not forward any packets with Link-Local source or 956 // destination addresses to other links. 957 if header.IsV6LinkLocalUnicastAddress(h.SourceAddress()) { 958 return &ip.ErrLinkLocalSourceAddress{} 959 } 960 if header.IsV6LinkLocalUnicastAddress(dstAddr) || header.IsV6LinkLocalMulticastAddress(dstAddr) { 961 return &ip.ErrLinkLocalDestinationAddress{} 962 } 963 964 hopLimit := h.HopLimit() 965 if hopLimit <= 1 { 966 // As per RFC 4443 section 3.3, 967 // 968 // If a router receives a packet with a Hop Limit of zero, or if a 969 // router decrements a packet's Hop Limit to zero, it MUST discard the 970 // packet and originate an ICMPv6 Time Exceeded message with Code 0 to 971 // the source of the packet. This indicates either a routing loop or 972 // too small an initial Hop Limit value. 973 // 974 // We return the original error rather than the result of returning 975 // the ICMP packet because the original error is more relevant to 976 // the caller. 977 _ = e.protocol.returnError(&icmpReasonHopLimitExceeded{}, pkt) 978 return &ip.ErrTTLExceeded{} 979 } 980 981 stk := e.protocol.stack 982 983 // Check if the destination is owned by the stack. 984 if ep := e.protocol.findEndpointWithAddress(dstAddr); ep != nil { 985 inNicName := stk.FindNICNameFromID(e.nic.ID()) 986 outNicName := stk.FindNICNameFromID(ep.nic.ID()) 987 if ok := stk.IPTables().Check(stack.Forward, pkt, nil, "" /* preroutingAddr */, inNicName, outNicName); !ok { 988 // iptables is telling us to drop the packet. 989 e.stats.ip.IPTablesForwardDropped.Increment() 990 return nil 991 } 992 993 // The packet originally arrived on e so provide its NIC as the input NIC. 994 ep.handleValidatedPacket(h, pkt, e.nic.Name() /* inNICName */) 995 return nil 996 } 997 998 // Check extension headers for any errors requiring action during forwarding. 999 if err := e.processExtensionHeaders(h, pkt, true /* forwarding */); err != nil { 1000 return &ip.ErrParameterProblem{} 1001 } 1002 1003 r, err := stk.FindRoute(0, "", dstAddr, ProtocolNumber, false /* multicastLoop */) 1004 switch err.(type) { 1005 case nil: 1006 case *tcpip.ErrNoRoute, *tcpip.ErrNetworkUnreachable: 1007 // We return the original error rather than the result of returning the 1008 // ICMP packet because the original error is more relevant to the caller. 1009 _ = e.protocol.returnError(&icmpReasonNetUnreachable{}, pkt) 1010 return &ip.ErrNoRoute{} 1011 default: 1012 return &ip.ErrOther{Err: err} 1013 } 1014 defer r.Release() 1015 1016 inNicName := stk.FindNICNameFromID(e.nic.ID()) 1017 outNicName := stk.FindNICNameFromID(r.NICID()) 1018 if ok := stk.IPTables().Check(stack.Forward, pkt, nil, "" /* preroutingAddr */, inNicName, outNicName); !ok { 1019 // iptables is telling us to drop the packet. 1020 e.stats.ip.IPTablesForwardDropped.Increment() 1021 return nil 1022 } 1023 1024 // We need to do a deep copy of the IP packet because 1025 // WriteHeaderIncludedPacket takes ownership of the packet buffer, but we do 1026 // not own it. 1027 newHdr := header.IPv6(stack.PayloadSince(pkt.NetworkHeader())) 1028 1029 // As per RFC 8200 section 3, 1030 // 1031 // Hop Limit 8-bit unsigned integer. Decremented by 1 by 1032 // each node that forwards the packet. 1033 newHdr.SetHopLimit(hopLimit - 1) 1034 1035 switch err := r.WriteHeaderIncludedPacket(stack.NewPacketBuffer(stack.PacketBufferOptions{ 1036 ReserveHeaderBytes: int(r.MaxHeaderLength()), 1037 Data: buffer.View(newHdr).ToVectorisedView(), 1038 IsForwardedPacket: true, 1039 })); err.(type) { 1040 case nil: 1041 return nil 1042 case *tcpip.ErrMessageTooLong: 1043 // As per RFC 4443, section 3.2: 1044 // A Packet Too Big MUST be sent by a router in response to a packet that 1045 // it cannot forward because the packet is larger than the MTU of the 1046 // outgoing link. 1047 _ = e.protocol.returnError(&icmpReasonPacketTooBig{}, pkt) 1048 return &ip.ErrMessageTooLong{} 1049 default: 1050 return &ip.ErrOther{Err: err} 1051 } 1052 } 1053 1054 // HandlePacket is called by the link layer when new ipv6 packets arrive for 1055 // this endpoint. 1056 func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) { 1057 stats := e.stats.ip 1058 1059 stats.PacketsReceived.Increment() 1060 1061 if !e.isEnabled() { 1062 stats.DisabledPacketsReceived.Increment() 1063 return 1064 } 1065 1066 h, ok := e.protocol.parseAndValidate(pkt) 1067 if !ok { 1068 stats.MalformedPacketsReceived.Increment() 1069 return 1070 } 1071 1072 if !e.nic.IsLoopback() { 1073 if !e.protocol.options.AllowExternalLoopbackTraffic { 1074 if header.IsV6LoopbackAddress(h.SourceAddress()) { 1075 stats.InvalidSourceAddressesReceived.Increment() 1076 return 1077 } 1078 1079 if header.IsV6LoopbackAddress(h.DestinationAddress()) { 1080 stats.InvalidDestinationAddressesReceived.Increment() 1081 return 1082 } 1083 } 1084 1085 if e.protocol.stack.HandleLocal() { 1086 addressEndpoint := e.AcquireAssignedAddress(header.IPv6(pkt.NetworkHeader().View()).SourceAddress(), e.nic.Promiscuous(), stack.CanBePrimaryEndpoint) 1087 if addressEndpoint != nil { 1088 addressEndpoint.DecRef() 1089 1090 // The source address is one of our own, so we never should have gotten 1091 // a packet like this unless HandleLocal is false or our NIC is the 1092 // loopback interface. 1093 stats.InvalidSourceAddressesReceived.Increment() 1094 return 1095 } 1096 } 1097 1098 // Loopback traffic skips the prerouting chain. 1099 inNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID()) 1100 if ok := e.protocol.stack.IPTables().Check(stack.Prerouting, pkt, nil, e.MainAddress().Address, inNicName, "" /* outNicName */); !ok { 1101 // iptables is telling us to drop the packet. 1102 stats.IPTablesPreroutingDropped.Increment() 1103 return 1104 } 1105 } 1106 1107 e.handleValidatedPacket(h, pkt, e.nic.Name() /* inNICName */) 1108 } 1109 1110 // handleLocalPacket is like HandlePacket except it does not perform the 1111 // prerouting iptables hook or check for loopback traffic that originated from 1112 // outside of the netstack (i.e. martian loopback packets). 1113 func (e *endpoint) handleLocalPacket(pkt *stack.PacketBuffer, canSkipRXChecksum bool) { 1114 stats := e.stats.ip 1115 stats.PacketsReceived.Increment() 1116 1117 pkt = pkt.CloneToInbound() 1118 pkt.RXTransportChecksumValidated = canSkipRXChecksum 1119 1120 h, ok := e.protocol.parseAndValidate(pkt) 1121 if !ok { 1122 stats.MalformedPacketsReceived.Increment() 1123 return 1124 } 1125 1126 e.handleValidatedPacket(h, pkt, e.nic.Name() /* inNICName */) 1127 } 1128 1129 func (e *endpoint) handleValidatedPacket(h header.IPv6, pkt *stack.PacketBuffer, inNICName string) { 1130 // Raw socket packets are delivered based solely on the transport protocol 1131 // number. We only require that the packet be valid IPv6. 1132 e.dispatcher.DeliverRawPacket(h.TransportProtocol(), pkt) 1133 1134 pkt.NICID = e.nic.ID() 1135 stats := e.stats.ip 1136 stats.ValidPacketsReceived.Increment() 1137 1138 srcAddr := h.SourceAddress() 1139 dstAddr := h.DestinationAddress() 1140 1141 // As per RFC 4291 section 2.7: 1142 // Multicast addresses must not be used as source addresses in IPv6 1143 // packets or appear in any Routing header. 1144 if header.IsV6MulticastAddress(srcAddr) { 1145 stats.InvalidSourceAddressesReceived.Increment() 1146 return 1147 } 1148 1149 // The destination address should be an address we own or a group we joined 1150 // for us to receive the packet. Otherwise, attempt to forward the packet. 1151 if addressEndpoint := e.AcquireAssignedAddress(dstAddr, e.nic.Promiscuous(), stack.CanBePrimaryEndpoint); addressEndpoint != nil { 1152 addressEndpoint.DecRef() 1153 } else if !e.IsInGroup(dstAddr) { 1154 if !e.Forwarding() { 1155 stats.InvalidDestinationAddressesReceived.Increment() 1156 return 1157 } 1158 switch err := e.forwardPacket(pkt); err.(type) { 1159 case nil: 1160 return 1161 case *ip.ErrLinkLocalSourceAddress: 1162 e.stats.ip.Forwarding.LinkLocalSource.Increment() 1163 case *ip.ErrLinkLocalDestinationAddress: 1164 e.stats.ip.Forwarding.LinkLocalDestination.Increment() 1165 case *ip.ErrTTLExceeded: 1166 e.stats.ip.Forwarding.ExhaustedTTL.Increment() 1167 case *ip.ErrNoRoute: 1168 e.stats.ip.Forwarding.Unrouteable.Increment() 1169 case *ip.ErrParameterProblem: 1170 e.stats.ip.Forwarding.ExtensionHeaderProblem.Increment() 1171 case *ip.ErrMessageTooLong: 1172 e.stats.ip.Forwarding.PacketTooBig.Increment() 1173 default: 1174 panic(fmt.Sprintf("unexpected error %s while trying to forward packet: %#v", err, pkt)) 1175 } 1176 e.stats.ip.Forwarding.Errors.Increment() 1177 return 1178 } 1179 1180 // iptables filtering. All packets that reach here are intended for 1181 // this machine and need not be forwarded. 1182 if ok := e.protocol.stack.IPTables().Check(stack.Input, pkt, nil, "" /* preroutingAddr */, inNICName, "" /* outNicName */); !ok { 1183 // iptables is telling us to drop the packet. 1184 stats.IPTablesInputDropped.Increment() 1185 return 1186 } 1187 1188 // Any returned error is only useful for terminating execution early, but 1189 // we have nothing left to do, so we can drop it. 1190 _ = e.processExtensionHeaders(h, pkt, false /* forwarding */) 1191 } 1192 1193 // processExtensionHeaders processes the extension headers in the given packet. 1194 // Returns an error if the processing of a header failed or if the packet should 1195 // be discarded. 1196 func (e *endpoint) processExtensionHeaders(h header.IPv6, pkt *stack.PacketBuffer, forwarding bool) error { 1197 stats := e.stats.ip 1198 srcAddr := h.SourceAddress() 1199 dstAddr := h.DestinationAddress() 1200 1201 // Create a VV to parse the packet. We don't plan to modify anything here. 1202 // vv consists of: 1203 // - Any IPv6 header bytes after the first 40 (i.e. extensions). 1204 // - The transport header, if present. 1205 // - Any other payload data. 1206 vv := pkt.NetworkHeader().View()[header.IPv6MinimumSize:].ToVectorisedView() 1207 vv.AppendView(pkt.TransportHeader().View()) 1208 vv.AppendViews(pkt.Data().Views()) 1209 it := header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(h.NextHeader()), vv) 1210 1211 var ( 1212 hasFragmentHeader bool 1213 routerAlert *header.IPv6RouterAlertOption 1214 ) 1215 1216 for { 1217 // Keep track of the start of the previous header so we can report the 1218 // special case of a Hop by Hop at a location other than at the start. 1219 previousHeaderStart := it.HeaderOffset() 1220 extHdr, done, err := it.Next() 1221 if err != nil { 1222 stats.MalformedPacketsReceived.Increment() 1223 return err 1224 } 1225 if done { 1226 break 1227 } 1228 1229 // As per RFC 8200, section 4: 1230 // 1231 // Extension headers (except for the Hop-by-Hop Options header) are 1232 // not processed, inserted, or deleted by any node along a packet's 1233 // delivery path until the packet reaches the node identified in the 1234 // Destination Address field of the IPv6 header. 1235 // 1236 // Furthermore, as per RFC 8200 section 4.1, the Hop By Hop extension 1237 // header is restricted to appear first in the list of extension headers. 1238 // 1239 // Therefore, we can immediately return once we hit any header other 1240 // than the Hop-by-Hop header while forwarding a packet. 1241 if forwarding { 1242 if _, ok := extHdr.(header.IPv6HopByHopOptionsExtHdr); !ok { 1243 return nil 1244 } 1245 } 1246 1247 switch extHdr := extHdr.(type) { 1248 case header.IPv6HopByHopOptionsExtHdr: 1249 // As per RFC 8200 section 4.1, the Hop By Hop extension header is 1250 // restricted to appear immediately after an IPv6 fixed header. 1251 if previousHeaderStart != 0 { 1252 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1253 code: header.ICMPv6UnknownHeader, 1254 pointer: previousHeaderStart, 1255 forwarding: forwarding, 1256 }, pkt) 1257 return fmt.Errorf("found Hop-by-Hop header = %#v with non-zero previous header offset = %d", extHdr, previousHeaderStart) 1258 } 1259 1260 optsIt := extHdr.Iter() 1261 1262 for { 1263 opt, done, err := optsIt.Next() 1264 if err != nil { 1265 stats.MalformedPacketsReceived.Increment() 1266 return err 1267 } 1268 if done { 1269 break 1270 } 1271 1272 switch opt := opt.(type) { 1273 case *header.IPv6RouterAlertOption: 1274 if routerAlert != nil { 1275 // As per RFC 2711 section 3, there should be at most one Router 1276 // Alert option per packet. 1277 // 1278 // There MUST only be one option of this type, regardless of 1279 // value, per Hop-by-Hop header. 1280 stats.MalformedPacketsReceived.Increment() 1281 return fmt.Errorf("found multiple Router Alert options (%#v, %#v)", opt, routerAlert) 1282 } 1283 routerAlert = opt 1284 stats.OptionRouterAlertReceived.Increment() 1285 default: 1286 switch opt.UnknownAction() { 1287 case header.IPv6OptionUnknownActionSkip: 1288 case header.IPv6OptionUnknownActionDiscard: 1289 return fmt.Errorf("found unknown Hop-by-Hop header option = %#v with discard action", opt) 1290 case header.IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest: 1291 if header.IsV6MulticastAddress(dstAddr) { 1292 return fmt.Errorf("found unknown hop-by-hop header option = %#v with discard action", opt) 1293 } 1294 fallthrough 1295 case header.IPv6OptionUnknownActionDiscardSendICMP: 1296 // This case satisfies a requirement of RFC 8200 section 4.2 which 1297 // states that an unknown option starting with bits [10] should: 1298 // 1299 // discard the packet and, regardless of whether or not the 1300 // packet's Destination Address was a multicast address, send an 1301 // ICMP Parameter Problem, Code 2, message to the packet's 1302 // Source Address, pointing to the unrecognized Option Type. 1303 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1304 code: header.ICMPv6UnknownOption, 1305 pointer: it.ParseOffset() + optsIt.OptionOffset(), 1306 respondToMulticast: true, 1307 forwarding: forwarding, 1308 }, pkt) 1309 return fmt.Errorf("found unknown hop-by-hop header option = %#v with discard action", opt) 1310 default: 1311 panic(fmt.Sprintf("unrecognized action for an unrecognized Hop By Hop extension header option = %#v", opt)) 1312 } 1313 } 1314 } 1315 1316 case header.IPv6RoutingExtHdr: 1317 // As per RFC 8200 section 4.4, if a node encounters a routing header with 1318 // an unrecognized routing type value, with a non-zero Segments Left 1319 // value, the node must discard the packet and send an ICMP Parameter 1320 // Problem, Code 0 to the packet's Source Address, pointing to the 1321 // unrecognized Routing Type. 1322 // 1323 // If the Segments Left is 0, the node must ignore the Routing extension 1324 // header and process the next header in the packet. 1325 // 1326 // Note, the stack does not yet handle any type of routing extension 1327 // header, so we just make sure Segments Left is zero before processing 1328 // the next extension header. 1329 if extHdr.SegmentsLeft() != 0 { 1330 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1331 code: header.ICMPv6ErroneousHeader, 1332 pointer: it.ParseOffset(), 1333 // For the sake of consistency, we're using the value of `forwarding` 1334 // here, even though it should always be false if we've reached this 1335 // point. If `forwarding` is true here, we're executing undefined 1336 // behavior no matter what. 1337 forwarding: forwarding, 1338 }, pkt) 1339 return fmt.Errorf("found unrecognized routing type with non-zero segments left in header = %#v", extHdr) 1340 } 1341 1342 case header.IPv6FragmentExtHdr: 1343 hasFragmentHeader = true 1344 1345 if extHdr.IsAtomic() { 1346 // This fragment extension header indicates that this packet is an 1347 // atomic fragment. An atomic fragment is a fragment that contains 1348 // all the data required to reassemble a full packet. As per RFC 6946, 1349 // atomic fragments must not interfere with "normal" fragmented traffic 1350 // so we skip processing the fragment instead of feeding it through the 1351 // reassembly process below. 1352 continue 1353 } 1354 1355 fragmentFieldOffset := it.ParseOffset() 1356 1357 // Don't consume the iterator if we have the first fragment because we 1358 // will use it to validate that the first fragment holds the upper layer 1359 // header. 1360 rawPayload := it.AsRawHeader(extHdr.FragmentOffset() != 0 /* consume */) 1361 1362 if extHdr.FragmentOffset() == 0 { 1363 // Check that the iterator ends with a raw payload as the first fragment 1364 // should include all headers up to and including any upper layer 1365 // headers, as per RFC 8200 section 4.5; only upper layer data 1366 // (non-headers) should follow the fragment extension header. 1367 var lastHdr header.IPv6PayloadHeader 1368 1369 for { 1370 it, done, err := it.Next() 1371 if err != nil { 1372 stats.MalformedPacketsReceived.Increment() 1373 stats.MalformedFragmentsReceived.Increment() 1374 return err 1375 } 1376 if done { 1377 break 1378 } 1379 1380 lastHdr = it 1381 } 1382 1383 // If the last header is a raw header, then the last portion of the IPv6 1384 // payload is not a known IPv6 extension header. Note, this does not 1385 // mean that the last portion is an upper layer header or not an 1386 // extension header because: 1387 // 1) we do not yet support all extension headers 1388 // 2) we do not validate the upper layer header before reassembling. 1389 // 1390 // This check makes sure that a known IPv6 extension header is not 1391 // present after the Fragment extension header in a non-initial 1392 // fragment. 1393 // 1394 // TODO(#2196): Support IPv6 Authentication and Encapsulated 1395 // Security Payload extension headers. 1396 // TODO(#2333): Validate that the upper layer header is valid. 1397 switch lastHdr.(type) { 1398 case header.IPv6RawPayloadHeader: 1399 default: 1400 stats.MalformedPacketsReceived.Increment() 1401 stats.MalformedFragmentsReceived.Increment() 1402 return fmt.Errorf("known extension header = %#v present after fragment header in a non-initial fragment", lastHdr) 1403 } 1404 } 1405 1406 fragmentPayloadLen := rawPayload.Buf.Size() 1407 if fragmentPayloadLen == 0 { 1408 // Drop the packet as it's marked as a fragment but has no payload. 1409 stats.MalformedPacketsReceived.Increment() 1410 stats.MalformedFragmentsReceived.Increment() 1411 return fmt.Errorf("fragment has no payload") 1412 } 1413 1414 // As per RFC 2460 Section 4.5: 1415 // 1416 // If the length of a fragment, as derived from the fragment packet's 1417 // Payload Length field, is not a multiple of 8 octets and the M flag 1418 // of that fragment is 1, then that fragment must be discarded and an 1419 // ICMP Parameter Problem, Code 0, message should be sent to the source 1420 // of the fragment, pointing to the Payload Length field of the 1421 // fragment packet. 1422 if extHdr.More() && fragmentPayloadLen%header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit != 0 { 1423 stats.MalformedPacketsReceived.Increment() 1424 stats.MalformedFragmentsReceived.Increment() 1425 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1426 code: header.ICMPv6ErroneousHeader, 1427 pointer: header.IPv6PayloadLenOffset, 1428 }, pkt) 1429 return fmt.Errorf("found fragment length = %d that is not a multiple of 8 octets", fragmentPayloadLen) 1430 } 1431 1432 // The packet is a fragment, let's try to reassemble it. 1433 start := extHdr.FragmentOffset() * header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit 1434 1435 // As per RFC 2460 Section 4.5: 1436 // 1437 // If the length and offset of a fragment are such that the Payload 1438 // Length of the packet reassembled from that fragment would exceed 1439 // 65,535 octets, then that fragment must be discarded and an ICMP 1440 // Parameter Problem, Code 0, message should be sent to the source of 1441 // the fragment, pointing to the Fragment Offset field of the fragment 1442 // packet. 1443 lengthAfterReassembly := int(start) + fragmentPayloadLen 1444 if lengthAfterReassembly > header.IPv6MaximumPayloadSize { 1445 stats.MalformedPacketsReceived.Increment() 1446 stats.MalformedFragmentsReceived.Increment() 1447 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1448 code: header.ICMPv6ErroneousHeader, 1449 pointer: fragmentFieldOffset, 1450 }, pkt) 1451 return fmt.Errorf("determined that reassembled packet length = %d would exceed allowed length = %d", lengthAfterReassembly, header.IPv6MaximumPayloadSize) 1452 } 1453 1454 // Note that pkt doesn't have its transport header set after reassembly, 1455 // and won't until DeliverNetworkPacket sets it. 1456 resPkt, proto, ready, err := e.protocol.fragmentation.Process( 1457 // IPv6 ignores the Protocol field since the ID only needs to be unique 1458 // across source-destination pairs, as per RFC 8200 section 4.5. 1459 fragmentation.FragmentID{ 1460 Source: srcAddr, 1461 Destination: dstAddr, 1462 ID: extHdr.ID(), 1463 }, 1464 start, 1465 start+uint16(fragmentPayloadLen)-1, 1466 extHdr.More(), 1467 uint8(rawPayload.Identifier), 1468 pkt, 1469 ) 1470 if err != nil { 1471 stats.MalformedPacketsReceived.Increment() 1472 stats.MalformedFragmentsReceived.Increment() 1473 return err 1474 } 1475 1476 if ready { 1477 pkt = resPkt 1478 1479 // We create a new iterator with the reassembled packet because we could 1480 // have more extension headers in the reassembled payload, as per RFC 1481 // 8200 section 4.5. We also use the NextHeader value from the first 1482 // fragment. 1483 data := pkt.Data() 1484 dataVV := buffer.NewVectorisedView(data.Size(), data.Views()) 1485 it = header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(proto), dataVV) 1486 } 1487 1488 case header.IPv6DestinationOptionsExtHdr: 1489 optsIt := extHdr.Iter() 1490 1491 for { 1492 opt, done, err := optsIt.Next() 1493 if err != nil { 1494 stats.MalformedPacketsReceived.Increment() 1495 return err 1496 } 1497 if done { 1498 break 1499 } 1500 1501 // We currently do not support any IPv6 Destination extension header 1502 // options. 1503 switch opt.UnknownAction() { 1504 case header.IPv6OptionUnknownActionSkip: 1505 case header.IPv6OptionUnknownActionDiscard: 1506 return fmt.Errorf("found unknown destination header option = %#v with discard action", opt) 1507 case header.IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest: 1508 if header.IsV6MulticastAddress(dstAddr) { 1509 return fmt.Errorf("found unknown destination header option %#v with discard action", opt) 1510 } 1511 fallthrough 1512 case header.IPv6OptionUnknownActionDiscardSendICMP: 1513 // This case satisfies a requirement of RFC 8200 section 4.2 1514 // which states that an unknown option starting with bits [10] should: 1515 // 1516 // discard the packet and, regardless of whether or not the 1517 // packet's Destination Address was a multicast address, send an 1518 // ICMP Parameter Problem, Code 2, message to the packet's 1519 // Source Address, pointing to the unrecognized Option Type. 1520 // 1521 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1522 code: header.ICMPv6UnknownOption, 1523 pointer: it.ParseOffset() + optsIt.OptionOffset(), 1524 respondToMulticast: true, 1525 }, pkt) 1526 return fmt.Errorf("found unknown destination header option %#v with discard action", opt) 1527 default: 1528 panic(fmt.Sprintf("unrecognized action for an unrecognized Destination extension header option = %#v", opt)) 1529 } 1530 } 1531 1532 case header.IPv6RawPayloadHeader: 1533 // If the last header in the payload isn't a known IPv6 extension header, 1534 // handle it as if it is transport layer data. 1535 1536 // Calculate the number of octets parsed from data. We want to remove all 1537 // the data except the unparsed portion located at the end, which its size 1538 // is extHdr.Buf.Size(). 1539 trim := pkt.Data().Size() - extHdr.Buf.Size() 1540 1541 // For unfragmented packets, extHdr still contains the transport header. 1542 // Get rid of it. 1543 // 1544 // For reassembled fragments, pkt.TransportHeader is unset, so this is a 1545 // no-op and pkt.Data begins with the transport header. 1546 trim += pkt.TransportHeader().View().Size() 1547 1548 pkt.Data().DeleteFront(trim) 1549 1550 stats.PacketsDelivered.Increment() 1551 if p := tcpip.TransportProtocolNumber(extHdr.Identifier); p == header.ICMPv6ProtocolNumber { 1552 pkt.TransportProtocolNumber = p 1553 e.handleICMP(pkt, hasFragmentHeader, routerAlert) 1554 } else { 1555 stats.PacketsDelivered.Increment() 1556 switch res := e.dispatcher.DeliverTransportPacket(p, pkt); res { 1557 case stack.TransportPacketHandled: 1558 case stack.TransportPacketDestinationPortUnreachable: 1559 // As per RFC 4443 section 3.1: 1560 // A destination node SHOULD originate a Destination Unreachable 1561 // message with Code 4 in response to a packet for which the 1562 // transport protocol (e.g., UDP) has no listener, if that transport 1563 // protocol has no alternative means to inform the sender. 1564 _ = e.protocol.returnError(&icmpReasonPortUnreachable{}, pkt) 1565 return fmt.Errorf("destination port unreachable") 1566 case stack.TransportPacketProtocolUnreachable: 1567 // As per RFC 8200 section 4. (page 7): 1568 // Extension headers are numbered from IANA IP Protocol Numbers 1569 // [IANA-PN], the same values used for IPv4 and IPv6. When 1570 // processing a sequence of Next Header values in a packet, the 1571 // first one that is not an extension header [IANA-EH] indicates 1572 // that the next item in the packet is the corresponding upper-layer 1573 // header. 1574 // With more related information on page 8: 1575 // If, as a result of processing a header, the destination node is 1576 // required to proceed to the next header but the Next Header value 1577 // in the current header is unrecognized by the node, it should 1578 // discard the packet and send an ICMP Parameter Problem message to 1579 // the source of the packet, with an ICMP Code value of 1 1580 // ("unrecognized Next Header type encountered") and the ICMP 1581 // Pointer field containing the offset of the unrecognized value 1582 // within the original packet. 1583 // 1584 // Which when taken together indicate that an unknown protocol should 1585 // be treated as an unrecognized next header value. 1586 // The location of the Next Header field is in a different place in 1587 // the initial IPv6 header than it is in the extension headers so 1588 // treat it specially. 1589 prevHdrIDOffset := uint32(header.IPv6NextHeaderOffset) 1590 if previousHeaderStart != 0 { 1591 prevHdrIDOffset = previousHeaderStart 1592 } 1593 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1594 code: header.ICMPv6UnknownHeader, 1595 pointer: prevHdrIDOffset, 1596 }, pkt) 1597 return fmt.Errorf("transport protocol unreachable") 1598 default: 1599 panic(fmt.Sprintf("unrecognized result from DeliverTransportPacket = %d", res)) 1600 } 1601 } 1602 1603 default: 1604 // Since the iterator returns IPv6RawPayloadHeader for unknown Extension 1605 // Header IDs this should never happen unless we missed a supported type 1606 // here. 1607 panic(fmt.Sprintf("unrecognized type from it.Next() = %T", extHdr)) 1608 1609 } 1610 } 1611 return nil 1612 } 1613 1614 // Close cleans up resources associated with the endpoint. 1615 func (e *endpoint) Close() { 1616 e.mu.Lock() 1617 e.disableLocked() 1618 e.mu.addressableEndpointState.Cleanup() 1619 e.mu.Unlock() 1620 1621 e.protocol.forgetEndpoint(e.nic.ID()) 1622 } 1623 1624 // NetworkProtocolNumber implements stack.NetworkEndpoint. 1625 func (e *endpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber { 1626 return e.protocol.Number() 1627 } 1628 1629 // AddAndAcquirePermanentAddress implements stack.AddressableEndpoint. 1630 func (e *endpoint) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, peb stack.PrimaryEndpointBehavior, configType stack.AddressConfigType, deprecated bool) (stack.AddressEndpoint, tcpip.Error) { 1631 // TODO(b/169350103): add checks here after making sure we no longer receive 1632 // an empty address. 1633 e.mu.Lock() 1634 defer e.mu.Unlock() 1635 return e.addAndAcquirePermanentAddressLocked(addr, peb, configType, deprecated) 1636 } 1637 1638 // addAndAcquirePermanentAddressLocked is like AddAndAcquirePermanentAddress but 1639 // with locking requirements. 1640 // 1641 // addAndAcquirePermanentAddressLocked also joins the passed address's 1642 // solicited-node multicast group and start duplicate address detection. 1643 // 1644 // Precondition: e.mu must be write locked. 1645 func (e *endpoint) addAndAcquirePermanentAddressLocked(addr tcpip.AddressWithPrefix, peb stack.PrimaryEndpointBehavior, configType stack.AddressConfigType, deprecated bool) (stack.AddressEndpoint, tcpip.Error) { 1646 addressEndpoint, err := e.mu.addressableEndpointState.AddAndAcquirePermanentAddress(addr, peb, configType, deprecated) 1647 if err != nil { 1648 return nil, err 1649 } 1650 1651 if !header.IsV6UnicastAddress(addr.Address) { 1652 return addressEndpoint, nil 1653 } 1654 1655 addressEndpoint.SetKind(stack.PermanentTentative) 1656 1657 if e.Enabled() { 1658 if err := e.mu.ndp.startDuplicateAddressDetection(addr.Address, addressEndpoint); err != nil { 1659 return nil, err 1660 } 1661 } 1662 1663 snmc := header.SolicitedNodeAddr(addr.Address) 1664 if err := e.joinGroupLocked(snmc); err != nil { 1665 // joinGroupLocked only returns an error if the group address is not a valid 1666 // IPv6 multicast address. 1667 panic(fmt.Sprintf("e.joinGroupLocked(%s): %s", snmc, err)) 1668 } 1669 1670 return addressEndpoint, nil 1671 } 1672 1673 // RemovePermanentAddress implements stack.AddressableEndpoint. 1674 func (e *endpoint) RemovePermanentAddress(addr tcpip.Address) tcpip.Error { 1675 e.mu.Lock() 1676 defer e.mu.Unlock() 1677 1678 addressEndpoint := e.getAddressRLocked(addr) 1679 if addressEndpoint == nil || !addressEndpoint.GetKind().IsPermanent() { 1680 return &tcpip.ErrBadLocalAddress{} 1681 } 1682 1683 return e.removePermanentEndpointLocked(addressEndpoint, true /* allowSLAACInvalidation */, &stack.DADAborted{}) 1684 } 1685 1686 // removePermanentEndpointLocked is like removePermanentAddressLocked except 1687 // it works with a stack.AddressEndpoint. 1688 // 1689 // Precondition: e.mu must be write locked. 1690 func (e *endpoint) removePermanentEndpointLocked(addressEndpoint stack.AddressEndpoint, allowSLAACInvalidation bool, dadResult stack.DADResult) tcpip.Error { 1691 addr := addressEndpoint.AddressWithPrefix() 1692 // If we are removing an address generated via SLAAC, cleanup 1693 // its SLAAC resources and notify the integrator. 1694 switch addressEndpoint.ConfigType() { 1695 case stack.AddressConfigSlaac: 1696 e.mu.ndp.cleanupSLAACAddrResourcesAndNotify(addr, allowSLAACInvalidation) 1697 case stack.AddressConfigSlaacTemp: 1698 e.mu.ndp.cleanupTempSLAACAddrResourcesAndNotify(addr) 1699 } 1700 1701 return e.removePermanentEndpointInnerLocked(addressEndpoint, dadResult) 1702 } 1703 1704 // removePermanentEndpointInnerLocked is like removePermanentEndpointLocked 1705 // except it does not cleanup SLAAC address state. 1706 // 1707 // Precondition: e.mu must be write locked. 1708 func (e *endpoint) removePermanentEndpointInnerLocked(addressEndpoint stack.AddressEndpoint, dadResult stack.DADResult) tcpip.Error { 1709 addr := addressEndpoint.AddressWithPrefix() 1710 e.mu.ndp.stopDuplicateAddressDetection(addr.Address, dadResult) 1711 1712 if err := e.mu.addressableEndpointState.RemovePermanentEndpoint(addressEndpoint); err != nil { 1713 return err 1714 } 1715 1716 snmc := header.SolicitedNodeAddr(addr.Address) 1717 err := e.leaveGroupLocked(snmc) 1718 // The endpoint may have already left the multicast group. 1719 if _, ok := err.(*tcpip.ErrBadLocalAddress); ok { 1720 err = nil 1721 } 1722 return err 1723 } 1724 1725 // hasPermanentAddressLocked returns true if the endpoint has a permanent 1726 // address equal to the passed address. 1727 // 1728 // Precondition: e.mu must be read or write locked. 1729 func (e *endpoint) hasPermanentAddressRLocked(addr tcpip.Address) bool { 1730 addressEndpoint := e.getAddressRLocked(addr) 1731 if addressEndpoint == nil { 1732 return false 1733 } 1734 return addressEndpoint.GetKind().IsPermanent() 1735 } 1736 1737 // getAddressRLocked returns the endpoint for the passed address. 1738 // 1739 // Precondition: e.mu must be read or write locked. 1740 func (e *endpoint) getAddressRLocked(localAddr tcpip.Address) stack.AddressEndpoint { 1741 return e.mu.addressableEndpointState.GetAddress(localAddr) 1742 } 1743 1744 // MainAddress implements stack.AddressableEndpoint. 1745 func (e *endpoint) MainAddress() tcpip.AddressWithPrefix { 1746 e.mu.RLock() 1747 defer e.mu.RUnlock() 1748 return e.mu.addressableEndpointState.MainAddress() 1749 } 1750 1751 // AcquireAssignedAddress implements stack.AddressableEndpoint. 1752 func (e *endpoint) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB stack.PrimaryEndpointBehavior) stack.AddressEndpoint { 1753 e.mu.RLock() 1754 defer e.mu.RUnlock() 1755 return e.acquireAddressOrCreateTempLocked(localAddr, allowTemp, tempPEB) 1756 } 1757 1758 // acquireAddressOrCreateTempLocked is like AcquireAssignedAddress but with 1759 // locking requirements. 1760 // 1761 // Precondition: e.mu must be write locked. 1762 func (e *endpoint) acquireAddressOrCreateTempLocked(localAddr tcpip.Address, allowTemp bool, tempPEB stack.PrimaryEndpointBehavior) stack.AddressEndpoint { 1763 return e.mu.addressableEndpointState.AcquireAssignedAddress(localAddr, allowTemp, tempPEB) 1764 } 1765 1766 // AcquireOutgoingPrimaryAddress implements stack.AddressableEndpoint. 1767 func (e *endpoint) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allowExpired bool) stack.AddressEndpoint { 1768 e.mu.RLock() 1769 defer e.mu.RUnlock() 1770 return e.acquireOutgoingPrimaryAddressRLocked(remoteAddr, allowExpired) 1771 } 1772 1773 // getLinkLocalAddressRLocked returns a link-local address from the primary list 1774 // of addresses, if one is available. 1775 // 1776 // See stack.PrimaryEndpointBehavior for more details about the primary list. 1777 // 1778 // Precondition: e.mu must be read locked. 1779 func (e *endpoint) getLinkLocalAddressRLocked() tcpip.Address { 1780 var linkLocalAddr tcpip.Address 1781 e.mu.addressableEndpointState.ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 1782 if addressEndpoint.IsAssigned(false /* allowExpired */) { 1783 if addr := addressEndpoint.AddressWithPrefix().Address; header.IsV6LinkLocalUnicastAddress(addr) { 1784 linkLocalAddr = addr 1785 return false 1786 } 1787 } 1788 return true 1789 }) 1790 return linkLocalAddr 1791 } 1792 1793 // acquireOutgoingPrimaryAddressRLocked is like AcquireOutgoingPrimaryAddress 1794 // but with locking requirements. 1795 // 1796 // Precondition: e.mu must be read locked. 1797 func (e *endpoint) acquireOutgoingPrimaryAddressRLocked(remoteAddr tcpip.Address, allowExpired bool) stack.AddressEndpoint { 1798 // addrCandidate is a candidate for Source Address Selection, as per 1799 // RFC 6724 section 5. 1800 type addrCandidate struct { 1801 addressEndpoint stack.AddressEndpoint 1802 addr tcpip.Address 1803 scope header.IPv6AddressScope 1804 1805 label uint8 1806 matchingPrefix uint8 1807 } 1808 1809 if len(remoteAddr) == 0 { 1810 return e.mu.addressableEndpointState.AcquireOutgoingPrimaryAddress(remoteAddr, allowExpired) 1811 } 1812 1813 // Create a candidate set of available addresses we can potentially use as a 1814 // source address. 1815 var cs []addrCandidate 1816 e.mu.addressableEndpointState.ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 1817 // If r is not valid for outgoing connections, it is not a valid endpoint. 1818 if !addressEndpoint.IsAssigned(allowExpired) { 1819 return true 1820 } 1821 1822 addr := addressEndpoint.AddressWithPrefix().Address 1823 scope, err := header.ScopeForIPv6Address(addr) 1824 if err != nil { 1825 // Should never happen as we got r from the primary IPv6 endpoint list and 1826 // ScopeForIPv6Address only returns an error if addr is not an IPv6 1827 // address. 1828 panic(fmt.Sprintf("header.ScopeForIPv6Address(%s): %s", addr, err)) 1829 } 1830 1831 cs = append(cs, addrCandidate{ 1832 addressEndpoint: addressEndpoint, 1833 addr: addr, 1834 scope: scope, 1835 label: getLabel(addr), 1836 matchingPrefix: remoteAddr.MatchingPrefix(addr), 1837 }) 1838 1839 return true 1840 }) 1841 1842 remoteScope, err := header.ScopeForIPv6Address(remoteAddr) 1843 if err != nil { 1844 // primaryIPv6Endpoint should never be called with an invalid IPv6 address. 1845 panic(fmt.Sprintf("header.ScopeForIPv6Address(%s): %s", remoteAddr, err)) 1846 } 1847 1848 remoteLabel := getLabel(remoteAddr) 1849 1850 // Sort the addresses as per RFC 6724 section 5 rules 1-3. 1851 // 1852 // TODO(b/146021396): Implement rules 4, 5 of RFC 6724 section 5. 1853 sort.Slice(cs, func(i, j int) bool { 1854 sa := cs[i] 1855 sb := cs[j] 1856 1857 // Prefer same address as per RFC 6724 section 5 rule 1. 1858 if sa.addr == remoteAddr { 1859 return true 1860 } 1861 if sb.addr == remoteAddr { 1862 return false 1863 } 1864 1865 // Prefer appropriate scope as per RFC 6724 section 5 rule 2. 1866 if sa.scope < sb.scope { 1867 return sa.scope >= remoteScope 1868 } else if sb.scope < sa.scope { 1869 return sb.scope < remoteScope 1870 } 1871 1872 // Avoid deprecated addresses as per RFC 6724 section 5 rule 3. 1873 if saDep, sbDep := sa.addressEndpoint.Deprecated(), sb.addressEndpoint.Deprecated(); saDep != sbDep { 1874 // If sa is not deprecated, it is preferred over sb. 1875 return sbDep 1876 } 1877 1878 // Prefer matching label as per RFC 6724 section 5 rule 6. 1879 if sa, sb := sa.label == remoteLabel, sb.label == remoteLabel; sa != sb { 1880 if sa { 1881 return true 1882 } 1883 if sb { 1884 return false 1885 } 1886 } 1887 1888 // Prefer temporary addresses as per RFC 6724 section 5 rule 7. 1889 if saTemp, sbTemp := sa.addressEndpoint.ConfigType() == stack.AddressConfigSlaacTemp, sb.addressEndpoint.ConfigType() == stack.AddressConfigSlaacTemp; saTemp != sbTemp { 1890 return saTemp 1891 } 1892 1893 // Use longest matching prefix as per RFC 6724 section 5 rule 8. 1894 if sa.matchingPrefix > sb.matchingPrefix { 1895 return true 1896 } 1897 if sb.matchingPrefix > sa.matchingPrefix { 1898 return false 1899 } 1900 1901 // sa and sb are equal, return the endpoint that is closest to the front of 1902 // the primary endpoint list. 1903 return i < j 1904 }) 1905 1906 // Return the most preferred address that can have its reference count 1907 // incremented. 1908 for _, c := range cs { 1909 if c.addressEndpoint.IncRef() { 1910 return c.addressEndpoint 1911 } 1912 } 1913 1914 return nil 1915 } 1916 1917 // PrimaryAddresses implements stack.AddressableEndpoint. 1918 func (e *endpoint) PrimaryAddresses() []tcpip.AddressWithPrefix { 1919 e.mu.RLock() 1920 defer e.mu.RUnlock() 1921 return e.mu.addressableEndpointState.PrimaryAddresses() 1922 } 1923 1924 // PermanentAddresses implements stack.AddressableEndpoint. 1925 func (e *endpoint) PermanentAddresses() []tcpip.AddressWithPrefix { 1926 e.mu.RLock() 1927 defer e.mu.RUnlock() 1928 return e.mu.addressableEndpointState.PermanentAddresses() 1929 } 1930 1931 // JoinGroup implements stack.GroupAddressableEndpoint. 1932 func (e *endpoint) JoinGroup(addr tcpip.Address) tcpip.Error { 1933 e.mu.Lock() 1934 defer e.mu.Unlock() 1935 return e.joinGroupLocked(addr) 1936 } 1937 1938 // joinGroupLocked is like JoinGroup but with locking requirements. 1939 // 1940 // Precondition: e.mu must be locked. 1941 func (e *endpoint) joinGroupLocked(addr tcpip.Address) tcpip.Error { 1942 if !header.IsV6MulticastAddress(addr) { 1943 return &tcpip.ErrBadAddress{} 1944 } 1945 1946 e.mu.mld.joinGroup(addr) 1947 return nil 1948 } 1949 1950 // LeaveGroup implements stack.GroupAddressableEndpoint. 1951 func (e *endpoint) LeaveGroup(addr tcpip.Address) tcpip.Error { 1952 e.mu.Lock() 1953 defer e.mu.Unlock() 1954 return e.leaveGroupLocked(addr) 1955 } 1956 1957 // leaveGroupLocked is like LeaveGroup but with locking requirements. 1958 // 1959 // Precondition: e.mu must be locked. 1960 func (e *endpoint) leaveGroupLocked(addr tcpip.Address) tcpip.Error { 1961 return e.mu.mld.leaveGroup(addr) 1962 } 1963 1964 // IsInGroup implements stack.GroupAddressableEndpoint. 1965 func (e *endpoint) IsInGroup(addr tcpip.Address) bool { 1966 e.mu.RLock() 1967 defer e.mu.RUnlock() 1968 return e.mu.mld.isInGroup(addr) 1969 } 1970 1971 // Stats implements stack.NetworkEndpoint. 1972 func (e *endpoint) Stats() stack.NetworkEndpointStats { 1973 return &e.stats.localStats 1974 } 1975 1976 var _ stack.NetworkProtocol = (*protocol)(nil) 1977 var _ fragmentation.TimeoutHandler = (*protocol)(nil) 1978 1979 type protocol struct { 1980 stack *stack.Stack 1981 options Options 1982 1983 mu struct { 1984 sync.RWMutex 1985 1986 // eps is keyed by NICID to allow protocol methods to retrieve an endpoint 1987 // when handling a packet, by looking at which NIC handled the packet. 1988 eps map[tcpip.NICID]*endpoint 1989 } 1990 1991 ids []uint32 1992 hashIV uint32 1993 1994 // defaultTTL is the current default TTL for the protocol. Only the 1995 // uint8 portion of it is meaningful. 1996 // 1997 // Must be accessed using atomic operations. 1998 defaultTTL uint32 1999 2000 fragmentation *fragmentation.Fragmentation 2001 } 2002 2003 // Number returns the ipv6 protocol number. 2004 func (p *protocol) Number() tcpip.NetworkProtocolNumber { 2005 return ProtocolNumber 2006 } 2007 2008 // MinimumPacketSize returns the minimum valid ipv6 packet size. 2009 func (p *protocol) MinimumPacketSize() int { 2010 return header.IPv6MinimumSize 2011 } 2012 2013 // DefaultPrefixLen returns the IPv6 default prefix length. 2014 func (p *protocol) DefaultPrefixLen() int { 2015 return header.IPv6AddressSize * 8 2016 } 2017 2018 // ParseAddresses implements stack.NetworkProtocol. 2019 func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { 2020 h := header.IPv6(v) 2021 return h.SourceAddress(), h.DestinationAddress() 2022 } 2023 2024 // NewEndpoint creates a new ipv6 endpoint. 2025 func (p *protocol) NewEndpoint(nic stack.NetworkInterface, dispatcher stack.TransportDispatcher) stack.NetworkEndpoint { 2026 e := &endpoint{ 2027 nic: nic, 2028 dispatcher: dispatcher, 2029 protocol: p, 2030 } 2031 2032 // NDP options must be 8 octet aligned and the first 2 bytes are used for 2033 // the type and length fields leaving 6 octets as the minimum size for a 2034 // nonce option without padding. 2035 const nonceSize = 6 2036 2037 // As per RFC 7527 section 4.1, 2038 // 2039 // If any probe is looped back within RetransTimer milliseconds after 2040 // having sent DupAddrDetectTransmits NS(DAD) messages, the interface 2041 // continues with another MAX_MULTICAST_SOLICIT number of NS(DAD) 2042 // messages transmitted RetransTimer milliseconds apart. 2043 // 2044 // Value taken from RFC 4861 section 10. 2045 const maxMulticastSolicit = 3 2046 dadOptions := ip.DADOptions{ 2047 Clock: p.stack.Clock(), 2048 SecureRNG: p.stack.SecureRNG(), 2049 NonceSize: nonceSize, 2050 ExtendDADTransmits: maxMulticastSolicit, 2051 Protocol: &e.mu.ndp, 2052 NICID: nic.ID(), 2053 } 2054 2055 e.mu.Lock() 2056 e.mu.addressableEndpointState.Init(e) 2057 e.mu.ndp.init(e, dadOptions) 2058 e.mu.mld.init(e) 2059 e.dad.mu.Lock() 2060 e.dad.mu.dad.Init(&e.dad.mu, p.options.DADConfigs, dadOptions) 2061 e.dad.mu.Unlock() 2062 e.mu.Unlock() 2063 2064 stackStats := p.stack.Stats() 2065 tcpip.InitStatCounters(reflect.ValueOf(&e.stats.localStats).Elem()) 2066 e.stats.ip.Init(&e.stats.localStats.IP, &stackStats.IP) 2067 e.stats.icmp.init(&e.stats.localStats.ICMP, &stackStats.ICMP.V6) 2068 2069 p.mu.Lock() 2070 defer p.mu.Unlock() 2071 p.mu.eps[nic.ID()] = e 2072 return e 2073 } 2074 2075 func (p *protocol) findEndpointWithAddress(addr tcpip.Address) *endpoint { 2076 p.mu.RLock() 2077 defer p.mu.RUnlock() 2078 2079 for _, e := range p.mu.eps { 2080 if addressEndpoint := e.AcquireAssignedAddress(addr, false /* allowTemp */, stack.NeverPrimaryEndpoint); addressEndpoint != nil { 2081 addressEndpoint.DecRef() 2082 return e 2083 } 2084 } 2085 2086 return nil 2087 } 2088 2089 func (p *protocol) forgetEndpoint(nicID tcpip.NICID) { 2090 p.mu.Lock() 2091 defer p.mu.Unlock() 2092 delete(p.mu.eps, nicID) 2093 } 2094 2095 // SetOption implements stack.NetworkProtocol. 2096 func (p *protocol) SetOption(option tcpip.SettableNetworkProtocolOption) tcpip.Error { 2097 switch v := option.(type) { 2098 case *tcpip.DefaultTTLOption: 2099 p.SetDefaultTTL(uint8(*v)) 2100 return nil 2101 default: 2102 return &tcpip.ErrUnknownProtocolOption{} 2103 } 2104 } 2105 2106 // Option implements stack.NetworkProtocol. 2107 func (p *protocol) Option(option tcpip.GettableNetworkProtocolOption) tcpip.Error { 2108 switch v := option.(type) { 2109 case *tcpip.DefaultTTLOption: 2110 *v = tcpip.DefaultTTLOption(p.DefaultTTL()) 2111 return nil 2112 default: 2113 return &tcpip.ErrUnknownProtocolOption{} 2114 } 2115 } 2116 2117 // SetDefaultTTL sets the default TTL for endpoints created with this protocol. 2118 func (p *protocol) SetDefaultTTL(ttl uint8) { 2119 atomic.StoreUint32(&p.defaultTTL, uint32(ttl)) 2120 } 2121 2122 // DefaultTTL returns the default TTL for endpoints created with this protocol. 2123 func (p *protocol) DefaultTTL() uint8 { 2124 return uint8(atomic.LoadUint32(&p.defaultTTL)) 2125 } 2126 2127 // Close implements stack.TransportProtocol. 2128 func (*protocol) Close() {} 2129 2130 // Wait implements stack.TransportProtocol. 2131 func (*protocol) Wait() {} 2132 2133 // parseAndValidate parses the packet (including its transport layer header) and 2134 // returns the parsed IP header. 2135 // 2136 // Returns true if the IP header was successfully parsed. 2137 func (p *protocol) parseAndValidate(pkt *stack.PacketBuffer) (header.IPv6, bool) { 2138 transProtoNum, hasTransportHdr, ok := p.Parse(pkt) 2139 if !ok { 2140 return nil, false 2141 } 2142 2143 h := header.IPv6(pkt.NetworkHeader().View()) 2144 // Do not include the link header's size when calculating the size of the IP 2145 // packet. 2146 if !h.IsValid(pkt.Size() - pkt.LinkHeader().View().Size()) { 2147 return nil, false 2148 } 2149 2150 if hasTransportHdr { 2151 switch err := p.stack.ParsePacketBufferTransport(transProtoNum, pkt); err { 2152 case stack.ParsedOK: 2153 case stack.UnknownTransportProtocol, stack.TransportLayerParseError: 2154 // The transport layer will handle unknown protocols and transport layer 2155 // parsing errors. 2156 default: 2157 panic(fmt.Sprintf("unexpected error parsing transport header = %d", err)) 2158 } 2159 } 2160 2161 return h, true 2162 } 2163 2164 // Parse implements stack.NetworkProtocol. 2165 func (*protocol) Parse(pkt *stack.PacketBuffer) (proto tcpip.TransportProtocolNumber, hasTransportHdr bool, ok bool) { 2166 proto, _, fragOffset, fragMore, ok := parse.IPv6(pkt) 2167 if !ok { 2168 return 0, false, false 2169 } 2170 2171 return proto, !fragMore && fragOffset == 0, true 2172 } 2173 2174 // calculateNetworkMTU calculates the network-layer payload MTU based on the 2175 // link-layer payload MTU and the length of every IPv6 header. 2176 // Note that this is different than the Payload Length field of the IPv6 header, 2177 // which includes the length of the extension headers. 2178 func calculateNetworkMTU(linkMTU, networkHeadersLen uint32) (uint32, tcpip.Error) { 2179 if linkMTU < header.IPv6MinimumMTU { 2180 return 0, &tcpip.ErrInvalidEndpointState{} 2181 } 2182 2183 // As per RFC 7112 section 5, we should discard packets if their IPv6 header 2184 // is bigger than 1280 bytes (ie, the minimum link MTU) since we do not 2185 // support PMTU discovery: 2186 // Hosts that do not discover the Path MTU MUST limit the IPv6 Header Chain 2187 // length to 1280 bytes. Limiting the IPv6 Header Chain length to 1280 2188 // bytes ensures that the header chain length does not exceed the IPv6 2189 // minimum MTU. 2190 if networkHeadersLen > header.IPv6MinimumMTU { 2191 return 0, &tcpip.ErrMalformedHeader{} 2192 } 2193 2194 networkMTU := linkMTU - networkHeadersLen 2195 if networkMTU > maxPayloadSize { 2196 networkMTU = maxPayloadSize 2197 } 2198 return networkMTU, nil 2199 } 2200 2201 // Options holds options to configure a new protocol. 2202 type Options struct { 2203 // NDPConfigs is the default NDP configurations used by interfaces. 2204 NDPConfigs NDPConfigurations 2205 2206 // AutoGenLinkLocal determines whether or not the stack attempts to 2207 // auto-generate a link-local address for newly enabled non-loopback 2208 // NICs. 2209 // 2210 // Note, setting this to true does not mean that a link-local address is 2211 // assigned right away, or at all. If Duplicate Address Detection is enabled, 2212 // an address is only assigned if it successfully resolves. If it fails, no 2213 // further attempts are made to auto-generate a link-local address. 2214 // 2215 // The generated link-local address follows RFC 4291 Appendix A guidelines. 2216 AutoGenLinkLocal bool 2217 2218 // NDPDisp is the NDP event dispatcher that an integrator can provide to 2219 // receive NDP related events. 2220 NDPDisp NDPDispatcher 2221 2222 // OpaqueIIDOpts hold the options for generating opaque interface 2223 // identifiers (IIDs) as outlined by RFC 7217. 2224 OpaqueIIDOpts OpaqueInterfaceIdentifierOptions 2225 2226 // TempIIDSeed is used to seed the initial temporary interface identifier 2227 // history value used to generate IIDs for temporary SLAAC addresses. 2228 // 2229 // Temporary SLAAC addresses are short-lived addresses which are unpredictable 2230 // and random from the perspective of other nodes on the network. It is 2231 // recommended that the seed be a random byte buffer of at least 2232 // header.IIDSize bytes to make sure that temporary SLAAC addresses are 2233 // sufficiently random. It should follow minimum randomness requirements for 2234 // security as outlined by RFC 4086. 2235 // 2236 // Note: using a nil value, the same seed across netstack program runs, or a 2237 // seed that is too small would reduce randomness and increase predictability, 2238 // defeating the purpose of temporary SLAAC addresses. 2239 TempIIDSeed []byte 2240 2241 // MLD holds options for MLD. 2242 MLD MLDOptions 2243 2244 // DADConfigs holds the default DAD configurations used by IPv6 endpoints. 2245 DADConfigs stack.DADConfigurations 2246 2247 // AllowExternalLoopbackTraffic indicates that inbound loopback packets (i.e. 2248 // martian loopback packets) should be accepted. 2249 AllowExternalLoopbackTraffic bool 2250 } 2251 2252 // NewProtocolWithOptions returns an IPv6 network protocol. 2253 func NewProtocolWithOptions(opts Options) stack.NetworkProtocolFactory { 2254 opts.NDPConfigs.validate() 2255 2256 ids := hash.RandN32(buckets) 2257 hashIV := hash.RandN32(1)[0] 2258 2259 return func(s *stack.Stack) stack.NetworkProtocol { 2260 p := &protocol{ 2261 stack: s, 2262 options: opts, 2263 2264 ids: ids, 2265 hashIV: hashIV, 2266 } 2267 p.fragmentation = fragmentation.NewFragmentation(header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, ReassembleTimeout, s.Clock(), p) 2268 p.mu.eps = make(map[tcpip.NICID]*endpoint) 2269 p.SetDefaultTTL(DefaultTTL) 2270 return p 2271 } 2272 } 2273 2274 // NewProtocol is equivalent to NewProtocolWithOptions with an empty Options. 2275 func NewProtocol(s *stack.Stack) stack.NetworkProtocol { 2276 return NewProtocolWithOptions(Options{})(s) 2277 } 2278 2279 func calculateFragmentReserve(pkt *stack.PacketBuffer) int { 2280 return pkt.AvailableHeaderBytes() + pkt.NetworkHeader().View().Size() + header.IPv6FragmentHeaderSize 2281 } 2282 2283 // hashRoute calculates a hash value for the given route. It uses the source & 2284 // destination address and 32-bit number to generate the hash. 2285 func hashRoute(r *stack.Route, hashIV uint32) uint32 { 2286 // The FNV-1a was chosen because it is a fast hashing algorithm, and 2287 // cryptographic properties are not needed here. 2288 h := fnv.New32a() 2289 if _, err := h.Write([]byte(r.LocalAddress())); err != nil { 2290 panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected to ever return an error", err)) 2291 } 2292 2293 if _, err := h.Write([]byte(r.RemoteAddress())); err != nil { 2294 panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected to ever return an error", err)) 2295 } 2296 2297 s := make([]byte, 4) 2298 binary.LittleEndian.PutUint32(s, hashIV) 2299 if _, err := h.Write(s); err != nil { 2300 panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected ever to return an error", err)) 2301 } 2302 2303 return h.Sum32() 2304 } 2305 2306 func buildNextFragment(pf *fragmentation.PacketFragmenter, originalIPHeaders header.IPv6, transportProto tcpip.TransportProtocolNumber, id uint32) (*stack.PacketBuffer, bool) { 2307 fragPkt, offset, copied, more := pf.BuildNextFragment() 2308 fragPkt.NetworkProtocolNumber = ProtocolNumber 2309 2310 originalIPHeadersLength := len(originalIPHeaders) 2311 2312 s := header.IPv6ExtHdrSerializer{&header.IPv6SerializableFragmentExtHdr{ 2313 FragmentOffset: uint16(offset / header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit), 2314 M: more, 2315 Identification: id, 2316 }} 2317 2318 fragmentIPHeadersLength := originalIPHeadersLength + s.Length() 2319 fragmentIPHeaders := header.IPv6(fragPkt.NetworkHeader().Push(fragmentIPHeadersLength)) 2320 2321 // Copy the IPv6 header and any extension headers already populated. 2322 if copied := copy(fragmentIPHeaders, originalIPHeaders); copied != originalIPHeadersLength { 2323 panic(fmt.Sprintf("wrong number of bytes copied into fragmentIPHeaders: got %d, want %d", copied, originalIPHeadersLength)) 2324 } 2325 2326 nextHeader, _ := s.Serialize(transportProto, fragmentIPHeaders[originalIPHeadersLength:]) 2327 2328 fragmentIPHeaders.SetNextHeader(nextHeader) 2329 fragmentIPHeaders.SetPayloadLength(uint16(copied + fragmentIPHeadersLength - header.IPv6MinimumSize)) 2330 2331 return fragPkt, more 2332 }