func (o *OgoInstance) ConnectionUp(dpid net.HardwareAddr) { dropMod := ofp10.NewFlowMod() dropMod.Priority = 1 arpFmod := ofp10.NewFlowMod() arpFmod.Priority = 2 arpFmod.Match.DLType = 0x0806 // ARP Messages arpFmod.AddAction(ofp10.NewActionOutput(ofp10.P_CONTROLLER)) dscFmod := ofp10.NewFlowMod() dscFmod.Priority = 0xffff dscFmod.Match.DLType = 0xa0f1 // Link Discovery Messages dscFmod.AddAction(ofp10.NewActionOutput(ofp10.P_CONTROLLER)) if sw, ok := Switch(dpid); ok { sw.Send(ofp10.NewFeaturesRequest()) sw.Send(dropMod) sw.Send(arpFmod) sw.Send(dscFmod) sw.Send(ofp10.NewEchoRequest()) } go o.linkDiscoveryLoop(dpid) }
func (c *Controller) handleConnection(conn *net.TCPConn) { stream := NewMessageStream(conn) h, err := ofpxx.NewHello(1) if err != nil { return } stream.Outbound <- h for { select { //case stream.Outbound <- ofp10.NewHello(): // Send hello message with latest protocol version. case msg := <-stream.Inbound: switch m := msg.(type) { // A Hello message of the appropriate type // completes version negotiation. If version // types are incompatable, it is possible the // connection may be servered without error. case *ofpxx.Header: if m.Version == ofp10.VERSION { // Version negotiation is // considered complete. Create // new Switch and notifiy listening // applications. stream.Version = m.Version stream.Outbound <- ofp10.NewFeaturesRequest() } else { // Connection should be severed if controller // doesn't support switch version. log.Println("Received unsupported ofp version", m.Version) stream.Shutdown <- true } // After a vaild FeaturesReply has been received we // have all the information we need. Create a new // switch object and notify applications. case *ofp10.SwitchFeatures: NewSwitch(stream, *m) for _, newInstance := range Applications { if sw, ok := Switch(m.DPID); ok { i := newInstance() sw.AddInstance(i) } } return // An error message may indicate a version mismatch. We // disconnect if an error occurs this early. case *ofp10.ErrorMsg: log.Println(m) stream.Version = m.Header.Version stream.Shutdown <- true } case err := <-stream.Error: // The connection has been shutdown. log.Println(err) return case <-time.After(time.Second * 3): // This shouldn't happen. If it does, both the controller // and switch are no longer communicating. The TCPConn is // still established though. log.Println("Connection timed out.") return } } }