github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/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/sagernet/gvisor/pkg/atomicbitops" 26 "github.com/sagernet/gvisor/pkg/buffer" 27 "github.com/sagernet/gvisor/pkg/sync" 28 "github.com/sagernet/gvisor/pkg/tcpip" 29 "github.com/sagernet/gvisor/pkg/tcpip/header" 30 "github.com/sagernet/gvisor/pkg/tcpip/header/parse" 31 "github.com/sagernet/gvisor/pkg/tcpip/network/internal/fragmentation" 32 "github.com/sagernet/gvisor/pkg/tcpip/network/internal/ip" 33 "github.com/sagernet/gvisor/pkg/tcpip/network/internal/multicast" 34 "github.com/sagernet/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, true /* readOnly */) 1109 if addressEndpoint != nil { 1110 // The source address is one of our own, so we never should have gotten 1111 // a packet like this unless HandleLocal is false or our NIC is the 1112 // loopback interface. 1113 stats.InvalidSourceAddressesReceived.Increment() 1114 return 1115 } 1116 } 1117 1118 // Loopback traffic skips the prerouting chain. 1119 inNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID()) 1120 if ok := e.protocol.stack.IPTables().CheckPrerouting(pkt, e, inNicName); !ok { 1121 // iptables is telling us to drop the packet. 1122 stats.IPTablesPreroutingDropped.Increment() 1123 return 1124 } 1125 } 1126 1127 e.handleValidatedPacket(h, pkt, e.nic.Name() /* inNICName */) 1128 } 1129 1130 // handleLocalPacket is like HandlePacket except it does not perform the 1131 // prerouting iptables hook or check for loopback traffic that originated from 1132 // outside of the netstack (i.e. martian loopback packets). 1133 func (e *endpoint) handleLocalPacket(pkt *stack.PacketBuffer, canSkipRXChecksum bool) { 1134 stats := e.stats.ip 1135 stats.PacketsReceived.Increment() 1136 1137 pkt = pkt.CloneToInbound() 1138 defer pkt.DecRef() 1139 pkt.RXChecksumValidated = canSkipRXChecksum 1140 1141 hView, ok := e.protocol.parseAndValidate(pkt) 1142 if !ok { 1143 stats.MalformedPacketsReceived.Increment() 1144 return 1145 } 1146 defer hView.Release() 1147 h := header.IPv6(hView.AsSlice()) 1148 1149 if !checkV4Mapped(h, stats) { 1150 return 1151 } 1152 1153 e.handleValidatedPacket(h, pkt, e.nic.Name() /* inNICName */) 1154 } 1155 1156 // forwardMulticastPacket validates a multicast pkt and attempts to forward it. 1157 // 1158 // This method should be invoked for incoming multicast packets using the 1159 // endpoint that received the packet. 1160 func (e *endpoint) forwardMulticastPacket(h header.IPv6, pkt *stack.PacketBuffer) ip.ForwardingError { 1161 if err := validateAddressesForForwarding(h); err != nil { 1162 return err 1163 } 1164 1165 // Check extension headers for any errors. 1166 if err := e.processExtensionHeaders(h, pkt, true /* forwarding */); err != nil { 1167 return &ip.ErrParameterProblem{} 1168 } 1169 1170 routeKey := stack.UnicastSourceAndMulticastDestination{ 1171 Source: h.SourceAddress(), 1172 Destination: h.DestinationAddress(), 1173 } 1174 1175 // The pkt has been validated. Consequently, if a route is not found, then 1176 // the pkt can safely be queued. 1177 result, hasBufferSpace := e.protocol.multicastRouteTable.GetRouteOrInsertPending(routeKey, pkt) 1178 1179 if !hasBufferSpace { 1180 // Unable to queue the pkt. Silently drop it. 1181 return &ip.ErrNoMulticastPendingQueueBufferSpace{} 1182 } 1183 1184 switch result.GetRouteResultState { 1185 case multicast.InstalledRouteFound: 1186 // Attempt to forward the pkt using an existing route. 1187 return e.forwardValidatedMulticastPacket(pkt, result.InstalledRoute) 1188 case multicast.NoRouteFoundAndPendingInserted: 1189 e.emitMulticastEvent(func(disp stack.MulticastForwardingEventDispatcher) { 1190 disp.OnMissingRoute(stack.MulticastPacketContext{ 1191 stack.UnicastSourceAndMulticastDestination{h.SourceAddress(), h.DestinationAddress()}, 1192 e.nic.ID(), 1193 }) 1194 }) 1195 case multicast.PacketQueuedInPendingRoute: 1196 default: 1197 panic(fmt.Sprintf("unexpected GetRouteResultState: %s", result.GetRouteResultState)) 1198 } 1199 return &ip.ErrHostUnreachable{} 1200 } 1201 1202 // forwardValidatedMulticastPacket attempts to forward the pkt using the 1203 // provided installedRoute. 1204 // 1205 // This method should be invoked by the endpoint that received the pkt. 1206 func (e *endpoint) forwardValidatedMulticastPacket(pkt *stack.PacketBuffer, installedRoute *multicast.InstalledRoute) ip.ForwardingError { 1207 // Per RFC 1812 section 5.2.1.3, 1208 // 1209 // Based on the IP source and destination addresses found in the datagram 1210 // header, the router determines whether the datagram has been received 1211 // on the proper interface for forwarding. If not, the datagram is 1212 // dropped silently. 1213 if e.nic.ID() != installedRoute.ExpectedInputInterface { 1214 h := header.IPv6(pkt.NetworkHeader().Slice()) 1215 e.emitMulticastEvent(func(disp stack.MulticastForwardingEventDispatcher) { 1216 disp.OnUnexpectedInputInterface(stack.MulticastPacketContext{ 1217 stack.UnicastSourceAndMulticastDestination{h.SourceAddress(), h.DestinationAddress()}, 1218 e.nic.ID(), 1219 }, installedRoute.ExpectedInputInterface) 1220 }) 1221 return &ip.ErrUnexpectedMulticastInputInterface{} 1222 } 1223 1224 for _, outgoingInterface := range installedRoute.OutgoingInterfaces { 1225 if err := e.forwardMulticastPacketForOutgoingInterface(pkt, outgoingInterface); err != nil { 1226 e.handleForwardingError(err) 1227 continue 1228 } 1229 // The pkt was successfully forwarded. Mark the route as used. 1230 installedRoute.SetLastUsedTimestamp(e.protocol.stack.Clock().NowMonotonic()) 1231 } 1232 return nil 1233 } 1234 1235 // forwardMulticastPacketForOutgoingInterface attempts to forward the pkt out 1236 // of the provided outgoing interface. 1237 // 1238 // This method should be invoked by the endpoint that received the pkt. 1239 func (e *endpoint) forwardMulticastPacketForOutgoingInterface(pkt *stack.PacketBuffer, outgoingInterface stack.MulticastRouteOutgoingInterface) ip.ForwardingError { 1240 h := header.IPv6(pkt.NetworkHeader().Slice()) 1241 1242 // Per RFC 1812 section 5.2.1.3, 1243 // 1244 // A copy of the multicast datagram is forwarded out each outgoing 1245 // interface whose minimum TTL value is less than or equal to the TTL 1246 // value in the datagram header. 1247 // 1248 // Copying of the packet is deferred to forwardPacketWithRoute since unicast 1249 // and multicast both require a copy. 1250 if outgoingInterface.MinTTL > h.HopLimit() { 1251 return &ip.ErrTTLExceeded{} 1252 } 1253 1254 route := e.protocol.stack.NewRouteForMulticast(outgoingInterface.ID, h.DestinationAddress(), e.NetworkProtocolNumber()) 1255 1256 if route == nil { 1257 // Failed to convert to a stack.Route. This likely means that the outgoing 1258 // endpoint no longer exists. 1259 return &ip.ErrHostUnreachable{} 1260 } 1261 defer route.Release() 1262 return e.forwardPacketWithRoute(route, pkt) 1263 } 1264 1265 // handleForwardingError processes the provided err and increments any relevant 1266 // counters. 1267 func (e *endpoint) handleForwardingError(err ip.ForwardingError) { 1268 stats := e.stats.ip 1269 switch err := err.(type) { 1270 case nil: 1271 return 1272 case *ip.ErrInitializingSourceAddress: 1273 stats.Forwarding.InitializingSource.Increment() 1274 case *ip.ErrLinkLocalSourceAddress: 1275 stats.Forwarding.LinkLocalSource.Increment() 1276 case *ip.ErrLinkLocalDestinationAddress: 1277 stats.Forwarding.LinkLocalDestination.Increment() 1278 case *ip.ErrTTLExceeded: 1279 stats.Forwarding.ExhaustedTTL.Increment() 1280 case *ip.ErrHostUnreachable: 1281 stats.Forwarding.Unrouteable.Increment() 1282 case *ip.ErrParameterProblem: 1283 stats.Forwarding.ExtensionHeaderProblem.Increment() 1284 case *ip.ErrMessageTooLong: 1285 stats.Forwarding.PacketTooBig.Increment() 1286 case *ip.ErrNoMulticastPendingQueueBufferSpace: 1287 stats.Forwarding.NoMulticastPendingQueueBufferSpace.Increment() 1288 case *ip.ErrUnexpectedMulticastInputInterface: 1289 stats.Forwarding.UnexpectedMulticastInputInterface.Increment() 1290 case *ip.ErrUnknownOutputEndpoint: 1291 stats.Forwarding.UnknownOutputEndpoint.Increment() 1292 case *ip.ErrOutgoingDeviceNoBufferSpace: 1293 stats.Forwarding.OutgoingDeviceNoBufferSpace.Increment() 1294 default: 1295 panic(fmt.Sprintf("unrecognized forwarding error: %s", err)) 1296 } 1297 stats.Forwarding.Errors.Increment() 1298 } 1299 1300 func (e *endpoint) handleValidatedPacket(h header.IPv6, pkt *stack.PacketBuffer, inNICName string) { 1301 pkt.NICID = e.nic.ID() 1302 1303 // Raw socket packets are delivered based solely on the transport protocol 1304 // number. We only require that the packet be valid IPv6. 1305 e.dispatcher.DeliverRawPacket(h.TransportProtocol(), pkt) 1306 1307 stats := e.stats.ip 1308 stats.ValidPacketsReceived.Increment() 1309 1310 srcAddr := h.SourceAddress() 1311 dstAddr := h.DestinationAddress() 1312 1313 // As per RFC 4291 section 2.7: 1314 // Multicast addresses must not be used as source addresses in IPv6 1315 // packets or appear in any Routing header. 1316 if header.IsV6MulticastAddress(srcAddr) { 1317 stats.InvalidSourceAddressesReceived.Increment() 1318 return 1319 } 1320 1321 if header.IsV6MulticastAddress(dstAddr) { 1322 // Handle all packets destined to a multicast address separately. Unlike 1323 // unicast, these packets can be both delivered locally and forwarded. See 1324 // RFC 1812 section 5.2.3 for details regarding the forwarding/local 1325 // delivery decision. 1326 1327 multicastForwading := e.MulticastForwarding() && e.protocol.multicastForwarding() 1328 1329 if multicastForwading { 1330 e.handleForwardingError(e.forwardMulticastPacket(h, pkt)) 1331 } 1332 1333 if e.IsInGroup(dstAddr) { 1334 e.deliverPacketLocally(h, pkt, inNICName) 1335 return 1336 } 1337 1338 if !multicastForwading { 1339 // Only consider the destination address invalid if we didn't attempt to 1340 // forward the pkt and it was not delivered locally. 1341 stats.InvalidDestinationAddressesReceived.Increment() 1342 } 1343 1344 return 1345 } 1346 1347 // The destination address should be an address we own for us to receive the 1348 // packet. Otherwise, attempt to forward the packet. 1349 if addressEndpoint := e.AcquireAssignedAddress(dstAddr, e.nic.Promiscuous(), stack.CanBePrimaryEndpoint, true /* readOnly */); addressEndpoint != nil { 1350 e.deliverPacketLocally(h, pkt, inNICName) 1351 } else if e.Forwarding() { 1352 e.handleForwardingError(e.forwardUnicastPacket(pkt)) 1353 } else { 1354 stats.InvalidDestinationAddressesReceived.Increment() 1355 } 1356 } 1357 1358 func (e *endpoint) deliverPacketLocally(h header.IPv6, pkt *stack.PacketBuffer, inNICName string) { 1359 stats := e.stats.ip 1360 1361 // iptables filtering. All packets that reach here are intended for 1362 // this machine and need not be forwarded. 1363 if ok := e.protocol.stack.IPTables().CheckInput(pkt, inNICName); !ok { 1364 // iptables is telling us to drop the packet. 1365 stats.IPTablesInputDropped.Increment() 1366 return 1367 } 1368 1369 // Any returned error is only useful for terminating execution early, but 1370 // we have nothing left to do, so we can drop it. 1371 _ = e.processExtensionHeaders(h, pkt, false /* forwarding */) 1372 } 1373 1374 func (e *endpoint) processExtensionHeader(it *header.IPv6PayloadIterator, pkt **stack.PacketBuffer, h header.IPv6, routerAlert **header.IPv6RouterAlertOption, hasFragmentHeader *bool, forwarding bool) (bool, error) { 1375 stats := e.stats.ip 1376 dstAddr := h.DestinationAddress() 1377 // Keep track of the start of the previous header so we can report the 1378 // special case of a Hop by Hop at a location other than at the start. 1379 previousHeaderStart := it.HeaderOffset() 1380 extHdr, done, err := it.Next() 1381 if err != nil { 1382 stats.MalformedPacketsReceived.Increment() 1383 return true, err 1384 } 1385 if done { 1386 return true, nil 1387 } 1388 defer extHdr.Release() 1389 1390 // As per RFC 8200, section 4: 1391 // 1392 // Extension headers (except for the Hop-by-Hop Options header) are 1393 // not processed, inserted, or deleted by any node along a packet's 1394 // delivery path until the packet reaches the node identified in the 1395 // Destination Address field of the IPv6 header. 1396 // 1397 // Furthermore, as per RFC 8200 section 4.1, the Hop By Hop extension 1398 // header is restricted to appear first in the list of extension headers. 1399 // 1400 // Therefore, we can immediately return once we hit any header other 1401 // than the Hop-by-Hop header while forwarding a packet. 1402 if forwarding { 1403 if _, ok := extHdr.(header.IPv6HopByHopOptionsExtHdr); !ok { 1404 return true, nil 1405 } 1406 } 1407 1408 switch extHdr := extHdr.(type) { 1409 case header.IPv6HopByHopOptionsExtHdr: 1410 if err := e.processIPv6HopByHopOptionsExtHdr(&extHdr, it, *pkt, dstAddr, routerAlert, previousHeaderStart, forwarding); err != nil { 1411 return true, err 1412 } 1413 case header.IPv6RoutingExtHdr: 1414 if err := e.processIPv6RoutingExtHeader(&extHdr, it, *pkt); err != nil { 1415 return true, err 1416 } 1417 case header.IPv6FragmentExtHdr: 1418 *hasFragmentHeader = true 1419 if extHdr.IsAtomic() { 1420 // This fragment extension header indicates that this packet is an 1421 // atomic fragment. An atomic fragment is a fragment that contains 1422 // all the data required to reassemble a full packet. As per RFC 6946, 1423 // atomic fragments must not interfere with "normal" fragmented traffic 1424 // so we skip processing the fragment instead of feeding it through the 1425 // reassembly process below. 1426 return false, nil 1427 } 1428 1429 if err := e.processFragmentExtHdr(&extHdr, it, pkt, h); err != nil { 1430 return true, err 1431 } 1432 case header.IPv6DestinationOptionsExtHdr: 1433 if err := e.processIPv6DestinationOptionsExtHdr(&extHdr, it, *pkt, dstAddr); err != nil { 1434 return true, err 1435 } 1436 case header.IPv6RawPayloadHeader: 1437 if err := e.processIPv6RawPayloadHeader(&extHdr, it, *pkt, *routerAlert, previousHeaderStart, *hasFragmentHeader); err != nil { 1438 return true, err 1439 } 1440 default: 1441 // Since the iterator returns IPv6RawPayloadHeader for unknown Extension 1442 // Header IDs this should never happen unless we missed a supported type 1443 // here. 1444 panic(fmt.Sprintf("unrecognized type from it.Next() = %T", extHdr)) 1445 } 1446 return false, nil 1447 } 1448 1449 // processExtensionHeaders processes the extension headers in the given packet. 1450 // Returns an error if the processing of a header failed or if the packet should 1451 // be discarded. 1452 func (e *endpoint) processExtensionHeaders(h header.IPv6, pkt *stack.PacketBuffer, forwarding bool) error { 1453 // Create a VV to parse the packet. We don't plan to modify anything here. 1454 // vv consists of: 1455 // - Any IPv6 header bytes after the first 40 (i.e. extensions). 1456 // - The transport header, if present. 1457 // - Any other payload data. 1458 v := pkt.NetworkHeader().View() 1459 if v != nil { 1460 v.TrimFront(header.IPv6MinimumSize) 1461 } 1462 buf := buffer.MakeWithView(v) 1463 buf.Append(pkt.TransportHeader().View()) 1464 dataBuf := pkt.Data().ToBuffer() 1465 buf.Merge(&dataBuf) 1466 it := header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(h.NextHeader()), buf) 1467 1468 // Add a reference to pkt because fragment header processing can replace this 1469 // packet with a new one that has an extra reference. Adding a reference here 1470 // keeps the two in parity so they can both be DecRef'd the same way. 1471 pkt.IncRef() 1472 defer func() { 1473 pkt.DecRef() 1474 it.Release() 1475 }() 1476 1477 var ( 1478 hasFragmentHeader bool 1479 routerAlert *header.IPv6RouterAlertOption 1480 ) 1481 for { 1482 if done, err := e.processExtensionHeader(&it, &pkt, h, &routerAlert, &hasFragmentHeader, forwarding); err != nil || done { 1483 return err 1484 } 1485 } 1486 } 1487 1488 func (e *endpoint) processIPv6RawPayloadHeader(extHdr *header.IPv6RawPayloadHeader, it *header.IPv6PayloadIterator, pkt *stack.PacketBuffer, routerAlert *header.IPv6RouterAlertOption, previousHeaderStart uint32, hasFragmentHeader bool) error { 1489 stats := e.stats.ip 1490 // If the last header in the payload isn't a known IPv6 extension header, 1491 // handle it as if it is transport layer data.Ã¥ 1492 1493 // Calculate the number of octets parsed from data. We want to consume all 1494 // the data except the unparsed portion located at the end, whose size is 1495 // extHdr.Buf.Size(). 1496 trim := pkt.Data().Size() - int(extHdr.Buf.Size()) 1497 1498 // For unfragmented packets, extHdr still contains the transport header. 1499 // Consume that too. 1500 // 1501 // For reassembled fragments, pkt.TransportHeader is unset, so this is a 1502 // no-op and pkt.Data begins with the transport header. 1503 trim += len(pkt.TransportHeader().Slice()) 1504 1505 if _, ok := pkt.Data().Consume(trim); !ok { 1506 stats.MalformedPacketsReceived.Increment() 1507 return fmt.Errorf("could not consume %d bytes", trim) 1508 } 1509 1510 proto := tcpip.TransportProtocolNumber(extHdr.Identifier) 1511 // If the packet was reassembled from a fragment, it will not have a 1512 // transport header set yet. 1513 if len(pkt.TransportHeader().Slice()) == 0 { 1514 e.protocol.parseTransport(pkt, proto) 1515 } 1516 1517 stats.PacketsDelivered.Increment() 1518 if proto == header.ICMPv6ProtocolNumber { 1519 e.handleICMP(pkt, hasFragmentHeader, routerAlert) 1520 return nil 1521 } 1522 switch res := e.dispatcher.DeliverTransportPacket(proto, pkt); res { 1523 case stack.TransportPacketHandled: 1524 return nil 1525 case stack.TransportPacketDestinationPortUnreachable: 1526 // As per RFC 4443 section 3.1: 1527 // A destination node SHOULD originate a Destination Unreachable 1528 // message with Code 4 in response to a packet for which the 1529 // transport protocol (e.g., UDP) has no listener, if that transport 1530 // protocol has no alternative means to inform the sender. 1531 _ = e.protocol.returnError(&icmpReasonPortUnreachable{}, pkt, true /* deliveredLocally */) 1532 return fmt.Errorf("destination port unreachable") 1533 case stack.TransportPacketProtocolUnreachable: 1534 // As per RFC 8200 section 4. (page 7): 1535 // Extension headers are numbered from IANA IP Protocol Numbers 1536 // [IANA-PN], the same values used for IPv4 and IPv6. When 1537 // processing a sequence of Next Header values in a packet, the 1538 // first one that is not an extension header [IANA-EH] indicates 1539 // that the next item in the packet is the corresponding upper-layer 1540 // header. 1541 // With more related information on page 8: 1542 // If, as a result of processing a header, the destination node is 1543 // required to proceed to the next header but the Next Header value 1544 // in the current header is unrecognized by the node, it should 1545 // discard the packet and send an ICMP Parameter Problem message to 1546 // the source of the packet, with an ICMP Code value of 1 1547 // ("unrecognized Next Header type encountered") and the ICMP 1548 // Pointer field containing the offset of the unrecognized value 1549 // within the original packet. 1550 // 1551 // Which when taken together indicate that an unknown protocol should 1552 // be treated as an unrecognized next header value. 1553 // The location of the Next Header field is in a different place in 1554 // the initial IPv6 header than it is in the extension headers so 1555 // treat it specially. 1556 prevHdrIDOffset := uint32(header.IPv6NextHeaderOffset) 1557 if previousHeaderStart != 0 { 1558 prevHdrIDOffset = previousHeaderStart 1559 } 1560 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1561 code: header.ICMPv6UnknownHeader, 1562 pointer: prevHdrIDOffset, 1563 }, pkt, true /* deliveredLocally */) 1564 return fmt.Errorf("transport protocol unreachable") 1565 default: 1566 panic(fmt.Sprintf("unrecognized result from DeliverTransportPacket = %d", res)) 1567 } 1568 } 1569 1570 func (e *endpoint) processIPv6RoutingExtHeader(extHdr *header.IPv6RoutingExtHdr, it *header.IPv6PayloadIterator, pkt *stack.PacketBuffer) error { 1571 // As per RFC 8200 section 4.4, if a node encounters a routing header with 1572 // an unrecognized routing type value, with a non-zero Segments Left 1573 // value, the node must discard the packet and send an ICMP Parameter 1574 // Problem, Code 0 to the packet's Source Address, pointing to the 1575 // unrecognized Routing Type. 1576 // 1577 // If the Segments Left is 0, the node must ignore the Routing extension 1578 // header and process the next header in the packet. 1579 // 1580 // Note, the stack does not yet handle any type of routing extension 1581 // header, so we just make sure Segments Left is zero before processing 1582 // the next extension header. 1583 if extHdr.SegmentsLeft() == 0 { 1584 return nil 1585 } 1586 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1587 code: header.ICMPv6ErroneousHeader, 1588 pointer: it.ParseOffset(), 1589 }, pkt, true /* deliveredLocally */) 1590 return fmt.Errorf("found unrecognized routing type with non-zero segments left in header = %#v", extHdr) 1591 } 1592 1593 func (e *endpoint) processIPv6DestinationOptionsExtHdr(extHdr *header.IPv6DestinationOptionsExtHdr, it *header.IPv6PayloadIterator, pkt *stack.PacketBuffer, dstAddr tcpip.Address) error { 1594 stats := e.stats.ip 1595 optsIt := extHdr.Iter() 1596 var uopt *header.IPv6UnknownExtHdrOption 1597 defer func() { 1598 if uopt != nil { 1599 uopt.Data.Release() 1600 } 1601 }() 1602 1603 for { 1604 opt, done, err := optsIt.Next() 1605 if err != nil { 1606 stats.MalformedPacketsReceived.Increment() 1607 return err 1608 } 1609 if uo, ok := opt.(*header.IPv6UnknownExtHdrOption); ok { 1610 uopt = uo 1611 } 1612 if done { 1613 break 1614 } 1615 1616 // We currently do not support any IPv6 Destination extension header 1617 // options. 1618 switch opt.UnknownAction() { 1619 case header.IPv6OptionUnknownActionSkip: 1620 case header.IPv6OptionUnknownActionDiscard: 1621 return fmt.Errorf("found unknown destination header option = %#v with discard action", opt) 1622 case header.IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest: 1623 if header.IsV6MulticastAddress(dstAddr) { 1624 if uo, ok := opt.(*header.IPv6UnknownExtHdrOption); ok { 1625 uopt = uo 1626 } 1627 return fmt.Errorf("found unknown destination header option %#v with discard action", opt) 1628 } 1629 fallthrough 1630 case header.IPv6OptionUnknownActionDiscardSendICMP: 1631 // This case satisfies a requirement of RFC 8200 section 4.2 1632 // which states that an unknown option starting with bits [10] should: 1633 // 1634 // discard the packet and, regardless of whether or not the 1635 // packet's Destination Address was a multicast address, send an 1636 // ICMP Parameter Problem, Code 2, message to the packet's 1637 // Source Address, pointing to the unrecognized Option Type. 1638 // 1639 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1640 code: header.ICMPv6UnknownOption, 1641 pointer: it.ParseOffset() + optsIt.OptionOffset(), 1642 respondToMulticast: true, 1643 }, pkt, true /* deliveredLocally */) 1644 return fmt.Errorf("found unknown destination header option %#v with discard action", opt) 1645 default: 1646 panic(fmt.Sprintf("unrecognized action for an unrecognized Destination extension header option = %#v", opt)) 1647 } 1648 if uopt != nil { 1649 uopt.Data.Release() 1650 uopt = nil 1651 } 1652 } 1653 return nil 1654 } 1655 1656 func (e *endpoint) processIPv6HopByHopOptionsExtHdr(extHdr *header.IPv6HopByHopOptionsExtHdr, it *header.IPv6PayloadIterator, pkt *stack.PacketBuffer, dstAddr tcpip.Address, routerAlert **header.IPv6RouterAlertOption, previousHeaderStart uint32, forwarding bool) error { 1657 stats := e.stats.ip 1658 // As per RFC 8200 section 4.1, the Hop By Hop extension header is 1659 // restricted to appear immediately after an IPv6 fixed header. 1660 if previousHeaderStart != 0 { 1661 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1662 code: header.ICMPv6UnknownHeader, 1663 pointer: previousHeaderStart, 1664 }, pkt, !forwarding /* deliveredLocally */) 1665 return fmt.Errorf("found Hop-by-Hop header = %#v with non-zero previous header offset = %d", extHdr, previousHeaderStart) 1666 } 1667 1668 optsIt := extHdr.Iter() 1669 var uopt *header.IPv6UnknownExtHdrOption 1670 defer func() { 1671 if uopt != nil { 1672 uopt.Data.Release() 1673 } 1674 }() 1675 1676 for { 1677 opt, done, err := optsIt.Next() 1678 if err != nil { 1679 stats.MalformedPacketsReceived.Increment() 1680 return err 1681 } 1682 if uo, ok := opt.(*header.IPv6UnknownExtHdrOption); ok { 1683 uopt = uo 1684 } 1685 if done { 1686 break 1687 } 1688 1689 switch opt := opt.(type) { 1690 case *header.IPv6RouterAlertOption: 1691 if *routerAlert != nil { 1692 // As per RFC 2711 section 3, there should be at most one Router 1693 // Alert option per packet. 1694 // 1695 // There MUST only be one option of this type, regardless of 1696 // value, per Hop-by-Hop header. 1697 stats.MalformedPacketsReceived.Increment() 1698 return fmt.Errorf("found multiple Router Alert options (%#v, %#v)", opt, *routerAlert) 1699 } 1700 *routerAlert = opt 1701 stats.OptionRouterAlertReceived.Increment() 1702 default: 1703 switch opt.UnknownAction() { 1704 case header.IPv6OptionUnknownActionSkip: 1705 case header.IPv6OptionUnknownActionDiscard: 1706 return fmt.Errorf("found unknown Hop-by-Hop header option = %#v with discard action", opt) 1707 case header.IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest: 1708 if header.IsV6MulticastAddress(dstAddr) { 1709 return fmt.Errorf("found unknown hop-by-hop header option = %#v with discard action", opt) 1710 } 1711 fallthrough 1712 case header.IPv6OptionUnknownActionDiscardSendICMP: 1713 // This case satisfies a requirement of RFC 8200 section 4.2 which 1714 // states that an unknown option starting with bits [10] should: 1715 // 1716 // discard the packet and, regardless of whether or not the 1717 // packet's Destination Address was a multicast address, send an 1718 // ICMP Parameter Problem, Code 2, message to the packet's 1719 // Source Address, pointing to the unrecognized Option Type. 1720 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1721 code: header.ICMPv6UnknownOption, 1722 pointer: it.ParseOffset() + optsIt.OptionOffset(), 1723 respondToMulticast: true, 1724 }, pkt, !forwarding /* deliveredLocally */) 1725 return fmt.Errorf("found unknown hop-by-hop header option = %#v with discard action", opt) 1726 default: 1727 panic(fmt.Sprintf("unrecognized action for an unrecognized Hop By Hop extension header option = %#v", opt)) 1728 } 1729 } 1730 if uopt != nil { 1731 uopt.Data.Release() 1732 uopt = nil 1733 } 1734 } 1735 return nil 1736 } 1737 1738 func (e *endpoint) processFragmentExtHdr(extHdr *header.IPv6FragmentExtHdr, it *header.IPv6PayloadIterator, pkt **stack.PacketBuffer, h header.IPv6) error { 1739 stats := e.stats.ip 1740 fragmentFieldOffset := it.ParseOffset() 1741 1742 // Don't consume the iterator if we have the first fragment because we 1743 // will use it to validate that the first fragment holds the upper layer 1744 // header. 1745 rawPayload := it.AsRawHeader(extHdr.FragmentOffset() != 0 /* consume */) 1746 defer rawPayload.Release() 1747 1748 if extHdr.FragmentOffset() == 0 { 1749 // Check that the iterator ends with a raw payload as the first fragment 1750 // should include all headers up to and including any upper layer 1751 // headers, as per RFC 8200 section 4.5; only upper layer data 1752 // (non-headers) should follow the fragment extension header. 1753 var lastHdr header.IPv6PayloadHeader 1754 1755 for { 1756 it, done, err := it.Next() 1757 if err != nil { 1758 stats.MalformedPacketsReceived.Increment() 1759 stats.MalformedFragmentsReceived.Increment() 1760 return err 1761 } 1762 if done { 1763 break 1764 } 1765 it.Release() 1766 1767 lastHdr = it 1768 } 1769 1770 // If the last header is a raw header, then the last portion of the IPv6 1771 // payload is not a known IPv6 extension header. Note, this does not 1772 // mean that the last portion is an upper layer header or not an 1773 // extension header because: 1774 // 1) we do not yet support all extension headers 1775 // 2) we do not validate the upper layer header before reassembling. 1776 // 1777 // This check makes sure that a known IPv6 extension header is not 1778 // present after the Fragment extension header in a non-initial 1779 // fragment. 1780 // 1781 // TODO(#2196): Support IPv6 Authentication and Encapsulated 1782 // Security Payload extension headers. 1783 // TODO(#2333): Validate that the upper layer header is valid. 1784 switch lastHdr.(type) { 1785 case header.IPv6RawPayloadHeader: 1786 default: 1787 stats.MalformedPacketsReceived.Increment() 1788 stats.MalformedFragmentsReceived.Increment() 1789 return fmt.Errorf("known extension header = %#v present after fragment header in a non-initial fragment", lastHdr) 1790 } 1791 } 1792 1793 fragmentPayloadLen := rawPayload.Buf.Size() 1794 if fragmentPayloadLen == 0 { 1795 // Drop the packet as it's marked as a fragment but has no payload. 1796 stats.MalformedPacketsReceived.Increment() 1797 stats.MalformedFragmentsReceived.Increment() 1798 return fmt.Errorf("fragment has no payload") 1799 } 1800 1801 // As per RFC 2460 Section 4.5: 1802 // 1803 // If the length of a fragment, as derived from the fragment packet's 1804 // Payload Length field, is not a multiple of 8 octets and the M flag 1805 // of that fragment is 1, then that fragment must be discarded and an 1806 // ICMP Parameter Problem, Code 0, message should be sent to the source 1807 // of the fragment, pointing to the Payload Length field of the 1808 // fragment packet. 1809 if extHdr.More() && fragmentPayloadLen%header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit != 0 { 1810 stats.MalformedPacketsReceived.Increment() 1811 stats.MalformedFragmentsReceived.Increment() 1812 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1813 code: header.ICMPv6ErroneousHeader, 1814 pointer: header.IPv6PayloadLenOffset, 1815 }, *pkt, true /* deliveredLocally */) 1816 return fmt.Errorf("found fragment length = %d that is not a multiple of 8 octets", fragmentPayloadLen) 1817 } 1818 1819 // The packet is a fragment, let's try to reassemble it. 1820 start := extHdr.FragmentOffset() * header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit 1821 1822 // As per RFC 2460 Section 4.5: 1823 // 1824 // If the length and offset of a fragment are such that the Payload 1825 // Length of the packet reassembled from that fragment would exceed 1826 // 65,535 octets, then that fragment must be discarded and an ICMP 1827 // Parameter Problem, Code 0, message should be sent to the source of 1828 // the fragment, pointing to the Fragment Offset field of the fragment 1829 // packet. 1830 lengthAfterReassembly := int(start) + int(fragmentPayloadLen) 1831 if lengthAfterReassembly > header.IPv6MaximumPayloadSize { 1832 stats.MalformedPacketsReceived.Increment() 1833 stats.MalformedFragmentsReceived.Increment() 1834 _ = e.protocol.returnError(&icmpReasonParameterProblem{ 1835 code: header.ICMPv6ErroneousHeader, 1836 pointer: fragmentFieldOffset, 1837 }, *pkt, true /* deliveredLocally */) 1838 return fmt.Errorf("determined that reassembled packet length = %d would exceed allowed length = %d", lengthAfterReassembly, header.IPv6MaximumPayloadSize) 1839 } 1840 1841 // Note that pkt doesn't have its transport header set after reassembly, 1842 // and won't until DeliverNetworkPacket sets it. 1843 resPkt, proto, ready, err := e.protocol.fragmentation.Process( 1844 // IPv6 ignores the Protocol field since the ID only needs to be unique 1845 // across source-destination pairs, as per RFC 8200 section 4.5. 1846 fragmentation.FragmentID{ 1847 Source: h.SourceAddress(), 1848 Destination: h.DestinationAddress(), 1849 ID: extHdr.ID(), 1850 }, 1851 start, 1852 start+uint16(fragmentPayloadLen)-1, 1853 extHdr.More(), 1854 uint8(rawPayload.Identifier), 1855 *pkt, 1856 ) 1857 if err != nil { 1858 stats.MalformedPacketsReceived.Increment() 1859 stats.MalformedFragmentsReceived.Increment() 1860 return err 1861 } 1862 1863 if ready { 1864 // We create a new iterator with the reassembled packet because we could 1865 // have more extension headers in the reassembled payload, as per RFC 1866 // 8200 section 4.5. We also use the NextHeader value from the first 1867 // fragment. 1868 it.Release() 1869 *it = header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(proto), resPkt.Data().ToBuffer()) 1870 (*pkt).DecRef() 1871 *pkt = resPkt 1872 } 1873 return nil 1874 } 1875 1876 // Close cleans up resources associated with the endpoint. 1877 func (e *endpoint) Close() { 1878 e.mu.Lock() 1879 e.disableLocked() 1880 e.mu.addressableEndpointState.Cleanup() 1881 e.mu.Unlock() 1882 1883 e.protocol.forgetEndpoint(e.nic.ID()) 1884 } 1885 1886 // NetworkProtocolNumber implements stack.NetworkEndpoint. 1887 func (e *endpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber { 1888 return e.protocol.Number() 1889 } 1890 1891 // AddAndAcquirePermanentAddress implements stack.AddressableEndpoint. 1892 func (e *endpoint) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, properties stack.AddressProperties) (stack.AddressEndpoint, tcpip.Error) { 1893 // TODO(b/169350103): add checks here after making sure we no longer receive 1894 // an empty address. 1895 e.mu.Lock() 1896 defer e.mu.Unlock() 1897 1898 // The dance of registering the dispatcher after adding the address makes it 1899 // so that the tentative state is skipped if DAD is disabled. 1900 addrDisp := properties.Disp 1901 properties.Disp = nil 1902 addressEndpoint, err := e.addAndAcquirePermanentAddressLocked(addr, properties) 1903 if addrDisp != nil && err == nil { 1904 addressEndpoint.RegisterDispatcher(addrDisp) 1905 } 1906 return addressEndpoint, err 1907 } 1908 1909 // addAndAcquirePermanentAddressLocked is like AddAndAcquirePermanentAddress but 1910 // with locking requirements. 1911 // 1912 // addAndAcquirePermanentAddressLocked also joins the passed address's 1913 // solicited-node multicast group and start duplicate address detection. 1914 // 1915 // Precondition: e.mu must be write locked. 1916 func (e *endpoint) addAndAcquirePermanentAddressLocked(addr tcpip.AddressWithPrefix, properties stack.AddressProperties) (stack.AddressEndpoint, tcpip.Error) { 1917 addressEndpoint, err := e.mu.addressableEndpointState.AddAndAcquireAddress(addr, properties, stack.PermanentTentative) 1918 if err != nil { 1919 return nil, err 1920 } 1921 1922 if !header.IsV6UnicastAddress(addr.Address) { 1923 return addressEndpoint, nil 1924 } 1925 1926 if e.Enabled() { 1927 if err := e.mu.ndp.startDuplicateAddressDetection(addr.Address, addressEndpoint); err != nil { 1928 return nil, err 1929 } 1930 } 1931 1932 snmc := header.SolicitedNodeAddr(addr.Address) 1933 if err := e.joinGroupLocked(snmc); err != nil { 1934 // joinGroupLocked only returns an error if the group address is not a valid 1935 // IPv6 multicast address. 1936 panic(fmt.Sprintf("e.joinGroupLocked(%s): %s", snmc, err)) 1937 } 1938 1939 return addressEndpoint, nil 1940 } 1941 1942 // RemovePermanentAddress implements stack.AddressableEndpoint. 1943 func (e *endpoint) RemovePermanentAddress(addr tcpip.Address) tcpip.Error { 1944 e.mu.Lock() 1945 defer e.mu.Unlock() 1946 1947 addressEndpoint := e.getAddressRLocked(addr) 1948 if addressEndpoint == nil || !addressEndpoint.GetKind().IsPermanent() { 1949 return &tcpip.ErrBadLocalAddress{} 1950 } 1951 1952 return e.removePermanentEndpointLocked(addressEndpoint, true /* allowSLAACInvalidation */, stack.AddressRemovalManualAction, &stack.DADAborted{}) 1953 } 1954 1955 // removePermanentEndpointLocked is like removePermanentAddressLocked except 1956 // it works with a stack.AddressEndpoint. 1957 // 1958 // Precondition: e.mu must be write locked. 1959 func (e *endpoint) removePermanentEndpointLocked(addressEndpoint stack.AddressEndpoint, allowSLAACInvalidation bool, reason stack.AddressRemovalReason, dadResult stack.DADResult) tcpip.Error { 1960 addr := addressEndpoint.AddressWithPrefix() 1961 // If we are removing an address generated via SLAAC, cleanup 1962 // its SLAAC resources and notify the integrator. 1963 if addressEndpoint.ConfigType() == stack.AddressConfigSlaac { 1964 if addressEndpoint.Temporary() { 1965 e.mu.ndp.cleanupTempSLAACAddrResourcesAndNotify(addr) 1966 } else { 1967 e.mu.ndp.cleanupSLAACAddrResourcesAndNotify(addr, allowSLAACInvalidation) 1968 } 1969 } 1970 1971 return e.removePermanentEndpointInnerLocked(addressEndpoint, reason, dadResult) 1972 } 1973 1974 // removePermanentEndpointInnerLocked is like removePermanentEndpointLocked 1975 // except it does not cleanup SLAAC address state. 1976 // 1977 // Precondition: e.mu must be write locked. 1978 func (e *endpoint) removePermanentEndpointInnerLocked(addressEndpoint stack.AddressEndpoint, reason stack.AddressRemovalReason, dadResult stack.DADResult) tcpip.Error { 1979 addr := addressEndpoint.AddressWithPrefix() 1980 e.mu.ndp.stopDuplicateAddressDetection(addr.Address, dadResult) 1981 1982 if err := e.mu.addressableEndpointState.RemovePermanentEndpoint(addressEndpoint, reason); err != nil { 1983 return err 1984 } 1985 1986 snmc := header.SolicitedNodeAddr(addr.Address) 1987 err := e.leaveGroupLocked(snmc) 1988 // The endpoint may have already left the multicast group. 1989 if _, ok := err.(*tcpip.ErrBadLocalAddress); ok { 1990 err = nil 1991 } 1992 return err 1993 } 1994 1995 // hasPermanentAddressLocked returns true if the endpoint has a permanent 1996 // address equal to the passed address. 1997 // 1998 // Precondition: e.mu must be read or write locked. 1999 func (e *endpoint) hasPermanentAddressRLocked(addr tcpip.Address) bool { 2000 addressEndpoint := e.getAddressRLocked(addr) 2001 if addressEndpoint == nil { 2002 return false 2003 } 2004 return addressEndpoint.GetKind().IsPermanent() 2005 } 2006 2007 // getAddressRLocked returns the endpoint for the passed address. 2008 // 2009 // Precondition: e.mu must be read or write locked. 2010 func (e *endpoint) getAddressRLocked(localAddr tcpip.Address) stack.AddressEndpoint { 2011 return e.mu.addressableEndpointState.GetAddress(localAddr) 2012 } 2013 2014 // SetDeprecated implements stack.AddressableEndpoint. 2015 func (e *endpoint) SetDeprecated(addr tcpip.Address, deprecated bool) tcpip.Error { 2016 e.mu.RLock() 2017 defer e.mu.RUnlock() 2018 return e.mu.addressableEndpointState.SetDeprecated(addr, deprecated) 2019 } 2020 2021 // SetLifetimes implements stack.AddressableEndpoint. 2022 func (e *endpoint) SetLifetimes(addr tcpip.Address, lifetimes stack.AddressLifetimes) tcpip.Error { 2023 e.mu.RLock() 2024 defer e.mu.RUnlock() 2025 return e.mu.addressableEndpointState.SetLifetimes(addr, lifetimes) 2026 } 2027 2028 // MainAddress implements stack.AddressableEndpoint. 2029 func (e *endpoint) MainAddress() tcpip.AddressWithPrefix { 2030 e.mu.RLock() 2031 defer e.mu.RUnlock() 2032 return e.mu.addressableEndpointState.MainAddress() 2033 } 2034 2035 // AcquireAssignedAddress implements stack.AddressableEndpoint. 2036 func (e *endpoint) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB stack.PrimaryEndpointBehavior, readOnly bool) stack.AddressEndpoint { 2037 e.mu.RLock() 2038 defer e.mu.RUnlock() 2039 return e.acquireAddressOrCreateTempLocked(localAddr, allowTemp, tempPEB, readOnly) 2040 } 2041 2042 // acquireAddressOrCreateTempLocked is like AcquireAssignedAddress but with 2043 // locking requirements. 2044 // 2045 // Precondition: e.mu must be write locked. 2046 func (e *endpoint) acquireAddressOrCreateTempLocked(localAddr tcpip.Address, allowTemp bool, tempPEB stack.PrimaryEndpointBehavior, readOnly bool) stack.AddressEndpoint { 2047 return e.mu.addressableEndpointState.AcquireAssignedAddress(localAddr, allowTemp, tempPEB, readOnly) 2048 } 2049 2050 // AcquireOutgoingPrimaryAddress implements stack.AddressableEndpoint. 2051 func (e *endpoint) AcquireOutgoingPrimaryAddress(remoteAddr, srcHint tcpip.Address, allowExpired bool) stack.AddressEndpoint { 2052 e.mu.RLock() 2053 defer e.mu.RUnlock() 2054 return e.acquireOutgoingPrimaryAddressRLocked(remoteAddr, srcHint, allowExpired) 2055 } 2056 2057 // getLinkLocalAddressRLocked returns a link-local address from the primary list 2058 // of addresses, if one is available. 2059 // 2060 // See stack.PrimaryEndpointBehavior for more details about the primary list. 2061 // 2062 // Precondition: e.mu must be read locked. 2063 func (e *endpoint) getLinkLocalAddressRLocked() tcpip.Address { 2064 var linkLocalAddr tcpip.Address 2065 e.mu.addressableEndpointState.ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 2066 if addressEndpoint.IsAssigned(false /* allowExpired */) { 2067 if addr := addressEndpoint.AddressWithPrefix().Address; header.IsV6LinkLocalUnicastAddress(addr) { 2068 linkLocalAddr = addr 2069 return false 2070 } 2071 } 2072 return true 2073 }) 2074 return linkLocalAddr 2075 } 2076 2077 // acquireOutgoingPrimaryAddressRLocked is like AcquireOutgoingPrimaryAddress 2078 // but with locking requirements. 2079 // 2080 // Precondition: e.mu must be read locked. 2081 func (e *endpoint) acquireOutgoingPrimaryAddressRLocked(remoteAddr, srcHint tcpip.Address, allowExpired bool) stack.AddressEndpoint { 2082 // TODO(b/309216156): Support IPv6 hints. 2083 2084 // addrCandidate is a candidate for Source Address Selection, as per 2085 // RFC 6724 section 5. 2086 type addrCandidate struct { 2087 addressEndpoint stack.AddressEndpoint 2088 addr tcpip.Address 2089 scope header.IPv6AddressScope 2090 2091 label uint8 2092 matchingPrefix uint8 2093 } 2094 2095 if remoteAddr.BitLen() == 0 { 2096 return e.mu.addressableEndpointState.AcquireOutgoingPrimaryAddress(remoteAddr, srcHint, allowExpired) 2097 } 2098 2099 // Create a candidate set of available addresses we can potentially use as a 2100 // source address. 2101 var cs []addrCandidate 2102 e.mu.addressableEndpointState.ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) bool { 2103 // If r is not valid for outgoing connections, it is not a valid endpoint. 2104 if !addressEndpoint.IsAssigned(allowExpired) { 2105 return true 2106 } 2107 2108 addr := addressEndpoint.AddressWithPrefix().Address 2109 scope, err := header.ScopeForIPv6Address(addr) 2110 if err != nil { 2111 // Should never happen as we got r from the primary IPv6 endpoint list and 2112 // ScopeForIPv6Address only returns an error if addr is not an IPv6 2113 // address. 2114 panic(fmt.Sprintf("header.ScopeForIPv6Address(%s): %s", addr, err)) 2115 } 2116 2117 cs = append(cs, addrCandidate{ 2118 addressEndpoint: addressEndpoint, 2119 addr: addr, 2120 scope: scope, 2121 label: getLabel(addr), 2122 matchingPrefix: remoteAddr.MatchingPrefix(addr), 2123 }) 2124 2125 return true 2126 }) 2127 2128 remoteScope, err := header.ScopeForIPv6Address(remoteAddr) 2129 if err != nil { 2130 // primaryIPv6Endpoint should never be called with an invalid IPv6 address. 2131 panic(fmt.Sprintf("header.ScopeForIPv6Address(%s): %s", remoteAddr, err)) 2132 } 2133 2134 remoteLabel := getLabel(remoteAddr) 2135 2136 // Sort the addresses as per RFC 6724 section 5 rules 1-3. 2137 // 2138 // TODO(b/146021396): Implement rules 4, 5 of RFC 6724 section 5. 2139 sort.Slice(cs, func(i, j int) bool { 2140 sa := cs[i] 2141 sb := cs[j] 2142 2143 // Prefer same address as per RFC 6724 section 5 rule 1. 2144 if sa.addr == remoteAddr { 2145 return true 2146 } 2147 if sb.addr == remoteAddr { 2148 return false 2149 } 2150 2151 // Prefer appropriate scope as per RFC 6724 section 5 rule 2. 2152 if sa.scope < sb.scope { 2153 return sa.scope >= remoteScope 2154 } else if sb.scope < sa.scope { 2155 return sb.scope < remoteScope 2156 } 2157 2158 // Avoid deprecated addresses as per RFC 6724 section 5 rule 3. 2159 if saDep, sbDep := sa.addressEndpoint.Deprecated(), sb.addressEndpoint.Deprecated(); saDep != sbDep { 2160 // If sa is not deprecated, it is preferred over sb. 2161 return sbDep 2162 } 2163 2164 // Prefer matching label as per RFC 6724 section 5 rule 6. 2165 if sa, sb := sa.label == remoteLabel, sb.label == remoteLabel; sa != sb { 2166 if sa { 2167 return true 2168 } 2169 if sb { 2170 return false 2171 } 2172 } 2173 2174 // Prefer temporary addresses as per RFC 6724 section 5 rule 7. 2175 if saTemp, sbTemp := sa.addressEndpoint.Temporary(), sb.addressEndpoint.Temporary(); saTemp != sbTemp { 2176 return saTemp 2177 } 2178 2179 // Use longest matching prefix as per RFC 6724 section 5 rule 8. 2180 if sa.matchingPrefix > sb.matchingPrefix { 2181 return true 2182 } 2183 if sb.matchingPrefix > sa.matchingPrefix { 2184 return false 2185 } 2186 2187 // sa and sb are equal, return the endpoint that is closest to the front of 2188 // the primary endpoint list. 2189 return i < j 2190 }) 2191 2192 // Return the most preferred address that can have its reference count 2193 // incremented. 2194 for _, c := range cs { 2195 if c.addressEndpoint.TryIncRef() { 2196 return c.addressEndpoint 2197 } 2198 } 2199 2200 return nil 2201 } 2202 2203 // PrimaryAddresses implements stack.AddressableEndpoint. 2204 func (e *endpoint) PrimaryAddresses() []tcpip.AddressWithPrefix { 2205 e.mu.RLock() 2206 defer e.mu.RUnlock() 2207 return e.mu.addressableEndpointState.PrimaryAddresses() 2208 } 2209 2210 // PermanentAddresses implements stack.AddressableEndpoint. 2211 func (e *endpoint) PermanentAddresses() []tcpip.AddressWithPrefix { 2212 e.mu.RLock() 2213 defer e.mu.RUnlock() 2214 return e.mu.addressableEndpointState.PermanentAddresses() 2215 } 2216 2217 // JoinGroup implements stack.GroupAddressableEndpoint. 2218 func (e *endpoint) JoinGroup(addr tcpip.Address) tcpip.Error { 2219 e.mu.Lock() 2220 defer e.mu.Unlock() 2221 return e.joinGroupLocked(addr) 2222 } 2223 2224 // joinGroupLocked is like JoinGroup but with locking requirements. 2225 // 2226 // Precondition: e.mu must be locked. 2227 func (e *endpoint) joinGroupLocked(addr tcpip.Address) tcpip.Error { 2228 if !header.IsV6MulticastAddress(addr) { 2229 return &tcpip.ErrBadAddress{} 2230 } 2231 2232 e.mu.mld.joinGroup(addr) 2233 return nil 2234 } 2235 2236 // LeaveGroup implements stack.GroupAddressableEndpoint. 2237 func (e *endpoint) LeaveGroup(addr tcpip.Address) tcpip.Error { 2238 e.mu.Lock() 2239 defer e.mu.Unlock() 2240 return e.leaveGroupLocked(addr) 2241 } 2242 2243 // leaveGroupLocked is like LeaveGroup but with locking requirements. 2244 // 2245 // Precondition: e.mu must be locked. 2246 func (e *endpoint) leaveGroupLocked(addr tcpip.Address) tcpip.Error { 2247 return e.mu.mld.leaveGroup(addr) 2248 } 2249 2250 // IsInGroup implements stack.GroupAddressableEndpoint. 2251 func (e *endpoint) IsInGroup(addr tcpip.Address) bool { 2252 e.mu.RLock() 2253 defer e.mu.RUnlock() 2254 return e.mu.mld.isInGroup(addr) 2255 } 2256 2257 // Stats implements stack.NetworkEndpoint. 2258 func (e *endpoint) Stats() stack.NetworkEndpointStats { 2259 return &e.stats.localStats 2260 } 2261 2262 var _ stack.NetworkProtocol = (*protocol)(nil) 2263 var _ stack.MulticastForwardingNetworkProtocol = (*protocol)(nil) 2264 var _ stack.RejectIPv6WithHandler = (*protocol)(nil) 2265 var _ fragmentation.TimeoutHandler = (*protocol)(nil) 2266 2267 type protocol struct { 2268 stack *stack.Stack 2269 options Options 2270 2271 mu struct { 2272 sync.RWMutex 2273 2274 // eps is keyed by NICID to allow protocol methods to retrieve an endpoint 2275 // when handling a packet, by looking at which NIC handled the packet. 2276 eps map[tcpip.NICID]*endpoint 2277 2278 // ICMP types for which the stack's global rate limiting must apply. 2279 icmpRateLimitedTypes map[header.ICMPv6Type]struct{} 2280 2281 // multicastForwardingDisp is the multicast forwarding event dispatcher that 2282 // an integrator can provide to receive multicast forwarding events. Note 2283 // that multicast packets will only be forwarded if this is non-nil. 2284 multicastForwardingDisp stack.MulticastForwardingEventDispatcher 2285 } 2286 2287 // defaultTTL is the current default TTL for the protocol. Only the 2288 // uint8 portion of it is meaningful. 2289 defaultTTL atomicbitops.Uint32 2290 2291 fragmentation *fragmentation.Fragmentation 2292 icmpRateLimiter *stack.ICMPRateLimiter 2293 2294 multicastRouteTable multicast.RouteTable 2295 } 2296 2297 // Number returns the ipv6 protocol number. 2298 func (p *protocol) Number() tcpip.NetworkProtocolNumber { 2299 return ProtocolNumber 2300 } 2301 2302 // MinimumPacketSize returns the minimum valid ipv6 packet size. 2303 func (p *protocol) MinimumPacketSize() int { 2304 return header.IPv6MinimumSize 2305 } 2306 2307 // ParseAddresses implements stack.NetworkProtocol. 2308 func (*protocol) ParseAddresses(b []byte) (src, dst tcpip.Address) { 2309 h := header.IPv6(b) 2310 return h.SourceAddress(), h.DestinationAddress() 2311 } 2312 2313 // NewEndpoint creates a new ipv6 endpoint. 2314 func (p *protocol) NewEndpoint(nic stack.NetworkInterface, dispatcher stack.TransportDispatcher) stack.NetworkEndpoint { 2315 e := &endpoint{ 2316 nic: nic, 2317 dispatcher: dispatcher, 2318 protocol: p, 2319 } 2320 2321 // NDP options must be 8 octet aligned and the first 2 bytes are used for 2322 // the type and length fields leaving 6 octets as the minimum size for a 2323 // nonce option without padding. 2324 const nonceSize = 6 2325 2326 // As per RFC 7527 section 4.1, 2327 // 2328 // If any probe is looped back within RetransTimer milliseconds after 2329 // having sent DupAddrDetectTransmits NS(DAD) messages, the interface 2330 // continues with another MAX_MULTICAST_SOLICIT number of NS(DAD) 2331 // messages transmitted RetransTimer milliseconds apart. 2332 // 2333 // Value taken from RFC 4861 section 10. 2334 const maxMulticastSolicit = 3 2335 dadOptions := ip.DADOptions{ 2336 Clock: p.stack.Clock(), 2337 SecureRNG: p.stack.SecureRNG().Reader, 2338 NonceSize: nonceSize, 2339 ExtendDADTransmits: maxMulticastSolicit, 2340 Protocol: &e.mu.ndp, 2341 NICID: nic.ID(), 2342 } 2343 2344 e.mu.Lock() 2345 e.mu.addressableEndpointState.Init(e, stack.AddressableEndpointStateOptions{HiddenWhileDisabled: true}) 2346 e.mu.ndp.init(e, dadOptions) 2347 e.mu.mld.init(e) 2348 e.dad.mu.Lock() 2349 e.dad.mu.dad.Init(&e.dad.mu, p.options.DADConfigs, dadOptions) 2350 e.dad.mu.Unlock() 2351 e.mu.Unlock() 2352 2353 stackStats := p.stack.Stats() 2354 tcpip.InitStatCounters(reflect.ValueOf(&e.stats.localStats).Elem()) 2355 e.stats.ip.Init(&e.stats.localStats.IP, &stackStats.IP) 2356 e.stats.icmp.init(&e.stats.localStats.ICMP, &stackStats.ICMP.V6) 2357 2358 p.mu.Lock() 2359 defer p.mu.Unlock() 2360 p.mu.eps[nic.ID()] = e 2361 return e 2362 } 2363 2364 func (p *protocol) findEndpointWithAddress(addr tcpip.Address) *endpoint { 2365 p.mu.RLock() 2366 defer p.mu.RUnlock() 2367 2368 for _, e := range p.mu.eps { 2369 if addressEndpoint := e.AcquireAssignedAddress(addr, false /* allowTemp */, stack.NeverPrimaryEndpoint, true /* readOnly */); addressEndpoint != nil { 2370 return e 2371 } 2372 } 2373 2374 return nil 2375 } 2376 2377 func (p *protocol) getEndpointForNIC(id tcpip.NICID) (*endpoint, bool) { 2378 p.mu.RLock() 2379 defer p.mu.RUnlock() 2380 ep, ok := p.mu.eps[id] 2381 return ep, ok 2382 } 2383 2384 func (p *protocol) forgetEndpoint(nicID tcpip.NICID) { 2385 p.mu.Lock() 2386 defer p.mu.Unlock() 2387 delete(p.mu.eps, nicID) 2388 } 2389 2390 // SetOption implements stack.NetworkProtocol. 2391 func (p *protocol) SetOption(option tcpip.SettableNetworkProtocolOption) tcpip.Error { 2392 switch v := option.(type) { 2393 case *tcpip.DefaultTTLOption: 2394 p.SetDefaultTTL(uint8(*v)) 2395 return nil 2396 default: 2397 return &tcpip.ErrUnknownProtocolOption{} 2398 } 2399 } 2400 2401 // Option implements stack.NetworkProtocol. 2402 func (p *protocol) Option(option tcpip.GettableNetworkProtocolOption) tcpip.Error { 2403 switch v := option.(type) { 2404 case *tcpip.DefaultTTLOption: 2405 *v = tcpip.DefaultTTLOption(p.DefaultTTL()) 2406 return nil 2407 default: 2408 return &tcpip.ErrUnknownProtocolOption{} 2409 } 2410 } 2411 2412 // SetDefaultTTL sets the default TTL for endpoints created with this protocol. 2413 func (p *protocol) SetDefaultTTL(ttl uint8) { 2414 p.defaultTTL.Store(uint32(ttl)) 2415 } 2416 2417 // DefaultTTL returns the default TTL for endpoints created with this protocol. 2418 func (p *protocol) DefaultTTL() uint8 { 2419 return uint8(p.defaultTTL.Load()) 2420 } 2421 2422 // emitMulticastEvent emits a multicast forwarding event using the provided 2423 // generator if a valid event dispatcher exists. 2424 func (e *endpoint) emitMulticastEvent(eventGenerator func(stack.MulticastForwardingEventDispatcher)) { 2425 e.protocol.mu.RLock() 2426 defer e.protocol.mu.RUnlock() 2427 if mcastDisp := e.protocol.mu.multicastForwardingDisp; mcastDisp != nil { 2428 eventGenerator(mcastDisp) 2429 } 2430 } 2431 2432 // Close implements stack.TransportProtocol. 2433 func (p *protocol) Close() { 2434 p.fragmentation.Release() 2435 p.multicastRouteTable.Close() 2436 } 2437 2438 func validateUnicastSourceAndMulticastDestination(addresses stack.UnicastSourceAndMulticastDestination) tcpip.Error { 2439 if !header.IsV6UnicastAddress(addresses.Source) || header.IsV6LinkLocalUnicastAddress(addresses.Source) { 2440 return &tcpip.ErrBadAddress{} 2441 } 2442 2443 if !header.IsV6MulticastAddress(addresses.Destination) || header.IsV6LinkLocalMulticastAddress(addresses.Destination) { 2444 return &tcpip.ErrBadAddress{} 2445 } 2446 2447 return nil 2448 } 2449 2450 func (p *protocol) multicastForwarding() bool { 2451 p.mu.RLock() 2452 defer p.mu.RUnlock() 2453 return p.mu.multicastForwardingDisp != nil 2454 } 2455 2456 func (p *protocol) newInstalledRoute(route stack.MulticastRoute) (*multicast.InstalledRoute, tcpip.Error) { 2457 if len(route.OutgoingInterfaces) == 0 { 2458 return nil, &tcpip.ErrMissingRequiredFields{} 2459 } 2460 2461 if !p.stack.HasNIC(route.ExpectedInputInterface) { 2462 return nil, &tcpip.ErrUnknownNICID{} 2463 } 2464 2465 for _, outgoingInterface := range route.OutgoingInterfaces { 2466 if route.ExpectedInputInterface == outgoingInterface.ID { 2467 return nil, &tcpip.ErrMulticastInputCannotBeOutput{} 2468 } 2469 2470 if !p.stack.HasNIC(outgoingInterface.ID) { 2471 return nil, &tcpip.ErrUnknownNICID{} 2472 } 2473 } 2474 return p.multicastRouteTable.NewInstalledRoute(route), nil 2475 } 2476 2477 // AddMulticastRoute implements stack.MulticastForwardingNetworkProtocol. 2478 func (p *protocol) AddMulticastRoute(addresses stack.UnicastSourceAndMulticastDestination, route stack.MulticastRoute) tcpip.Error { 2479 if !p.multicastForwarding() { 2480 return &tcpip.ErrNotPermitted{} 2481 } 2482 2483 if err := validateUnicastSourceAndMulticastDestination(addresses); err != nil { 2484 return err 2485 } 2486 2487 installedRoute, err := p.newInstalledRoute(route) 2488 if err != nil { 2489 return err 2490 } 2491 2492 pendingPackets := p.multicastRouteTable.AddInstalledRoute(addresses, installedRoute) 2493 2494 for _, pkt := range pendingPackets { 2495 p.forwardPendingMulticastPacket(pkt, installedRoute) 2496 } 2497 return nil 2498 } 2499 2500 // RemoveMulticastRoute implements 2501 // stack.MulticastForwardingNetworkProtocol.RemoveMulticastRoute. 2502 func (p *protocol) RemoveMulticastRoute(addresses stack.UnicastSourceAndMulticastDestination) tcpip.Error { 2503 if err := validateUnicastSourceAndMulticastDestination(addresses); err != nil { 2504 return err 2505 } 2506 2507 if removed := p.multicastRouteTable.RemoveInstalledRoute(addresses); !removed { 2508 return &tcpip.ErrHostUnreachable{} 2509 } 2510 2511 return nil 2512 } 2513 2514 // MulticastRouteLastUsedTime implements 2515 // stack.MulticastForwardingNetworkProtocol. 2516 func (p *protocol) MulticastRouteLastUsedTime(addresses stack.UnicastSourceAndMulticastDestination) (tcpip.MonotonicTime, tcpip.Error) { 2517 if err := validateUnicastSourceAndMulticastDestination(addresses); err != nil { 2518 return tcpip.MonotonicTime{}, err 2519 } 2520 2521 timestamp, found := p.multicastRouteTable.GetLastUsedTimestamp(addresses) 2522 2523 if !found { 2524 return tcpip.MonotonicTime{}, &tcpip.ErrHostUnreachable{} 2525 } 2526 2527 return timestamp, nil 2528 } 2529 2530 // EnableMulticastForwarding implements 2531 // stack.MulticastForwardingNetworkProtocol.EnableMulticastForwarding. 2532 func (p *protocol) EnableMulticastForwarding(disp stack.MulticastForwardingEventDispatcher) (bool, tcpip.Error) { 2533 p.mu.Lock() 2534 defer p.mu.Unlock() 2535 2536 if p.mu.multicastForwardingDisp != nil { 2537 return true, nil 2538 } 2539 2540 if disp == nil { 2541 return false, &tcpip.ErrInvalidOptionValue{} 2542 } 2543 2544 p.mu.multicastForwardingDisp = disp 2545 return false, nil 2546 } 2547 2548 // DisableMulticastForwarding implements 2549 // stack.MulticastForwardingNetworkProtocol.DisableMulticastForwarding. 2550 func (p *protocol) DisableMulticastForwarding() { 2551 p.mu.Lock() 2552 defer p.mu.Unlock() 2553 p.mu.multicastForwardingDisp = nil 2554 p.multicastRouteTable.RemoveAllInstalledRoutes() 2555 } 2556 2557 func (p *protocol) forwardPendingMulticastPacket(pkt *stack.PacketBuffer, installedRoute *multicast.InstalledRoute) { 2558 defer pkt.DecRef() 2559 2560 // Attempt to forward the packet using the endpoint that it originally 2561 // arrived on. This ensures that the packet is only forwarded if it 2562 // matches the route's expected input interface (see 5a of RFC 1812 section 2563 // 5.2.1.3). 2564 ep, ok := p.getEndpointForNIC(pkt.NICID) 2565 2566 if !ok { 2567 // The endpoint that the packet arrived on no longer exists. Silently 2568 // drop the pkt. 2569 return 2570 } 2571 2572 if !ep.MulticastForwarding() { 2573 return 2574 } 2575 2576 ep.handleForwardingError(ep.forwardValidatedMulticastPacket(pkt, installedRoute)) 2577 } 2578 2579 // Wait implements stack.TransportProtocol. 2580 func (*protocol) Wait() {} 2581 2582 // parseAndValidate parses the packet (including its transport layer header) and 2583 // returns a view containing the parsed IP header. The caller is responsible 2584 // for releasing the returned View. 2585 // 2586 // Returns true if the IP header was successfully parsed. 2587 func (p *protocol) parseAndValidate(pkt *stack.PacketBuffer) (*buffer.View, bool) { 2588 transProtoNum, hasTransportHdr, ok := p.Parse(pkt) 2589 if !ok { 2590 return nil, false 2591 } 2592 2593 h := header.IPv6(pkt.NetworkHeader().Slice()) 2594 // Do not include the link header's size when calculating the size of the IP 2595 // packet. 2596 if !h.IsValid(pkt.Size() - len(pkt.LinkHeader().Slice())) { 2597 return nil, false 2598 } 2599 2600 if hasTransportHdr { 2601 p.parseTransport(pkt, transProtoNum) 2602 } 2603 2604 return pkt.NetworkHeader().View(), true 2605 } 2606 2607 func (p *protocol) parseTransport(pkt *stack.PacketBuffer, transProtoNum tcpip.TransportProtocolNumber) { 2608 if transProtoNum == header.ICMPv6ProtocolNumber { 2609 // The transport layer will handle transport layer parsing errors. 2610 _ = parse.ICMPv6(pkt) 2611 return 2612 } 2613 2614 switch err := p.stack.ParsePacketBufferTransport(transProtoNum, pkt); err { 2615 case stack.ParsedOK: 2616 case stack.UnknownTransportProtocol, stack.TransportLayerParseError: 2617 // The transport layer will handle unknown protocols and transport layer 2618 // parsing errors. 2619 default: 2620 panic(fmt.Sprintf("unexpected error parsing transport header = %d", err)) 2621 } 2622 } 2623 2624 // Parse implements stack.NetworkProtocol. 2625 func (*protocol) Parse(pkt *stack.PacketBuffer) (proto tcpip.TransportProtocolNumber, hasTransportHdr bool, ok bool) { 2626 proto, _, fragOffset, fragMore, ok := parse.IPv6(pkt) 2627 if !ok { 2628 return 0, false, false 2629 } 2630 2631 return proto, !fragMore && fragOffset == 0, true 2632 } 2633 2634 // allowICMPReply reports whether an ICMP reply with provided type may 2635 // be sent following the rate mask options and global ICMP rate limiter. 2636 func (p *protocol) allowICMPReply(icmpType header.ICMPv6Type) bool { 2637 p.mu.RLock() 2638 defer p.mu.RUnlock() 2639 2640 if _, ok := p.mu.icmpRateLimitedTypes[icmpType]; ok { 2641 return p.stack.AllowICMPMessage() 2642 } 2643 return true 2644 } 2645 2646 // SendRejectionError implements stack.RejectIPv6WithHandler. 2647 func (p *protocol) SendRejectionError(pkt *stack.PacketBuffer, rejectWith stack.RejectIPv6WithICMPType, inputHook bool) tcpip.Error { 2648 switch rejectWith { 2649 case stack.RejectIPv6WithICMPNoRoute: 2650 return p.returnError(&icmpReasonNetUnreachable{}, pkt, inputHook) 2651 case stack.RejectIPv6WithICMPAddrUnreachable: 2652 return p.returnError(&icmpReasonHostUnreachable{}, pkt, inputHook) 2653 case stack.RejectIPv6WithICMPPortUnreachable: 2654 return p.returnError(&icmpReasonPortUnreachable{}, pkt, inputHook) 2655 case stack.RejectIPv6WithICMPAdminProhibited: 2656 return p.returnError(&icmpReasonAdministrativelyProhibited{}, pkt, inputHook) 2657 default: 2658 panic(fmt.Sprintf("unhandled %[1]T = %[1]d", rejectWith)) 2659 } 2660 } 2661 2662 // calculateNetworkMTU calculates the network-layer payload MTU based on the 2663 // link-layer payload MTU and the length of every IPv6 header. 2664 // Note that this is different than the Payload Length field of the IPv6 header, 2665 // which includes the length of the extension headers. 2666 func calculateNetworkMTU(linkMTU, networkHeadersLen uint32) (uint32, tcpip.Error) { 2667 if linkMTU < header.IPv6MinimumMTU { 2668 return 0, &tcpip.ErrInvalidEndpointState{} 2669 } 2670 2671 // As per RFC 7112 section 5, we should discard packets if their IPv6 header 2672 // is bigger than 1280 bytes (ie, the minimum link MTU) since we do not 2673 // support PMTU discovery: 2674 // Hosts that do not discover the Path MTU MUST limit the IPv6 Header Chain 2675 // length to 1280 bytes. Limiting the IPv6 Header Chain length to 1280 2676 // bytes ensures that the header chain length does not exceed the IPv6 2677 // minimum MTU. 2678 if networkHeadersLen > header.IPv6MinimumMTU { 2679 return 0, &tcpip.ErrMalformedHeader{} 2680 } 2681 2682 networkMTU := linkMTU - networkHeadersLen 2683 if networkMTU > maxPayloadSize { 2684 networkMTU = maxPayloadSize 2685 } 2686 return networkMTU, nil 2687 } 2688 2689 // Options holds options to configure a new protocol. 2690 type Options struct { 2691 // NDPConfigs is the default NDP configurations used by interfaces. 2692 NDPConfigs NDPConfigurations 2693 2694 // AutoGenLinkLocal determines whether or not the stack attempts to 2695 // auto-generate a link-local address for newly enabled non-loopback 2696 // NICs. 2697 // 2698 // Note, setting this to true does not mean that a link-local address is 2699 // assigned right away, or at all. If Duplicate Address Detection is enabled, 2700 // an address is only assigned if it successfully resolves. If it fails, no 2701 // further attempts are made to auto-generate a link-local address. 2702 // 2703 // The generated link-local address follows RFC 4291 Appendix A guidelines. 2704 AutoGenLinkLocal bool 2705 2706 // NDPDisp is the NDP event dispatcher that an integrator can provide to 2707 // receive NDP related events. 2708 NDPDisp NDPDispatcher 2709 2710 // OpaqueIIDOpts hold the options for generating opaque interface 2711 // identifiers (IIDs) as outlined by RFC 7217. 2712 OpaqueIIDOpts OpaqueInterfaceIdentifierOptions 2713 2714 // TempIIDSeed is used to seed the initial temporary interface identifier 2715 // history value used to generate IIDs for temporary SLAAC addresses. 2716 // 2717 // Temporary SLAAC addresses are short-lived addresses which are unpredictable 2718 // and random from the perspective of other nodes on the network. It is 2719 // recommended that the seed be a random byte buffer of at least 2720 // header.IIDSize bytes to make sure that temporary SLAAC addresses are 2721 // sufficiently random. It should follow minimum randomness requirements for 2722 // security as outlined by RFC 4086. 2723 // 2724 // Note: using a nil value, the same seed across netstack program runs, or a 2725 // seed that is too small would reduce randomness and increase predictability, 2726 // defeating the purpose of temporary SLAAC addresses. 2727 TempIIDSeed []byte 2728 2729 // MLD holds options for MLD. 2730 MLD MLDOptions 2731 2732 // DADConfigs holds the default DAD configurations used by IPv6 endpoints. 2733 DADConfigs stack.DADConfigurations 2734 2735 // AllowExternalLoopbackTraffic indicates that inbound loopback packets (i.e. 2736 // martian loopback packets) should be accepted. 2737 AllowExternalLoopbackTraffic bool 2738 } 2739 2740 // NewProtocolWithOptions returns an IPv6 network protocol. 2741 func NewProtocolWithOptions(opts Options) stack.NetworkProtocolFactory { 2742 opts.NDPConfigs.validate() 2743 2744 return func(s *stack.Stack) stack.NetworkProtocol { 2745 p := &protocol{ 2746 stack: s, 2747 options: opts, 2748 } 2749 p.fragmentation = fragmentation.NewFragmentation(header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, ReassembleTimeout, s.Clock(), p) 2750 p.mu.eps = make(map[tcpip.NICID]*endpoint) 2751 p.SetDefaultTTL(DefaultTTL) 2752 // Set default ICMP rate limiting to Linux defaults. 2753 // 2754 // Default: 0-1,3-127 (rate limit ICMPv6 errors except Packet Too Big) 2755 // See https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt. 2756 defaultIcmpTypes := make(map[header.ICMPv6Type]struct{}) 2757 for i := header.ICMPv6Type(0); i < header.ICMPv6EchoRequest; i++ { 2758 switch i { 2759 case header.ICMPv6PacketTooBig: 2760 // Do not rate limit packet too big by default. 2761 default: 2762 defaultIcmpTypes[i] = struct{}{} 2763 } 2764 } 2765 p.mu.icmpRateLimitedTypes = defaultIcmpTypes 2766 2767 if err := p.multicastRouteTable.Init(multicast.DefaultConfig(s.Clock())); err != nil { 2768 panic(fmt.Sprintf("p.multicastRouteTable.Init(_): %s", err)) 2769 } 2770 2771 return p 2772 } 2773 } 2774 2775 // NewProtocol is equivalent to NewProtocolWithOptions with an empty Options. 2776 func NewProtocol(s *stack.Stack) stack.NetworkProtocol { 2777 return NewProtocolWithOptions(Options{})(s) 2778 } 2779 2780 func calculateFragmentReserve(pkt *stack.PacketBuffer) int { 2781 return pkt.AvailableHeaderBytes() + len(pkt.NetworkHeader().Slice()) + header.IPv6FragmentHeaderSize 2782 } 2783 2784 // getFragmentID returns a random uint32 number (other than zero) to be used as 2785 // fragment ID in the IPv6 header. 2786 func (e *endpoint) getFragmentID() uint32 { 2787 rng := e.protocol.stack.SecureRNG() 2788 id := rng.Uint32() 2789 for id == 0 { 2790 id = rng.Uint32() 2791 } 2792 return id 2793 } 2794 2795 func buildNextFragment(pf *fragmentation.PacketFragmenter, originalIPHeaders header.IPv6, transportProto tcpip.TransportProtocolNumber, id uint32) (*stack.PacketBuffer, bool) { 2796 fragPkt, offset, copied, more := pf.BuildNextFragment() 2797 fragPkt.NetworkProtocolNumber = ProtocolNumber 2798 2799 originalIPHeadersLength := len(originalIPHeaders) 2800 2801 s := header.IPv6ExtHdrSerializer{&header.IPv6SerializableFragmentExtHdr{ 2802 FragmentOffset: uint16(offset / header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit), 2803 M: more, 2804 Identification: id, 2805 }} 2806 2807 fragmentIPHeadersLength := originalIPHeadersLength + s.Length() 2808 fragmentIPHeaders := header.IPv6(fragPkt.NetworkHeader().Push(fragmentIPHeadersLength)) 2809 2810 // Copy the IPv6 header and any extension headers already populated. 2811 if copied := copy(fragmentIPHeaders, originalIPHeaders); copied != originalIPHeadersLength { 2812 panic(fmt.Sprintf("wrong number of bytes copied into fragmentIPHeaders: got %d, want %d", copied, originalIPHeadersLength)) 2813 } 2814 2815 nextHeader, _ := s.Serialize(transportProto, fragmentIPHeaders[originalIPHeadersLength:]) 2816 2817 fragmentIPHeaders.SetNextHeader(nextHeader) 2818 fragmentIPHeaders.SetPayloadLength(uint16(copied + fragmentIPHeadersLength - header.IPv6MinimumSize)) 2819 2820 return fragPkt, more 2821 } 2822 2823 func checkV4Mapped(h header.IPv6, stats ip.MultiCounterIPStats) bool { 2824 // Disallow IPv4-mapped addresses per RFC 6890 section 2.2.3. 2825 ret := true 2826 if header.IsV4MappedAddress(h.SourceAddress()) { 2827 stats.InvalidSourceAddressesReceived.Increment() 2828 ret = false 2829 } 2830 if header.IsV4MappedAddress(h.DestinationAddress()) { 2831 stats.InvalidDestinationAddressesReceived.Increment() 2832 ret = false 2833 } 2834 return ret 2835 }