func (d *of10Driver) handlePkt(pkt of.Header, c *ofConn) error { pkt10, err := of10.ToHeader10(pkt) if err != nil { return err } switch { case of10.IsEchoRequest(pkt10): return d.handleEchoRequest(of10.NewEchoRequestWithBuf(pkt10.Buf), c) case of10.IsFeaturesReply(pkt10): return d.handleFeaturesReply(of10.NewFeaturesReplyWithBuf(pkt10.Buf), c) case of10.IsPacketIn(pkt10): return d.handlePacketIn(of10.NewPacketInWithBuf(pkt10.Buf), c) case of10.IsErrorMsg(pkt10): return d.handleErrorMsg(of10.NewErrorMsgWithBuf(pkt10.Buf), c) case of10.IsStatsReply(pkt10): return d.handleStatsReply(of10.NewStatsReplyWithBuf(pkt10.Buf), c) default: return fmt.Errorf("Received unsupported packet: %v", pkt.Type()) } }
func (d *of10Driver) handshake(c *ofConn) error { freq := of10.NewFeaturesRequest() if err := c.WriteHeader(freq.Header); err != nil { return err } c.Flush() glog.V(2).Info("%v sent features request to the switch", c.ctx) hdr, err := c.ReadHeader() if err != nil { return err } v10, err := of10.ToHeader10(hdr) if err != nil { return err } frep, err := of10.ToFeaturesReply(v10) if err != nil { return err } glog.Infof("%v completes handshaking with switch %016x", c.ctx, frep.DatapathId()) glog.Infof("%v disables packet buffers in switch %016x", c.ctx, frep.DatapathId()) cfg := of10.NewSwitchSetConfig() cfg.SetMissSendLen(0xFFFF) c.WriteHeader(cfg.Header) nodeID := datapathIDToNodeID(frep.DatapathId()) c.node = nom.Node{ ID: nodeID, MACAddr: datapathIDToMACAddr(frep.DatapathId()), Capabilities: nil, } glog.Infof("%v is connected to %v", c.ctx, c.node) nomDriver := nom.Driver{ BeeID: c.ctx.ID(), Role: nom.DriverRoleDefault, } c.ctx.Emit(nom.NodeConnected{ Node: c.node, Driver: nomDriver, }) d.ofPorts = make(map[uint16]*nom.Port) d.nomPorts = make(map[nom.UID]uint16) for _, p := range frep.Ports() { name := p.Name() port := nom.Port{ ID: portNoToPortID(uint32(p.PortNo())), Name: string(name[:]), MACAddr: p.HwAddr(), Node: c.NodeUID(), } d.ofPorts[p.PortNo()] = &port d.nomPorts[port.UID()] = p.PortNo() glog.Infof("%v added", port) if p.PortNo() <= uint16(of10.PP_MAX) { c.ctx.Emit(nom.PortStatusChanged{ Port: port, Driver: nomDriver, }) } } return nil }