Skip to content

Add icmp forwarder#597

Merged
openshift-merge-bot[bot] merged 7 commits intocontainers:mainfrom
evidolob:add-icmp-forwarder
Apr 16, 2026
Merged

Add icmp forwarder#597
openshift-merge-bot[bot] merged 7 commits intocontainers:mainfrom
evidolob:add-icmp-forwarder

Conversation

@evidolob
Copy link
Copy Markdown
Collaborator

Resolves: #428

@cfergeau
Copy link
Copy Markdown
Collaborator

There are some files to remove from the update gvisor commit

 .idea/gvisor-tap-vsock.iml                                                               |   4 +
 .idea/workspace.xml                                                                      | 130 +++++++++++++++++++
 bin/gvforwarder                                                                          | Bin 0 -> 5767352 bytes
 bin/gvproxy                                                                              | Bin 0 -> 12132674 bytes
 bin/qemu-wrapper                                                                         | Bin 0 -> 2339538 bytes

go mod tidy is missing in the final commit, I would squash the vendoring of x/net in this commit as well.

113b50a has a variant of the ping test which passes with current main branch (with a FIXME), this could replace the commit in the PR, and you’d change the test in the final commit (but that’s not a requirement, we can keep the code as it currently is)

@evidolob
Copy link
Copy Markdown
Collaborator Author

@cfergeau Mentioned that this changes not working properly on linux, need to address that.
The error is:

WARN[0020] ICMP reply ID/Seq mismatch: got ID=55409 Seq=1, expected ID=1 Seq=1 

Comment thread pkg/services/forwarder/icmp.go Outdated
localAddress := r.ID().LocalAddress

// Skip forwarding for addresses that should be handled locally
if header.IsV4LoopbackAddress(localAddress) || localAddress == header.IPv4Broadcast {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is header.IPv4Broadcast 192.168.127.255? I believe broadcast ping falls in the "privileged" operations that we don’t support?
Maybe we should add this special case to the test case?

Copy link
Copy Markdown

@Lanius-collaris Lanius-collaris Jan 17, 2026

Choose a reason for hiding this comment

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

is header.IPv4Broadcast 192.168.127.255?

header.IPv4Broadcast == tcpip.AddrFrom4([4]byte{0xff, 0xff, 0xff, 0xff})
https://pkg.go.dev/gvisor.dev/gvisor@v0.0.0-20260117033839-509480e92861/pkg/tcpip/header#IPv4Broadcast

On Linux setting SO_BROADCAST option doesn't require privileges, but some users may want these broadcast packets to be forwarded to other VMs in the same subnet.

package main

import (
	"fmt"
	"net"
	"os"
	"syscall"
)

func p(e error) {
	if e != nil {
		panic(e)
	}
}
func FdToUDPConn(fd int) *net.UDPConn {
	defer syscall.Close(fd)
	conn, _ := net.FilePacketConn(os.NewFile(uintptr(fd), ""))
	return conn.(*net.UDPConn)
}
func main() {
	dstStr := "192.168.127.255"
	if len(os.Args) >= 2 {
		dstStr = os.Args[1]
	}
	dst := net.ParseIP(dstStr)
	if dst == nil {
		fmt.Printf("invalid IP %s\n", dstStr)
		return
	}

	fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_ICMP)
	p(err)
	laddr := syscall.SockaddrInet4{
		Port: 0,
		Addr: [4]byte{0, 0, 0, 0},
	}
	err = syscall.Bind(fd, &laddr)
	p(err)
	conn := FdToUDPConn(fd)
	defer conn.Close()

	raw, _ := conn.SyscallConn()
	raw.Control(func(t uintptr) {
		err = syscall.SetsockoptInt(int(t), syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
		p(err)
	})
	addr1 := net.UDPAddr{
		IP:   dst,
		Port: 0,
	}
	payload := [12]byte{
		8, 0, 0, 0,
		0, 0, 0, 0,
		0x68, 0x61, 0x68, 0x61,
	}
	_, err = conn.WriteTo(payload[:], &addr1)
	p(err)
}

Comment thread pkg/services/forwarder/icmp_packet.go Outdated
func createICMPConnection() (*netIcmp.PacketConn, error) {
var network string
if runtime.GOOS == "windows" {
// Windows requires privileged raw sockets (ip4:icmp)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does this mean on Windows we will get a UAC prompt when trying to use ping?
I see a few runtime.GOOS checks in this file, it might be worth removing the checks, and having constants/small helpers in icmp_unix.go and icmp_windows.go files.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It should not trigger UAC on windows.

Comment thread go.mod Outdated
Comment thread cmd/gvproxy/config.go
@Lanius-collaris
Copy link
Copy Markdown

Lanius-collaris commented Jan 17, 2026

Mentioned that this changes not working properly on linux, need to address that. The error is:

WARN[0020] ICMP reply ID/Seq mismatch: got ID=55409 Seq=1, expected ID=1 Seq=1 

You bind the socket to a random ID here (on Linux), so the ID in the ICMP echo reply is likely different.
https://github.com/evidolob/gvisor-tap-vsock/blob/bcf6cfa3116fc4fed8543736de0e3517eaa31301/pkg/services/forwarder/icmp_packet.go#L120
The ID here works like the local port of a UDP socket.

@redbeam
Copy link
Copy Markdown
Contributor

redbeam commented Jan 20, 2026

Tested successfully on MacBook Pro M3 Pro, macOS 15.7.2, podman 5.6.1, although the testsuite failed with this error:

• Failure [2.079 seconds]
ping with gvproxy and vfkit
/Users/mskvarla/gvisor-tap-vsock/test-vfkit/basic_test.go:106
  should succeed to ping a known IP [It]
  /Users/mskvarla/gvisor-tap-vsock/test-vfkit/basic_test.go:117

  Unexpected error:
      <*exec.ExitError | 0x140001946e0>: 
      exit status 1
      {
          ProcessState: {
              pid: 51347,
              status: 256,
              rusage: {
                  Utime: {
                      Sec: 0,
                      Usec: 6550,
                      Pad_cgo_0: [0, 0, 0, 0],
                  },
                  Stime: {
                      Sec: 0,
                      Usec: 2891,
                      Pad_cgo_0: [0, 0, 0, 0],
                  },
                  Maxrss: 4947968,
                  Ixrss: 0,
                  Idrss: 0,
                  Isrss: 0,
                  Minflt: 523,
                  Majflt: 1,
                  Nswap: 0,
                  Inblock: 0,
                  Oublock: 0,
                  Msgsnd: 17,
                  Msgrcv: 36,
                  Nsignals: 0,
                  Nvcsw: 14,
                  Nivcsw: 15,
              },
          },
          Stderr: [87, 97, 114, 110, 105, 110, 103, 58, 32, 80, 101, 114, 109, 97, 110, 101, 110, 116, 108, 121, 32, 97, 100, 100, 101, 100, 32, 39, 91, 49, 50, 55, 46, 48, 46, 48, 46, 49, 93, 58, 50, 50, 50, 51, 39, 32, 40, 69, 68, 50, 53, 53, 49, 57, 41, 32, 116, 111, 32, 116, 104, 101, 32, 108, 105, 115, 116, 32, 111, 102, 32, 107, 110, 111, 119, 110, 32, 104, 111, 115, 116, 115, 46, 13, 10],
      }
  occurred

@evidolob
Copy link
Copy Markdown
Collaborator Author

@redbeam Could you ensure that your mac has access to ip used in test? That error could be because your mac cannot reach to ip under test.

@redbeam
Copy link
Copy Markdown
Contributor

redbeam commented Feb 21, 2026

@evidolob I tried running the testsuite again, and couldn't reproduce the error.

@evidolob evidolob force-pushed the add-icmp-forwarder branch 4 times, most recently from ed29efe to 5416ae0 Compare February 24, 2026 13:14
@evidolob evidolob force-pushed the add-icmp-forwarder branch from 0f04850 to dbe049e Compare March 19, 2026 08:18
@evidolob evidolob force-pushed the add-icmp-forwarder branch 2 times, most recently from a4a0115 to 5f40c1d Compare April 10, 2026 11:41
Copy link
Copy Markdown
Collaborator

@cfergeau cfergeau left a comment

Choose a reason for hiding this comment

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

The Windows test adds a lot of code to this PR, I’d suggest to split it to its own PR so that we can focus on getting the ICMP PR merged ?

Comment thread test-utils/pull.go Outdated
cmd := exec.Command("..\\tools\\bin\\gxz.exe", "-d", "-c", src)
stdOut, err := cmd.StdoutPipe()
if err != nil {
return err
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Did you get a chance to try this change which should be more efficient:

diff --git a/test-utils/pull.go b/test-utils/pull.go
index 819c052e..9d4634c8 100644
--- a/test-utils/pull.go
+++ b/test-utils/pull.go
@@ -87,16 +87,8 @@ func Decompress(localPath string) (string, error) {
 // depends on xz: not pre-installed on mac, so it becomes a brew dependency
 func decompressXZ(src string, output io.Writer) error {
        cmd := exec.Command("xzcat", "-T0", "-k", src)
-       stdOut, err := cmd.StdoutPipe()
-       if err != nil {
-               return err
-       }
+       cmd.Stdout = output
        cmd.Stderr = os.Stderr
-       go func() {
-               if _, err := io.Copy(output, stdOut); err != nil {
-                       logrus.Error(err)
-               }
-       }()
        return cmd.Run()
 }

It would be better to share most of the code here as only the command is different if I’m not mistaken?

var cmd *exec.Cmd
if runtime.GOOS == "windows" {
		cmd = exec.Command("..\\tools\\bin\\gxz.exe", "-d", "-c", src)
else {
        cmd = exec.Command("xzcat", "-T0", "-k", src)
}

@evidolob evidolob force-pushed the add-icmp-forwarder branch 2 times, most recently from eea0795 to ca1ca5e Compare April 15, 2026 08:58
@evidolob evidolob force-pushed the add-icmp-forwarder branch 2 times, most recently from 75e0137 to 8905967 Compare April 15, 2026 11:29
@evidolob evidolob requested a review from cfergeau April 15, 2026 11:33
@evidolob evidolob mentioned this pull request Apr 15, 2026
@evidolob
Copy link
Copy Markdown
Collaborator Author

@cfergeau I split pr in to two, PR with tests here #641

cfergeau and others added 7 commits April 16, 2026 15:49
This will help verify containers#428 is really fixed.

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
Add .vscode and .idea ide/editor folders and few files created during test

Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
The current implementation supports forwarding only ICMP Echo(ping) packets, as OS not allow to send arbitrary packets without escalating privileges.  All other ICMP packets are dropped(ignored)

Changes in 'icmp_packet.go' and 'icmp.go' was mostly maded by cursor.

Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
- Added getExpectedReplyIdent function to handle ICMP echo identifier validation for Linux and Windows.
- Updated handlePingRequest to use the new function for validating echo replies.
- Add ping tests for qemu test suite

Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
As Azure and by extension Github Actions are not allowing to ping external domains,
we need to disable the ping tests for now.

Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
@cfergeau cfergeau force-pushed the add-icmp-forwarder branch from 8905967 to c4ab5ba Compare April 16, 2026 14:30
@cfergeau
Copy link
Copy Markdown
Collaborator

/lgtm
/approve

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 16, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cfergeau, evidolob

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit df2e0d8 into containers:main Apr 16, 2026
24 of 27 checks passed
@github-project-automation github-project-automation bot moved this from Ready for review to Done in Project planning: crc Apr 16, 2026
@evidolob evidolob deleted the add-icmp-forwarder branch April 17, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICMP limitation

6 participants