shouldHandlePing returns whether or not netstack should handle an incoming ICMP echo request packet, and the IP address that should be pinged from this process. The IP address can be different from the destination in the packet if the destination is a 4via6 address.
(p *packet.Parsed)
| 1446 | // process. The IP address can be different from the destination in the packet |
| 1447 | // if the destination is a 4via6 address. |
| 1448 | func (ns *Impl) shouldHandlePing(p *packet.Parsed) (_ netip.Addr, ok bool) { |
| 1449 | if !p.IsEchoRequest() { |
| 1450 | return netip.Addr{}, false |
| 1451 | } |
| 1452 | |
| 1453 | destIP := p.Dst.Addr() |
| 1454 | |
| 1455 | // We need to handle pings for all 4via6 addresses, even if this |
| 1456 | // netstack instance normally isn't responsible for processing subnets. |
| 1457 | // |
| 1458 | // For example, on Linux, subnet router traffic could be handled via |
| 1459 | // tun+iptables rules for most packets, but we still need to handle |
| 1460 | // ICMP echo requests over 4via6 since the host networking stack |
| 1461 | // doesn't know what to do with a 4via6 address. |
| 1462 | // |
| 1463 | // shouldProcessInbound returns 'true' to say that we should process |
| 1464 | // all IPv6 packets with a destination address in the 'via' range, so |
| 1465 | // check before we check the "ProcessSubnets" boolean below. |
| 1466 | if viaRange.Contains(destIP) { |
| 1467 | // The input echo request was to a 4via6 address, which we cannot |
| 1468 | // simply ping as-is from this process. Translate the destination to an |
| 1469 | // IPv4 address, so that our relayed ping (in userPing) is pinging the |
| 1470 | // underlying destination IP. |
| 1471 | // |
| 1472 | // ICMPv4 and ICMPv6 are different protocols with different on-the-wire |
| 1473 | // representations, so normally you can't send an ICMPv6 message over |
| 1474 | // IPv4 and expect to get a useful result. However, in this specific |
| 1475 | // case things are safe because the 'userPing' function doesn't make |
| 1476 | // use of the input packet. |
| 1477 | return tsaddr.UnmapVia(destIP), true |
| 1478 | } |
| 1479 | |
| 1480 | // If we get here, we don't do anything unless this netstack instance |
| 1481 | // is responsible for processing subnet traffic. |
| 1482 | if !ns.ProcessSubnets { |
| 1483 | return netip.Addr{}, false |
| 1484 | } |
| 1485 | |
| 1486 | // For non-4via6 addresses, we don't handle pings if they're destined |
| 1487 | // for a Tailscale IP. |
| 1488 | if tsaddr.IsTailscaleIP(destIP) { |
| 1489 | return netip.Addr{}, false |
| 1490 | } |
| 1491 | |
| 1492 | // This netstack instance is processing subnet traffic, so handle the |
| 1493 | // ping ourselves. |
| 1494 | return destIP, true |
| 1495 | } |
| 1496 | |
| 1497 | func netaddrIPFromNetstackIP(s tcpip.Address) netip.Addr { |
| 1498 | switch s.Len() { |