jonstout / ogo Goto Github PK
View Code? Open in Web Editor NEWAn OpenFlow Network Controller in Go
License: GNU General Public License v3.0
An OpenFlow Network Controller in Go
License: GNU General Public License v3.0
Hello.
Faced strange problem — it doesn't work by default. As i could find, the problem is in core.go ConnectionUp method in dscFmod
dscFmod := ofp10.NewFlowMod()
dscFmod.Priority = 0xffff
dscFmod.Match.DLType = 0xa0f1 // Link Discovery Messages
dscFmod.AddAction(ofp10.NewActionOutput(ofp10.P_CONTROLLER))
If you disable this mod, everything will work as expected. Why so? This mod brings controllers very strange behavior, and causes the l2 example doesn't work.
The PacketIn struct does not include the padding, which is not necessary but also does not consider the padding when (un-)marshaling the packet, which leads to wrong packets.
As far as I can see this repo is not really maintained anymore. Should I send a pull request anyway or fork it? (I have another issue, MessageStream taking a net.TCPConn instead of a net.Conn and might have more issues in the future)
hi @jonstout,
As far as I can see, after a switch starts up, function Controller.handleConnection()
and OFSwitch.receive()
are both tring to pop messages from the same inbound channel OFSwitch.stream.Inbound
. However the former one can only deal with the OPFT_HELLO or OFPT_FEATURES_REPLY messages.
So, other messages will be discarded if received by Controller.handleConnection()
?
Hello.
Here is simple code, right from the README
package main
import (
"log"
"net"
"runtime"
"github.com/jonstout/ogo"
"github.com/jonstout/ogo/protocol/ofp10"
)
func NewDemoInstance() interface{} {
return new(DemoInstance)
}
// Acts as a simple learning switch.
type DemoInstance struct{}
func (b *DemoInstance) ConnectionUp(dpid net.HardwareAddr) {
log.Println("Switch connected:", dpid)
}
func (b *DemoInstance) ConnectionDown(dpid net.HardwareAddr) {
log.Println("Switch disconnected:", dpid)
}
func (b *DemoInstance) PacketIn(dpid net.HardwareAddr, pkt *ofp10.PacketIn) {
log.Println("PacketIn message received from:", dpid, "len:", pkt.Len(), "datalen:", pkt.Data.Len(), "hwsrc:", pkt.Data.HWSrc, "hwdst:", pkt.Data.HWDst, pkt.Data.Ethertype)
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
ctrl := ogo.NewController()
ctrl.RegisterApplication(NewDemoInstance)
ctrl.Listen(":6633")
}
Switch connects to controller, but while pinging hosts, i see following
2015/09/12 21:04:26 Listening for connections on :6633
2015/09/12 21:04:27 Openflow Connection: 00:00:4a:9c:96:38:5a:49
2015/09/12 21:04:27 Switch connected: 00:00:4a:9c:96:38:5a:49
2015/09/12 21:04:30 PacketIn message received from: 00:00:4a:9c:96:38:5a:49 len: 71 datalen: 54 hwsrc: hwdst: 65535
2015/09/12 21:04:31 PacketIn message received from: 00:00:4a:9c:96:38:5a:49 len: 71 datalen: 54 hwsrc: hwdst: 65535
2015/09/12 21:04:32 PacketIn message received from: 00:00:4a:9c:96:38:5a:49 len: 71 datalen: 54 hwsrc: hwdst: 65535
HWSrc and HWDst are empty. Why?
I'm trying it on very simple setup — one vswitch, two hosts. POX as a reference and it works. But example/l2/application.go — doesn't — the problem is a lack of hw addresses in PacketIn method.
Am i missing something?
hi,
I am starting to write a new version of my OpenFlow controller [1], currently in Haskell, in Go.
in our current version, we make use of the fact that each switch has its own I/O loop to provide concurrency to switch-specific computation. so, rather than muxing all messages of type A onto a single channel (which then becomes a bottleneck), I would prefer to have a set of per-switch channels with all messages from that switch. we've found this concurrency to be necessary as the controller scales.
anyway, is this something you would be open to? (sorry to file this as an issue, I couldn't find your email address :-) ... I think it could be done by exposing a lower-level interface in addition to the current one.
if not, what is your license for this project? we have a basic OpenFlow serialization/deserialization library for go which we've been using [2], and might want to adapt some of your parsers into ours.
thanks!
Andrew
[1] http://pane.cs.brown.edu
[2] https://github.com/brownsys/GoOF
Why core.go contains 0xa0f1 for LLDP messsages? I can't find this protocol id, LLDP have only 0x88cc. Why not use only this value?
Also maybe move l2 example app to examples dir and create some more examples? FOr example i'm interesting to try create l2 multiswitch with topology detection...
Are there any plans to implement OpenFlow 1.3?
I spend some days to create parser for udp/dhcp messages and i have some questions:
Is that possible to provide not only []byte to packet reader from socket, but also io.Reader?
Now as i see pacit always parse from buttom layer to top, but i think this is unecessary. Simple example - i'm create flowmod message and want to get to controller only mesages from specific port. But in this message i'm only need MAC (ethernet layer) and for example dhcp packet. In this case i'm only need to decode and populate 2 layers, and i can skip ip, udp layers and not populate structures...
In this case i think best of all from ogo create ethernet packet that have Data []byte with payload from ethernet packet.
After that pacit may have Decode method that can input []byte, packets ..*Packet.
In packets we can add layers that we need, absent layers may be skipped or failed.
In this case from ethernet layer we can determine length of payload, after that we can dig to it and skips all layers before dhcp.
Does it sounds reasonable?
I think for simple constant isolation and not mess namespaces from various type of packets we need to splis pacit into multiple packages, for example:
http://godoc.org/bitbucket.org/vtolstov/netpkt
http://godoc.org/bitbucket.org/vtolstov/netpkt/ethernet
http://godoc.org/bitbucket.org/vtolstov/netpkt/arp
http://godoc.org/bitbucket.org/vtolstov/netpkt/ipv4
http://godoc.org/bitbucket.org/vtolstov/netpkt/udp
Do you have email to contact? I think github issue tracker not the best place to this discussions...
Hi!
I see another changes in ogo and have a question:
https://github.com/jonstout/ogo/blob/master/ogo.go#L85
Why P_ALL? As i known that means send packet to all ports, but in case of usage stp port can be blocked to avoid loops. Why not use P_FLOOD ?
Maybe the time to move pacit to ogo?
And what about split pacit to packages?
I'm already have troubles then create helper functions for dhcp. For example i need NewDiscover, NewReply, NewRequest, NewOffer and much more. Now i need to create functions like NewDHCPOffer.
In case of other protocols if we need helpers for it (for example if we need create ethernet tcp packet and send it to switch) we need to prefix all functions that i think not the best way.
For ogo changes are minimal because its creates ethernet packet.
Config requests not properly sended to openvswitch. This is simple code:
res := ofp10.NewSetConfig()
res.MissSendLen = uint16(512)
s.Send(res)
That produces errors in vswitch logs:
2013-09-10T06:23:56Z|02542|ofp_msgs|WARN|received OFPT_SET_CONFIG with incorrect length 8 (expected length 12)
2013-09-10T06:23:56Z|02543|connmgr|INFO|ovs-vm<->tcp:127.0.0.1:6633: sending OFPBRC_BAD_LEN error reply to OFPT_SET_CONFIG message
Hello. I think about writing proxy like app for openflow (local openflow controllers sends some messages to central openflow controller).
What best method for this? As i inderstand i need some openflow client package?
I'm compile simple ogo app with race flag and get this results:
==================
WARNING: DATA RACE
Read by goroutine 13:
github.com/jonstout/ogo/openflow/ofp10.func·001()
/home/vase/devel/go/src/github.com/jonstout/ogo/openflow/ofp10/ofp10.go:64 +0xa3
github.com/jonstout/ogo/openflow/ofp10.NewHello()
/home/vase/devel/go/src/github.com/jonstout/ogo/openflow/ofp10/ofp10.go:139 +0x44
github.com/jonstout/ogo/core.NewOFPSwitch()
/home/vase/devel/go/src/github.com/jonstout/ogo/core/switch.go:42 +0x39
Previous write by goroutine 8:
github.com/jonstout/ogo/openflow/ofp10.func·001()
/home/vase/devel/go/src/github.com/jonstout/ogo/openflow/ofp10/ofp10.go:65 +0xbb
github.com/jonstout/ogo/openflow/ofp10.NewHello()
/home/vase/devel/go/src/github.com/jonstout/ogo/openflow/ofp10/ofp10.go:139 +0x44
github.com/jonstout/ogo/core.NewOFPSwitch()
/home/vase/devel/go/src/github.com/jonstout/ogo/core/switch.go:42 +0x39
Goroutine 13 (running) created at:
github.com/jonstout/ogo/core.(*Controller).Start()
/home/vase/devel/go/src/github.com/jonstout/ogo/core/controller.go:35 +0x26f
main.func·001()
/home/vase/devel/ofp/main.go:53 +0x84
Goroutine 8 (finished) created at:
github.com/jonstout/ogo/core.(*Controller).Start()
/home/vase/devel/go/src/github.com/jonstout/ogo/core/controller.go:35 +0x26f
main.func·001()
/home/vase/devel/ofp/main.go:53 +0x84
Tried to run ogo's l2
switch together with mininet. I first ran ./pox.py forwarding.l2_learning
as my controller and set up a basic mininet network (and it worked), and now I want to replace pox with ogo's l2 switch example, but I get:
InboundError EOF
as soon as my mininet network is started. mininet itself seems to not notice any problems at first, but trying to do h1 ping h2
fails with Destination Host Unreachable
. This is all that ogo l2 logs:
Ogo 2013
2014/08/13 17:30:16 Listening for connections on 0.0.0.0:6633
2014/08/13 17:30:19 InboundError EOF
2014/08/13 17:30:19 EOF
2014/08/13 17:30:19 Closing OpenFlow message stream.
2014/08/13 17:30:19 Openflow Connection: 00:00:00:00:00:00:00:01
Any hints regarding how to solve this would be appreciated. It seems that the Read
from the connection sees an EOF
first thing. Strange?
Hello again.
I'm try to parse dhcp messages and stuck at strange thing.
First of all: https://github.com/vtolstov/pacit/blob/dhcp/udp.go https://github.com/vtolstov/pacit/blob/dhcp/dhcp.go
If pacit have this files it can parse udp and dhcp. But as i see openvswitch not pass full dhcp packet to ogo.
When i parse dhcp message i have only data ended to ClientHardwareAddr after that all bytes equal to 0. Why this happening? In Wireshark i see tht to openvswitch device go complete packet, but vswitch or controller reads only partial of it..
func (app *appDHCP) parsePacketIn(dpid net.HardwareAddr, pkt *ofp10.PacketIn) {
eth := pkt.Data
switch eth.Ethertype {
case pacit.ARP_MSG:
arp := eth.Data.(*pacit.ARP)
//log.Printf("arp: %+v\n", arp)
_ = arp
case pacit.IPv4_MSG:
ip := eth.Data.(*pacit.IPv4)
//log.Printf("ipv4: %+v\n", ip)
switch ip.Protocol {
case pacit.IP_ICMP:
icmp := ip.Data.(*pacit.ICMP)
// log.Printf("icmp: %+v\n", icmp)
_ = icmp
case pacit.IP_UDP:
udp := ip.Data.(*pacit.UDP)
// log.Printf("udp: %+v\n", udp)
if udp.PortSrc == 68 && udp.PortDst == 67 {
dhcp := &pacit.DHCP{}
_, err := dhcp.Write(udp.Data)
if err != nil {
log.Fatalf(err.Error())
}
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.