summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-02-16 00:41:11 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2021-09-21 20:07:55 +0200
commit2709c3027cc2d21fa43e285a60fa3aa0b74f9e50 (patch)
treee1593d1c8bc743e6f7ab23da8c68745485318ae9 /pkg/tcpip
parent9ed2c54502009fb4b1c7179214a031c12518dfed (diff)
WIP gre testgre-master
and wg_tunnel sample
Diffstat (limited to 'pkg/tcpip')
-rw-r--r--pkg/tcpip/sample/tun_tcp_connect/main.go77
-rw-r--r--pkg/tcpip/sample/wg_tunnel/config.yaml116
-rw-r--r--pkg/tcpip/sample/wg_tunnel/gobgp/main.go119
-rw-r--r--pkg/tcpip/sample/wg_tunnel/test/main.go66
4 files changed, 366 insertions, 12 deletions
diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go
index 05b879543..2bbb7ffcc 100644
--- a/pkg/tcpip/sample/tun_tcp_connect/main.go
+++ b/pkg/tcpip/sample/tun_tcp_connect/main.go
@@ -57,8 +57,11 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/link/rawfile"
"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
"gvisor.dev/gvisor/pkg/tcpip/link/tun"
+ "gvisor.dev/gvisor/pkg/tcpip/link/tunnel"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
+ "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"gvisor.dev/gvisor/pkg/tcpip/stack"
+ "gvisor.dev/gvisor/pkg/tcpip/transport/gre"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -89,9 +92,29 @@ func writer(ch chan struct{}, ep tcpip.Endpoint) {
}
}
+func parseIP(s string) tcpip.Address {
+ addr := tcpip.Address(net.ParseIP(s))
+ ip4addr := addr.To4(); if ip4addr != "" {
+ return ip4addr
+ } else {
+ return addr
+ }
+}
+
+func addAddress(s *stack.Stack, id tcpip.NICID, addr tcpip.Address) *tcpip.Error {
+ var proto tcpip.NetworkProtocolNumber
+ if addr.To4() == "" {
+ proto = ipv6.ProtocolNumber
+ } else {
+ proto = ipv4.ProtocolNumber
+ }
+
+ return s.AddAddress(id, proto, addr)
+}
+
func main() {
- if len(os.Args) != 6 {
- log.Fatal("Usage: ", os.Args[0], " <tun-device> <local-ipv4-address> <local-port> <remote-ipv4-address> <remote-port>")
+ if len(os.Args) != 8 {
+ log.Fatal("Usage: ", os.Args[0], " <tun-device> <local-ipv4-address> <local-port> <remote-ipv4-address> <remote-port> <local-gre-address> <remote-gre-address>")
}
tunName := os.Args[1]
@@ -99,15 +122,21 @@ func main() {
portName := os.Args[3]
remoteAddrName := os.Args[4]
remotePortName := os.Args[5]
+ greAddrName := os.Args[6]
+ greRemoteAddrName := os.Args[7]
rand.Seed(time.Now().UnixNano())
- addr := tcpip.Address(net.ParseIP(addrName).To4())
+ addr := parseIP(addrName)
+ greAddr := parseIP(greAddrName)
+ greRemoteAddr := parseIP(greRemoteAddrName)
remote := tcpip.FullAddress{
- NIC: 1,
- Addr: tcpip.Address(net.ParseIP(remoteAddrName).To4()),
+ NIC: 0,
+ Addr: parseIP(remoteAddrName),
}
+ log.Printf("local:%v remote:%v", addr, remote)
+
var localPort uint16
if v, err := strconv.Atoi(portName); err != nil {
log.Fatalf("Unable to convert port %v: %v", portName, err)
@@ -124,8 +153,8 @@ func main() {
// Create the stack with ipv4 and tcp protocols, then add a tun-based
// NIC and ipv4 address.
s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
- TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
+ NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
+ TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, gre.NewProtocol},
})
mtu, err := rawfile.GetMTU(tunName)
@@ -146,21 +175,42 @@ func main() {
log.Fatal(err)
}
- protocolAddr := tcpip.ProtocolAddress{
- Protocol: ipv4.ProtocolNumber,
- AddressWithPrefix: addr.WithPrefix(),
+ if err := addAddress(s, 1, greAddr); err != nil {
+ log.Fatal(err)
+ }
+
+ greEP := tunnel.New(mtu - 24)
+ if err := s.CreateNIC(2, sniffer.New(greEP)); err != nil {
+ log.Fatal(err)
}
- if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
- log.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
+ if err := addAddress(s, 2, addr); err != nil {
+ log.Fatal(err)
}
// Add default route.
+ subnet, err := tcpip.NewSubnet(
+ tcpip.Address(parseIP("10.0.0.0")),
+ tcpip.AddressMask(parseIP("255.255.255.0")))
+ if err != nil {
+ panic(err)
+ }
s.SetRouteTable([]tcpip.Route{
{
+ Destination: subnet,
+ NIC: 1,
+ },
+ {
Destination: header.IPv4EmptySubnet,
+ NIC: 2,
+ },
+ {
+ Destination: header.IPv6EmptySubnet,
NIC: 1,
},
})
+ log.Printf("Nics enabled 1:%v 2:%v 3:%v", s.CheckNIC(1), s.CheckNIC(2), s.CheckNIC(3))
+
+ greEP.Start(s, &greAddr, &greRemoteAddr)
// Create TCP endpoint.
var wq waiter.Queue
@@ -193,6 +243,9 @@ func main() {
fmt.Println("Connected")
+ payload := tcpip.SlicePayload([]byte("GET / HTTP/1.0\r\nHost: www.m7n.se\r\n\r\n"))
+ ep.Write(payload, tcpip.WriteOptions{})
+
// Start the writer in its own goroutine.
writerCompletedCh := make(chan struct{})
go writer(writerCompletedCh, ep) // S/R-SAFE: sample code.
diff --git a/pkg/tcpip/sample/wg_tunnel/config.yaml b/pkg/tcpip/sample/wg_tunnel/config.yaml
new file mode 100644
index 000000000..7a0c250dc
--- /dev/null
+++ b/pkg/tcpip/sample/wg_tunnel/config.yaml
@@ -0,0 +1,116 @@
+network:
+ version: 2
+ renderer: gvisor
+ ethernets:
+ lo:
+ addresses:
+ - 127.0.0.1/8
+ - ::1/128
+ - 10.1.0.1/24
+ - 2001:470:de6f:5310::1/64
+ routes:
+ - to: 10.1.15.0/24
+ - to: 2001:470:de6f:531f::/64
+ tuntaps:
+ tun:
+ name: tun1
+ mode: tun
+ mtu: 1280
+# fd: 0
+# name: tap1
+# mode: tap
+ addresses:
+ - 10.1.1.2/24
+ - 2001:470:de6f:5311::2/64
+ nameservers:
+ addresses:
+ - 8.8.8.8
+ - 8.8.4.4
+# routes:
+# - to: 0.0.0.0/0
+# via: 10.1.1.1
+# metric: 200
+# - to: ::/0
+# via: 2001:470:de6f:5311::1
+# metric: 200
+ macaddress: aa:00:01:01:02:01
+
+ tunnels:
+ tun1:
+ mode: udp
+ local: 0.0.0.0:10002
+ remote: 127.0.0.1:10001
+ #FIXME detect MTU
+ mtu: 1280 #1500
+ addresses:
+ - 10.1.2.1/24
+ - 2001:470:de6f:5312::1/64
+ routes:
+# - to: 0.0.0.0/0
+# via: 10.1.2.2
+# metric: 100
+# - to: ::/0
+# via: 2001:470:de6f:5312::2
+# metric: 100
+ macaddress: aa:00:01:01:02:02
+
+ wireguards:
+# wg1:
+# name: wg1
+# addresses:
+# - 10.1.3.2/24
+# - 2001:470:de6f:5313::2/64
+# listen_port: 51820
+# private_key: cCBLRrAKF0oqLua2IGYr6ngQRLdgCSTa8hzDLQvezUI=
+# peers:
+# - public_key: igb6I+JFOEXPN4JjZvSslxNDPQK1/Ofi6310RzH2HAk=
+# endpoint: 10.49.50.1:51820
+# allowed_ips:
+# - 10.1.2.3/32
+# - 0.0.0.0/0
+# - ::/0
+# # persistent_keepalive: 3600
+# nameservers:
+# addresses:
+# - 8.8.8.8
+# - 8.8.4.4
+# routes:
+# - to: 0.0.0.0/0
+# via: 10.1.3.1
+# metric: 100
+# mark: 1
+# mask: 255
+# - to: ::/0
+# via: 2001:470:de6f:5313::1
+# metric: 100
+# mark: 1
+# mask: 255
+# macaddress: aa:00:01:01:02:03
+
+ wg2:
+ name: wg2
+ addresses:
+ - 10.49.124.111/32
+ - 2001:470:dfae:6300::111/128
+ - 2001:470:dfae:6300::1:111/128
+ - fe80::111/64
+ listen_port: 51820
+ private_key: cCBLRrAKF0oqLua2IGYr6ngQRLdgCSTa8hzDLQvezUI=
+ peers:
+ - public_key: 5Q5KIFIeskMh/QanwH9/5lHQ9NhWBsY16kwaS0ELQyg=
+ endpoint: 10.49.50.215:51820
+ allowed_ips:
+ - 2001:470:dfae:6300::1:3/128
+ - ::/0
+ - 0.0.0.0/0
+ persistent_keepalive: 3600
+ nameservers:
+ addresses:
+ - 8.8.8.8
+ - 8.8.4.4
+ routes:
+ - to: 10.49.124.0/24
+ - to: 0.0.0.0/0
+ - to: ::/0
+ - to: 2001:470:dfae:6300::/64
+ macaddress: aa:00:01:01:02:04
diff --git a/pkg/tcpip/sample/wg_tunnel/gobgp/main.go b/pkg/tcpip/sample/wg_tunnel/gobgp/main.go
new file mode 100644
index 000000000..3f51adc69
--- /dev/null
+++ b/pkg/tcpip/sample/wg_tunnel/gobgp/main.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ "context"
+ "time"
+
+ "github.com/golang/protobuf/ptypes"
+ "github.com/golang/protobuf/ptypes/any"
+ api "github.com/osrg/gobgp/api"
+ gobgp "github.com/osrg/gobgp/pkg/server"
+ log "github.com/sirupsen/logrus"
+)
+
+func main() {
+ log.SetLevel(log.DebugLevel)
+ s := gobgp.NewBgpServer()
+ go s.Serve()
+
+ // global configuration
+ if err := s.StartBgp(context.Background(), &api.StartBgpRequest{
+ Global: &api.Global{
+ As: 65003,
+ RouterId: "10.0.255.254",
+ ListenPort: -1, // gobgp won't listen on tcp:179
+ },
+ }); err != nil {
+ log.Fatal(err)
+ }
+
+ // monitor the change of the peer state
+ if err := s.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(p *api.Peer) { log.Info(p) }); err != nil {
+ log.Fatal(err)
+ }
+
+ // neighbor configuration
+ n := &api.Peer{
+ Conf: &api.PeerConf{
+ NeighborAddress: "172.17.0.2",
+ PeerAs: 65002,
+ },
+ }
+
+ if err := s.AddPeer(context.Background(), &api.AddPeerRequest{
+ Peer: n,
+ }); err != nil {
+ log.Fatal(err)
+ }
+
+ // add routes
+ nlri, _ := ptypes.MarshalAny(&api.IPAddressPrefix{
+ Prefix: "10.0.0.0",
+ PrefixLen: 24,
+ })
+
+ a1, _ := ptypes.MarshalAny(&api.OriginAttribute{
+ Origin: 0,
+ })
+ a2, _ := ptypes.MarshalAny(&api.NextHopAttribute{
+ NextHop: "10.0.0.1",
+ })
+ a3, _ := ptypes.MarshalAny(&api.AsPathAttribute{
+ Segments: []*api.AsSegment{
+ {
+ Type: 2,
+ Numbers: []uint32{6762, 39919, 65000, 35753, 65000},
+ },
+ },
+ })
+ attrs := []*any.Any{a1, a2, a3}
+
+ _, err := s.AddPath(context.Background(), &api.AddPathRequest{
+ Path: &api.Path{
+ Family: &api.Family{Afi: api.Family_AFI_IP, Safi: api.Family_SAFI_UNICAST},
+ Nlri: nlri,
+ Pattrs: attrs,
+ },
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ v6Family := &api.Family{
+ Afi: api.Family_AFI_IP6,
+ Safi: api.Family_SAFI_UNICAST,
+ }
+
+ // add v6 route
+ nlri, _ = ptypes.MarshalAny(&api.IPAddressPrefix{
+ PrefixLen: 64,
+ Prefix: "2001:db8:1::",
+ })
+ v6Attrs, _ := ptypes.MarshalAny(&api.MpReachNLRIAttribute{
+ Family: v6Family,
+ NextHops: []string{"2001:db8::1"},
+ Nlris: []*any.Any{nlri},
+ })
+
+ c, _ := ptypes.MarshalAny(&api.CommunitiesAttribute{
+ Communities: []uint32{100, 200},
+ })
+
+ _, err = s.AddPath(context.Background(), &api.AddPathRequest{
+ Path: &api.Path{
+ Family: v6Family,
+ Nlri: nlri,
+ Pattrs: []*any.Any{a1, v6Attrs, c},
+ },
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ s.ListPath(context.Background(), &api.ListPathRequest{Family: v6Family}, func(p *api.Destination) {
+ log.Info(p)
+ })
+
+ // do something useful here instead of exiting
+ time.Sleep(time.Minute * 3)
+}
diff --git a/pkg/tcpip/sample/wg_tunnel/test/main.go b/pkg/tcpip/sample/wg_tunnel/test/main.go
new file mode 100644
index 000000000..5373ca840
--- /dev/null
+++ b/pkg/tcpip/sample/wg_tunnel/test/main.go
@@ -0,0 +1,66 @@
+package main
+
+import (
+ "fmt"
+ "log"
+ "net"
+ "runtime"
+ "syscall"
+ "time"
+)
+
+func CheckError(err error) {
+ if err != nil {
+ log.Fatal("Error: " , err)
+ }
+}
+
+func TestFinalize(conn *net.UDPConn) {
+ event := make(chan string)
+
+ runtime.SetFinalizer(conn, func (obj *net.UDPConn) {
+ fmt.Println("Finalize: UDPConn", obj.LocalAddr(), obj.RemoteAddr())
+ event <- "Finalize UDPConn"
+ })
+
+ runtime.GC()
+
+ select {
+ case res := <-event:
+ fmt.Println(res)
+ case <-time.After(2 * time.Second):
+ fmt.Println("No finalize")
+ }
+}
+
+func test() {
+ ServerAddr,err := net.ResolveUDPAddr("udp", "127.0.0.1:10001")
+ CheckError(err)
+
+ LocalAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:10002")
+ CheckError(err)
+
+ conn, err := net.DialUDP("udp", LocalAddr, ServerAddr)
+ CheckError(err)
+
+ runtime.KeepAlive(conn)
+
+ sd, err := conn.File()
+ CheckError(err)
+
+ TestFinalize(conn)
+
+ var fd int
+ fd = int(sd.Fd())
+
+ syscall.SetNonblock(fd, true)
+
+ // conn.Write([]byte("HelloWorld!"))
+ //_, err = sd.Write([]byte("HelloWorld!"))
+ _, err = syscall.Write(fd, []byte("HelloWorld!"))
+ CheckError(err)
+}
+
+func main() {
+ test()
+}