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