summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/link/gre/gre.go
blob: 04f8f8da7bb6a57a2b57519ae888e81a65ffb91b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package gre

import (
        "math"
        "net"
	"log"
        "os"

	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
	"gvisor.dev/gvisor/pkg/tcpip/transport/raw"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/waiter"
)

var SIZE = 16

type Endpoint struct {
	channel.Endpoint
}

type writer Endpoint

func New(mtu uint32) *Endpoint{
	var linkAddress tcpip.LinkAddress

	ch := channel.New(SIZE, mtu, linkAddress)
	return &Endpoint{
		Endpoint: *ch,
	}
}

func (e *Endpoint) GetChannel() *channel.Endpoint {
        return &e.Endpoint
}

func (e *Endpoint) Bind(s *stack.Stack, laddr tcpip.FullAddress) {
        log.Println("Bind begin")

	// Create TCP endpoint.
	var wq waiter.Queue
	ep, err := raw.NewEndpoint(s, ipv4.ProtocolNumber, header.GREProtocolNumber, &wq)
	if err != nil {
		log.Fatal(err)
	}
        log.Println("EP: %s", ep)

        raddr := tcpip.FullAddress{NIC: 1, Addr: tcpip.Address(net.ParseIP("10.0.0.1"))}
        log.Println("Remote:", raddr.Addr, raddr)

        if err := ep.Bind(tcpip.FullAddress{1, "", 0}); err != nil {
                log.Fatal("Bind failed: ", err)
        }

        // if err := ep.Connect(raddr); err != nil {
        //         log.Fatal("Connect failed: ", err)
        // }
                
	// Issue connect request and wait for it to complete.
	waitEntry, notifyCh := waiter.NewChannelEntry(nil)

	// Read data and write to standard output until the peer closes the
	// connection from its side.
	wq.EventRegister(&waitEntry, waiter.EventIn)
	for {
		_, err := ep.Read(os.Stdout, math.MaxUint16, tcpip.ReadOptions{})
		if err != nil {
			if err == tcpip.ErrClosedForReceive {
				break
			}

			if err == tcpip.ErrWouldBlock {
				<-notifyCh
				continue
			}

			log.Fatal("Read() failed:", err)
		}
	}
	wq.EventUnregister(&waitEntry)
        log.Println("Bind end")
}

// Attach saves the stack network-layer dispatcher for use later when packets
// are injected.
func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) {
        log.Println("GRE: Attach")

	e.Endpoint.Attach(dispatcher)
}