Add icmp forwarder#597
Conversation
2eaf5ba to
f489345
Compare
f489345 to
96a70cf
Compare
|
There are some files to remove from the
113b50a has a variant of the ping test which passes with current |
96a70cf to
bcf6cfa
Compare
|
@cfergeau Mentioned that this changes not working properly on linux, need to address that. |
| localAddress := r.ID().LocalAddress | ||
|
|
||
| // Skip forwarding for addresses that should be handled locally | ||
| if header.IsV4LoopbackAddress(localAddress) || localAddress == header.IPv4Broadcast { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
is
header.IPv4Broadcast192.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)
}
| func createICMPConnection() (*netIcmp.PacketConn, error) { | ||
| var network string | ||
| if runtime.GOOS == "windows" { | ||
| // Windows requires privileged raw sockets (ip4:icmp) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Does IcmpSendEcho2() require privileges?
https://learn.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho2
There was a problem hiding this comment.
It should not trigger UAC on windows.
You bind the socket to a random ID here (on Linux), so the ID in the ICMP echo reply is likely different. |
bcf6cfa to
5aa57c7
Compare
|
Tested successfully on MacBook Pro M3 Pro, |
|
@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. |
4958b63 to
2cf9909
Compare
2cf9909 to
cf48878
Compare
|
@evidolob I tried running the testsuite again, and couldn't reproduce the error. |
ed29efe to
5416ae0
Compare
0f04850 to
dbe049e
Compare
a4a0115 to
5f40c1d
Compare
cfergeau
left a comment
There was a problem hiding this comment.
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 ?
| cmd := exec.Command("..\\tools\\bin\\gxz.exe", "-d", "-c", src) | ||
| stdOut, err := cmd.StdoutPipe() | ||
| if err != nil { | ||
| return err |
There was a problem hiding this comment.
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)
}
eea0795 to
ca1ca5e
Compare
75e0137 to
8905967
Compare
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>
8905967 to
c4ab5ba
Compare
|
/lgtm |
|
[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 DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
df2e0d8
into
containers:main
Resolves: #428