GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — icmp: workaround for gvisor's fake ICMP echo by Lanius-collaris · Pull Request #142 · celzero/firestack

Conversation

@Lanius-collaris

@Lanius-collaris Lanius-collaris commented Mar 22, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Not working. I'm trying inserting code in other positions.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ignoramous reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@Lanius-collaris
icmp: workaround for gvisor's fake ICMP echo
2cc55a2
github-advanced-security[bot]
github-advanced-security AI found potential problems Mar 22, 2025
View reviewed changes
Comment thread intra/netstack/icmp.go Fixed

Uh oh!

There was an error while loading. Please reload this page.

@ignoramous

ignoramous commented Mar 22, 2025

Copy link
Copy Markdown
Contributor

Thanks.

I wonder if this forceful default handling of ICMP is a bug on gvisor upstream despite having set a ICMP handler? It was working as I'd expect it to in previous (believe a year or so ago) gvisor version.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ignoramous
ignoramous requested a review from Copilot March 22, 2025 15:44
Copilot AI reviewed Mar 22, 2025
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a workaround for gvisor's fake ICMP echo by modifying the ICMP packet types and recalculating checksums for both ICMPv6 and ICMPv4 before processing.

  • Adds a new ICMPHackTarget and associated Action method for intercepting and modifying ICMP packets.
  • Implements restore functions to revert the experimental packet type changes and adjusts the outbound handler to invoke the hack.
Comments suppressed due to low confidence (2)

intra/netstack/icmp.go:36

  • [nitpick] Consider replacing the magic number 200 with a clearly named constant (e.g., ICMPv6ExperimentalType) for improved readability and maintenance.
icmp6Hdr.SetType(200)

intra/netstack/icmp.go:56

  • [nitpick] Replace the magic number 253 with a named constant (e.g., ICMPv4ExperimentalType) to enhance clarity and consistency.
icmp4Hdr.SetType(253)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Lanius-collaris

Lanius-collaris commented Mar 24, 2025

Copy link
Copy Markdown
Contributor Author

It was working as I'd expect it to in previous (believe a year or so ago) gvisor version.

🤔Will current handler work if these lines are deleted?
https://github.com/google/gvisor/blob/3a9ba17351571e343e16caec2e44215d8adc400f/pkg/tcpip/network/ipv6/icmp.go#L694
https://github.com/google/gvisor/blob/3a9ba17351571e343e16caec2e44215d8adc400f/pkg/tcpip/network/ipv4/icmp.go#L449

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Lanius-collaris

Lanius-collaris commented Mar 28, 2025

Copy link
Copy Markdown
Contributor Author

I wonder if this forceful default handling of ICMP is a bug on gvisor upstream despite having set a ICMP handler? It was working as I'd expect it to in previous (believe a year or so ago) gvisor version.

I have a theory that these lines were written for inbound ICMP echo requests (packet sockets can receive them).

@kevinGC
Could you answer ignoramous' question?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@kevinGC

kevinGC commented Mar 28, 2025

Copy link
Copy Markdown

Sorry, what's the specific question? I'm missing some context and not sure what 'fake' means in the title here.

I don't remember any recent changes to ICMP handling. If you've set a custom handler for ICMP packets and the stack is still doing its own ICMP handling, I think that's because ICMP handling is tightly coupled to the ipv4 and ipv6 packages. Nobody has tried to split them AFAIK, so there's no easy way to turn off just ICMP.

Packet sockets should get ICMP messages regardless of the code in the ipv4 and ipv6 packages; it happens earlier in packaet processing (around nic.go:DeliverLinkPacket).

BTW @nybidari is the gVisor networking lead these days.

ignoramous reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ignoramous

ignoramous commented Mar 28, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Sorry, what's the specific question? I'm missing some context and not sure what 'fake' means in the title here.

Netstack replies to ICMP messages on its own and does not wait on the Handler set via stack.SetTransportProtocolHandler (unlike for TCP and UDP, for which Netstack processes packets only if the Handler does not).

I should note that Netstack we use is setup with Spoofing and is Promiscuous (ref), in addition to being the default gateway (0.0.0.0 and :: routes); HandleLocal & NICForwarding opts are also set to false (ref).

Packet sockets should get ICMP messages regardless of the code in the ipv4 and ipv6 packages;

This happens even today. The Handler does get those packets, but Netstack replies to those packets before the Handler has had the chance.

Like @Lanius-collaris points out, ICMP is handled internally (here) before being delivered to the Handler (here?)? For us, it is enough if ICMP requests (echo, specifically) (which aren't tied to an existing UDP/TCP sesssion), like those usually coming from ping or equivalent progs, are sent to the Handler before Netstack looks at them.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Lanius-collaris

Lanius-collaris commented Mar 28, 2025

Copy link
Copy Markdown
Contributor Author

I have a theory that these lines were written for inbound ICMP echo requests (packet sockets can receive them).

Packet sockets should get ICMP messages regardless of the code in the ipv4 and ipv6 packages; it happens earlier in packaet processing (around nic.go:DeliverLinkPacket).

"packet sockets" here mean sockets created with socket(AF_PACKET, int socket_type, int protocol) on linux, not tcpip.Endpoint provided by gvisor.dev/gvisor/pkg/tcpip/transport/packet module.

If you've set a custom handler for ICMP packets and the stack is still doing its own ICMP handling, I think that's because ICMP handling is tightly coupled to the ipv4 and ipv6 packages. Nobody has tried to split them AFAIK, so there's no easy way to turn off just ICMP.

I have tried and succeeded. 😆 Stack.IPTables() is powerful.
Lanius-collaris/gvisor-playground@5403bf8

ignoramous reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ignoramous
ignoramous force-pushed the n2 branch 3 times, most recently from bf17d71 to 04fe473 Compare August 18, 2025 03:33
Lanius-collaris
Lanius-collaris commented Aug 26, 2025
View reviewed changes
Comment thread intra/netstack/icmp.go Outdated
rules[index].Filter.Protocol = header.ICMPv6ProtocolNumber
rules[index].Filter.CheckProtocol = true
rules[index].Target = target
ipt.ReplaceTable(stack.MangleID, table, true)

@Lanius-collaris Lanius-collaris Aug 26, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried bumping gvisor for my gvisor-playground, found that new gvisor requires ForceReplaceTable() to work. All rules in iptables become useless if shouldSkipOrPopulateTables() returns true……

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ignoramous ignoramous Aug 28, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying, for the current changes to work, firestack would have to be pinned to its current gvisor@go version v0.0.0-20250816201027-ba3b9ca85f20?

firestack/go.mod

Line 27 in 96bf8e8

gvisor.dev/gvisor v0.0.0-20250816201027-ba3b9ca85f20

(I never really got the hang of the gvisor/netstack internals at all...)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Lanius-collaris Lanius-collaris Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried bumping gvisor for my gvisor-playground, found that new gvisor requires ForceReplaceTable() to work. All rules in iptables become useless if shouldSkipOrPopulateTables() returns true……

Are you saying, for the current changes to work, firestack would have to be pinned to its current gvisor@go version v0.0.0-20250816201027-ba3b9ca85f20?

I mean that shouldSkipOrPopulateTables() return true ( https://github.com/google/gvisor/blob/fd370915f22e/pkg/tcpip/stack/iptables.go#L315 in some cases gvisor thinks modified iptables are not modified ) so 2cc55a2 doesn't work, but IPTables.ForceReplaceTable() solves this problem, IPTables.ReplaceTable() in gvisor v0.0.0-20231023213702-2691a8f9b1cf ( used by my gvisor-playground ) always works.

The comment about gvisor v0.0.0-20250816201027-ba3b9ca85f20 means that firestack's handler is not called after stack.SetTransportProtocolHandler(icmp.ProtocolNumber6, …)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Lanius-collaris added 2 commits August 27, 2025 12:55
@Lanius-collaris
Merge branch 'celzero:n2' into icmp-hack
de2a7f2
@Lanius-collaris
netstack/icmp.go: Use ForceReplaceTable() to update iptables and simp…
eff90d9
…lify icmpForwarder.reply4() and icmpForwarder.reply6()
@Lanius-collaris
Lanius-collaris marked this pull request as ready for review August 27, 2025 05:06
github-advanced-security[bot]
github-advanced-security AI found potential problems Aug 27, 2025
View reviewed changes
Comment thread intra/netstack/icmp.go Fixed

Uh oh!

There was an error while loading. Please reload this page.

@Lanius-collaris
Merge branch 'celzero:n2' into icmp-hack
212044f
@Lanius-collaris Lanius-collaris mentioned this pull request Aug 27, 2025
icmp: fix reply4() #183
Merged
@ignoramous

ignoramous commented Aug 28, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Can we create a bool icmp6IPtablesHack (or if you can think of a better name), which when set to true uses these changes, but otherwise falls back to running existing code? If that's too much work, I can take it up, too.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Lanius-collaris

Lanius-collaris commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

Can we create a bool icmp6IPtablesHack (or if you can think of a better name), which when set to true uses these changes, but otherwise falls back to running existing code? If that's too much work, I can take it up, too.

Even if gvisor changes the behavior ( in pkg/tcpip/network/ipv6/icmp.go and pkg/tcpip/network/ipv6/ipv6.go ), you still need to recompile firestack, and it's very easy to remove ICMPHackTarget, so I think a new option is not needed.

I will leave the maintenance to you.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ignoramous

ignoramous commented Aug 28, 2025

Copy link
Copy Markdown
Contributor

Gotcha.

Even if gvisor changes the behavior ( in pkg/tcpip/network/ipv6/icmp.go and pkg/tcpip/network/ipv6/ipv6.go ), you still need to recompile firestack

Recompiling firestack is no big deal? Each commit batch has a compiled artifact pushed to GitHub Packages and Maven Central... and we've managed to upgrade the gvisor@go module from upstream without much fanfare (at least until now).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Lanius-collaris

Lanius-collaris commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

Recompiling firestack is no big deal? Each commit batch has a compiled artifact pushed to GitHub Packages and Maven Central... and we've managed to upgrade the gvisor@go module from upstream without much fanfare (at least until now).

I means rethink app can't call settings.XXXX() to use stack.SetTransportProtocolHandler(icmp.ProtocolNumber6, …) for ICMPv6 without recompiling, do you want to keep two implementations?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Lanius-collaris added 3 commits August 30, 2025 04:27
@Lanius-collaris
Merge branch 'celzero:n2' into icmp-hack
92b44ef
@Lanius-collaris
icmp: make github-advanced-security bot happy
3788d23
@Lanius-collaris
icmp: make bot happy
7097a63
ignoramous
ignoramous approved these changes Dec 25, 2025
View reviewed changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments
@ignoramous ignoramous ignoramous approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@Lanius-collaris @ignoramous @kevinGC @github-advanced-security
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.