-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathogo.go
104 lines (89 loc) · 2.18 KB
/
ogo.go
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
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"fmt"
"net"
"runtime"
"sync"
"github.com/jonstout/ogo/core"
"github.com/jonstout/ogo/protocol/ofp10"
)
// Structure to track hosts that we discover.
type Host struct {
mac net.HardwareAddr
port uint16
}
// A thread safe map to store our hosts.
type HostMap struct {
hosts map[string]Host
sync.RWMutex
}
func NewHostMap() *HostMap {
h := new(HostMap)
h.hosts = make(map[string]Host)
return h
}
// Returns the host associated with mac.
func (m *HostMap) Host(mac net.HardwareAddr) (h Host, ok bool) {
m.RLock()
defer m.RUnlock()
h, ok = m.hosts[mac.String()]
return
}
// Records the host mac address and the port where mac was discovered.
func (m *HostMap) SetHost(mac net.HardwareAddr, port uint16) {
m.Lock()
defer m.Unlock()
m.hosts[mac.String()] = Host{mac, port}
}
var hostMap HostMap
// Returns a new instance that implements one of the many
// interfaces found in ofp/ofp10/interface.go. One
// DemoInstance will be created for each switch that connects
// to the network.
func NewDemoInstance() interface{} {
return &DemoInstance{&hostMap}
}
// Acts as a simple learning switch.
type DemoInstance struct {
*HostMap
}
func (b *DemoInstance) PacketIn(dpid net.HardwareAddr, pkt *ofp10.PacketIn) {
eth := pkt.Data
// Ignore link discovery packet types.
if eth.Ethertype == 0xa0f1 || eth.Ethertype == 0x88cc {
return
}
b.SetHost(eth.HWSrc, pkt.InPort)
if host, ok := b.Host(eth.HWDst); ok {
f1 := ofp10.NewFlowMod()
f1.Match.DLSrc = eth.HWSrc
f1.Match.DLDst = eth.HWDst
f1.AddAction(ofp10.NewActionOutput(host.port))
f1.IdleTimeout = 3
f2 := ofp10.NewFlowMod()
f2.Match.DLSrc = eth.HWDst
f2.Match.DLDst = eth.HWSrc
f2.AddAction(ofp10.NewActionOutput(pkt.InPort))
f2.IdleTimeout = 3
if s, ok := core.Switch(dpid); ok {
s.Send(f1)
s.Send(f2)
}
} else {
p := ofp10.NewPacketOut()
p.InPort = pkt.InPort
p.AddAction(ofp10.NewActionOutput(ofp10.P_ALL))
p.Data = ð
if sw, ok := core.Switch(dpid); ok {
sw.Send(p)
}
}
}
func main() {
fmt.Println("Ogo 2013")
runtime.GOMAXPROCS(runtime.NumCPU())
ctrl := core.NewController()
hostMap = *NewHostMap()
ctrl.RegisterApplication(NewDemoInstance)
ctrl.Listen(":6633")
}