Skip to content

netstack: allow defaultHandler respond ICMPv4Echo in promiscuous mode #11609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 30, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion pkg/tcpip/network/ipv4/icmp.go
Original file line number Diff line number Diff line change
@@ -356,12 +356,20 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
replyData := stack.PayloadSince(pkt.TransportHeader())
defer replyData.Release()
ipHdr := header.IPv4(pkt.NetworkHeader().Slice())
localAddressTemporary := pkt.NetworkPacketInfo.LocalAddressTemporary
localAddressBroadcast := pkt.NetworkPacketInfo.LocalAddressBroadcast

// It's possible that a raw socket expects to receive this.
// It's possible that a raw socket or custom defaultHandler expects to
// receive this packet.
e.dispatcher.DeliverTransportPacket(header.ICMPv4ProtocolNumber, pkt)
pkt = nil

// Skip direct ICMP echo reply if the packet was received with a temporary
// address, allowing custom handlers to take over.
if localAddressTemporary {
return
}

sent := e.stats.icmp.packetsSent
if !e.protocol.allowICMPReply(header.ICMPv4EchoReply, header.ICMPv4UnusedCode) {
sent.rateLimited.Increment()
1 change: 1 addition & 0 deletions pkg/tcpip/network/ipv4/ipv4.go
Original file line number Diff line number Diff line change
@@ -1169,6 +1169,7 @@ func (e *endpoint) handleValidatedPacket(h header.IPv4, pkt *stack.PacketBuffer,
// If the packet is destined for this device, then it should be delivered
// locally. Otherwise, if forwarding is enabled, it should be forwarded.
if addressEndpoint := e.AcquireAssignedAddress(dstAddr, e.nic.Promiscuous(), stack.CanBePrimaryEndpoint, true /* readOnly */); addressEndpoint != nil {
pkt.NetworkPacketInfo.LocalAddressTemporary = addressEndpoint.Temporary()
subnet := addressEndpoint.AddressWithPrefix().Subnet()
pkt.NetworkPacketInfo.LocalAddressBroadcast = subnet.IsBroadcast(dstAddr) || dstAddr == header.IPv4Broadcast
e.deliverPacketLocally(h, pkt, inNICName)
2 changes: 1 addition & 1 deletion pkg/tcpip/stack/addressable_endpoint_state.go
Original file line number Diff line number Diff line change
@@ -602,7 +602,7 @@ func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tc

// Proceed to add a new temporary endpoint.
addr := localAddr.WithPrefix()
ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, Temporary)
ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB, Temporary: true}, Temporary)
if err != nil {
// addAndAcquireAddressLocked only returns an error if the address is
// already assigned but we just checked above if the address exists so we
4 changes: 4 additions & 0 deletions pkg/tcpip/stack/registration.go
Original file line number Diff line number Diff line change
@@ -58,6 +58,10 @@ type NetworkPacketInfo struct {
// address.
LocalAddressBroadcast bool

// LocalAddressTemporary is true if the packet's local address is a temporary
// address.
LocalAddressTemporary bool

// IsForwardedPacket is true if the packet is being forwarded.
IsForwardedPacket bool
}