From 9ff81925ffcb1833871a409c4bc004144062ae22 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 18 Mar 2020 21:00:32 +0100 Subject: WIP create wireguard link package --- pkg/tcpip/link/wireguard/gtun.go | 135 +++++++++++++++++++++++++++++++++++++ pkg/tcpip/sample/wg_tunnel/gtun.go | 135 ------------------------------------- pkg/tcpip/sample/wg_tunnel/main.go | 5 +- 3 files changed, 138 insertions(+), 137 deletions(-) create mode 100644 pkg/tcpip/link/wireguard/gtun.go delete mode 100644 pkg/tcpip/sample/wg_tunnel/gtun.go diff --git a/pkg/tcpip/link/wireguard/gtun.go b/pkg/tcpip/link/wireguard/gtun.go new file mode 100644 index 000000000..d533ca5ba --- /dev/null +++ b/pkg/tcpip/link/wireguard/gtun.go @@ -0,0 +1,135 @@ +package wireguard + +import ( + "context" + "fmt" + "os" + + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/buffer" + "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/pkg/tcpip/link/channel" + "gvisor.dev/gvisor/pkg/tcpip/stack" + wgtun "golang.zx2c4.com/wireguard/tun" +) + +type WgTun struct { + events chan wgtun.Event + ch *channel.Endpoint + stack *stack.Stack + ctx context.Context + cancel context.CancelFunc +} + +func (tun *WgTun) File() *os.File { + fmt.Println("File") + return nil +} + +func (tun *WgTun) Read(buff []byte, offset int) (int, error) { + fmt.Println("Read ", len(buff), offset) + + p, ok := tun.ch.ReadContext(tun.ctx) + if ok == false { + fmt.Println("Read error") + return 0, nil // FIXME error + } + vv := p.Pkt.Data + v := vv.ToView() + h := p.Pkt.Header.View() + fmt.Println("Read packet", vv.Size(), len(v), len(h), h) + + if len(buff) - offset < len(h) + len(v) { + fmt.Println("Short buffer") + return 0, nil // FIXME error + } + + copy(buff[offset:], h) + copy(buff[offset+len(h):], v) + return len(h)+len(v), nil +} + +func versionToProtocol(version int) tcpip.NetworkProtocolNumber { + switch version { + case header.IPv4Version: return header.IPv4ProtocolNumber + case header.IPv6Version: return header.IPv6ProtocolNumber + } + + return 0 +} + +func (tun *WgTun) Write(buff []byte, offset int) (int, error) { + size := len(buff) - offset + fmt.Println("Write ", len(buff), offset, size) + + if size < 1 { + return 0, nil // FIXME error + } + + buffSlice := buff[offset : offset+size] + + pkt := tcpip.PacketBuffer{ + Data: buffer.NewViewFromBytes(buffSlice).ToVectorisedView(), + } + //version := buff[offset] & 0x0f + protocol := versionToProtocol(header.IPVersion(buffSlice)) + netProto := tun.stack.NetworkProtocolInstance(protocol) + if netProto == nil { + fmt.Println("Write not ok") + return 0, nil + } + src, dst := netProto.ParseAddresses(pkt.Data.First()) + fmt.Println("Write ", src, dst) + // TODO change destination address + tun.ch.InjectInbound(protocol, pkt) // FIXME detect protocol number + + return size, nil +} + +func (tun *WgTun) Flush() error { + // TODO: can flushing be implemented by buffering and using sendmmsg? + fmt.Println("Flush") + return nil +} + +func (tun *WgTun) MTU() (int, error) { + fmt.Println("MTU") + return 1280, nil +} + +func (tun *WgTun) Name() (string, error) { + fmt.Println("Name") + return "foobar", nil +} + +func (tun *WgTun) Events() chan wgtun.Event { + fmt.Println("Events") + return tun.events +} + +func (tun *WgTun) Close() error { + fmt.Println("Close") + // TODO +// tun.cancel() + return nil +} + +func CreateWgTun(s *stack.Stack, ch *channel.Endpoint) (wgtun.Device, error) { + size := 16 + ctx, cancel := context.WithCancel(context.Background()) + tun := &WgTun{ + ch: ch, + events: make(chan wgtun.Event, size), + stack: s, + ctx: ctx, + cancel: cancel, + } + +// go func() { + fmt.Println("Post event") + tun.events <- wgtun.EventUp + fmt.Println("Posted event") +// }() + + return tun, nil +} diff --git a/pkg/tcpip/sample/wg_tunnel/gtun.go b/pkg/tcpip/sample/wg_tunnel/gtun.go deleted file mode 100644 index d641fc42d..000000000 --- a/pkg/tcpip/sample/wg_tunnel/gtun.go +++ /dev/null @@ -1,135 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" - "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/channel" - "gvisor.dev/gvisor/pkg/tcpip/stack" - wgtun "golang.zx2c4.com/wireguard/tun" -) - -type GoTun struct { - events chan wgtun.Event - ch *channel.Endpoint - stack *stack.Stack - ctx context.Context - cancel context.CancelFunc -} - -func (tun *GoTun) File() *os.File { - fmt.Println("File") - return nil -} - -func (tun *GoTun) Read(buff []byte, offset int) (int, error) { - fmt.Println("Read ", len(buff), offset) - - p, ok := tun.ch.ReadContext(tun.ctx) - if ok == false { - fmt.Println("Read error") - return 0, nil // FIXME error - } - vv := p.Pkt.Data - v := vv.ToView() - h := p.Pkt.Header.View() - fmt.Println("Read packet", vv.Size(), len(v), len(h), h) - - if len(buff) - offset < len(h) + len(v) { - fmt.Println("Short buffer") - return 0, nil // FIXME error - } - - copy(buff[offset:], h) - copy(buff[offset+len(h):], v) - return len(h)+len(v), nil -} - -func versionToProtocol(version int) tcpip.NetworkProtocolNumber { - switch version { - case header.IPv4Version: return header.IPv4ProtocolNumber - case header.IPv6Version: return header.IPv6ProtocolNumber - } - - return 0 -} - -func (tun *GoTun) Write(buff []byte, offset int) (int, error) { - size := len(buff) - offset - fmt.Println("Write ", len(buff), offset, size) - - if size < 1 { - return 0, nil // FIXME error - } - - buffSlice := buff[offset : offset+size] - - pkt := tcpip.PacketBuffer{ - Data: buffer.NewViewFromBytes(buffSlice).ToVectorisedView(), - } - //version := buff[offset] & 0x0f - protocol := versionToProtocol(header.IPVersion(buffSlice)) - netProto := tun.stack.NetworkProtocolInstance(protocol) - if netProto == nil { - fmt.Println("Write not ok") - return 0, nil - } - src, dst := netProto.ParseAddresses(pkt.Data.First()) - fmt.Println("Write ", src, dst) - // TODO change destination address - tun.ch.InjectInbound(protocol, pkt) // FIXME detect protocol number - - return size, nil -} - -func (tun *GoTun) Flush() error { - // TODO: can flushing be implemented by buffering and using sendmmsg? - fmt.Println("Flush") - return nil -} - -func (tun *GoTun) MTU() (int, error) { - fmt.Println("MTU") - return 1280, nil -} - -func (tun *GoTun) Name() (string, error) { - fmt.Println("Name") - return "foobar", nil -} - -func (tun *GoTun) Events() chan wgtun.Event { - fmt.Println("Events") - return tun.events -} - -func (tun *GoTun) Close() error { - fmt.Println("Close") - // TODO -// tun.cancel() - return nil -} - -func CreateGoTun(s *stack.Stack, ch *channel.Endpoint) (wgtun.Device, error) { - size := 16 - ctx, cancel := context.WithCancel(context.Background()) - tun := &GoTun{ - ch: ch, - events: make(chan wgtun.Event, size), - stack: s, - ctx: ctx, - cancel: cancel, - } - -// go func() { - fmt.Println("Post event") - tun.events <- wgtun.EventUp - fmt.Println("Posted event") -// }() - - return tun, nil -} diff --git a/pkg/tcpip/sample/wg_tunnel/main.go b/pkg/tcpip/sample/wg_tunnel/main.go index b859dff7a..1c87a09c2 100644 --- a/pkg/tcpip/sample/wg_tunnel/main.go +++ b/pkg/tcpip/sample/wg_tunnel/main.go @@ -44,6 +44,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/link/loopback" "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/tun" + "gvisor.dev/gvisor/pkg/tcpip/link/wireguard" "gvisor.dev/gvisor/pkg/tcpip/network/arp" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" @@ -295,9 +296,9 @@ func addWgLink(s *stack.Stack, nic tcpip.NICID, interfaceName string, addr tcpip //mtu := 1500 // tun, err := wg_tun.CreateTUN(interfaceName, mtu) - tun, err := CreateGoTun(s, ep) + tun, err := wireguard.CreateWgTun(s, ep) if err != nil { - log.Fatal("CreateGoTun", err) + log.Fatal("CreateWgTun", err) } -- cgit v1.2.3