func (self StratosOxm) Parse(buf []byte) map[ofp4sw.OxmKey]ofp4sw.OxmPayload { ret := make(map[ofp4sw.OxmKey]ofp4sw.OxmPayload) for _, oxmbuf := range oxm.Oxm(buf).Iter() { hdr := oxmbuf.Header() if hdr.Class() == ofp4.OFPXMC_EXPERIMENTER { exp := ofp4.OxmExperimenterHeader(oxmbuf) if exp.Experimenter() == oxm.STRATOS_EXPERIMENTER_ID { key := OxmKeyStratos(hdr.Field()) length := hdr.Length() - 4 if useOxmMultiValue(key) { payload := OxmMultiValue{} if p, ok := ret[key]; ok { payload = p.(OxmMultiValue) } payload.Values = append(payload.Values, oxmbuf[8:8+length]) ret[key] = payload } else { if hdr.HasMask() { ret[key] = ofp4sw.OxmValueMask{ Value: oxmbuf[8 : 8+length/2], Mask: oxmbuf[8+length/2:], } } else { ret[key] = ofp4sw.OxmValueMask{ Value: oxmbuf[8 : 8+length], } } } } } } return ret }
func (self FlowStats) String() string { comps := []string{ fmt.Sprintf("table=%d,priority=%d", self.TableId(), self.Priority()), } if n := self.IdleTimeout(); n != 0 { comps = append(comps, fmt.Sprintf("idle_timeout=%d", n)) } if n := self.HardTimeout(); n != 0 { comps = append(comps, fmt.Sprintf("hard_timeout=%d", n)) } comps = append(comps, fmt.Sprintf("cookie=0x%x", self.Cookie())) if fields := self.Match().OxmFields(); len(fields) > 0 { comps = append(comps, fmt.Sprintf("%v", oxm.Oxm(fields))) } if insts := self.Instructions(); len(insts) > 0 { for _, inst := range insts { comps = append(comps, fmt.Sprintf("%v", inst)) } } return strings.Join(comps, ",") }
func (self VxlanPort) Egress(fr Frame) error { var dst net.IP vxlan := make([]byte, 8+len(fr.Data)) vxlan[0] = 0x08 // valid flag for _, x := range oxm.Oxm(fr.Oob).Iter() { switch x.Header().Type() { case oxm.OXM_OF_TUNNEL_ID: copy(vxlan[4:7], x[9:12]) case oxm.NXM_NX_TUN_IPV4_DST: dst = net.IP(x[4:8]) } } copy(vxlan[8:], fr.Data) if n, err := self.conn.WriteToUDP(vxlan, &net.UDPAddr{ IP: dst, Port: self.port, }); err != nil { return err } else if n < len(vxlan) { fmt.Printf("MTU error?") } return nil }
func (self FlowMod) String() string { cmd := self.Command() comps := []string{ fmt.Sprintf("table=%d,priority=%d", self.TableId(), self.Priority()), } if cmd == OFPFC_ADD { comps = append(comps, fmt.Sprintf("cookie=0x%x", self.Cookie())) } else if self.CookieMask() != 0 { comps = append(comps, fmt.Sprintf("cookie=0x%x/0x%x", self.Cookie(), self.CookieMask())) } if fields := self.Match().OxmFields(); len(fields) > 0 { comps = append(comps, fmt.Sprintf("%v", oxm.Oxm(fields))) } if cmd != OFPFC_DELETE && cmd != OFPFC_DELETE_STRICT { if n := self.BufferId(); n != OFP_NO_BUFFER { comps = append(comps, fmt.Sprintf("buffer=%d", n)) } } if n := self.IdleTimeout(); n != 0 { comps = append(comps, fmt.Sprintf("idle_timeout=%d", n)) } if n := self.IdleTimeout(); n != 0 { comps = append(comps, fmt.Sprintf("hard_timeout=%d", n)) } if cmd == OFPFC_DELETE || cmd == OFPFC_DELETE_STRICT { if v := self.OutPort(); v != OFPP_ANY { comps = append(comps, fmt.Sprintf("out_port=%d", v)) } if v := self.OutGroup(); v != OFPG_ANY { comps = append(comps, fmt.Sprintf("group=%d", v)) } } if insts := self.Instructions(); len(insts) > 0 { comps = append(comps, fmt.Sprintf("%v", insts)) } return strings.Join(comps, ",") }
func main() { flag.Parse() args := flag.Args() getConn := func() io.ReadWriter { p := strings.SplitN(args[0], ":", 2) if len(p) == 1 { panic(fmt.Sprintf("connection scheme failure %s", args[0])) } else if c, err := net.Dial(p[0], p[1]); err != nil { panic(err) } else if n, err := c.Write([]byte(hello)); n != 8 || err != nil { panic("hello send error") } else if res := readMsg(c); res.Type() != ofp4.OFPT_HELLO { panic("hello recv error") } else { return c } } con := getConn() for { msg := readMsg(con) switch msg.Type() { case ofp4.OFPT_PACKET_IN: pin := ofp4.PacketIn(msg) comps := []string{ fmt.Sprintf("table=%d,cookie=%d", pin.TableId(), pin.Cookie()), } if match := pin.Match().OxmFields(); len(match) > 0 { comps = append(comps, oxm.Oxm(match).String()) } log.Print(strings.Join(comps, ",")) log.Print(gopacket.NewPacket(pin.Data(), layers.LayerTypeEthernet, gopacket.Default)) } } }
func (self ActionHeader) String() string { seq := []byte(self) switch binary.BigEndian.Uint16(seq) { case OFPAT_OUTPUT: makePort := func(ports string) string { maxLen := binary.BigEndian.Uint16(seq[8:]) if maxLen == OFPCML_NO_BUFFER { return fmt.Sprintf("output=%s", ports) } else { return fmt.Sprintf("output=%s:0x%x", ports, maxLen) } } port := binary.BigEndian.Uint32(seq[4:]) switch port { case OFPP_MAX: return makePort("max") case OFPP_IN_PORT: return makePort("in_port") case OFPP_TABLE: return makePort("table") case OFPP_NORMAL: return makePort("normal") case OFPP_FLOOD: return makePort("flood") case OFPP_ALL: return makePort("all") case OFPP_CONTROLLER: return makePort("controller") case OFPP_LOCAL: return makePort("local") case OFPP_ANY: return makePort("any") default: return makePort(fmt.Sprintf("%d", port)) } case OFPAT_COPY_TTL_OUT: return "copy_ttl_out" case OFPAT_COPY_TTL_IN: return "copy_ttl_in" case OFPAT_SET_MPLS_TTL: return fmt.Sprintf("set_mpls_ttl=%d", seq[4]) case OFPAT_DEC_MPLS_TTL: return "dec_mpls_ttl" case OFPAT_PUSH_VLAN: return fmt.Sprintf("push_vlan=0x%04x", binary.BigEndian.Uint16(seq[4:])) case OFPAT_POP_VLAN: return "pop_vlan" case OFPAT_PUSH_MPLS: return fmt.Sprintf("push_mpls=0x%04x", binary.BigEndian.Uint16(seq[4:])) case OFPAT_POP_MPLS: return fmt.Sprintf("pop_mpls=0x%04x", binary.BigEndian.Uint16(seq[4:])) case OFPAT_SET_QUEUE: return fmt.Sprintf("set_queue=%d", binary.BigEndian.Uint32(seq[4:])) case OFPAT_GROUP: return fmt.Sprintf("group=%d", binary.BigEndian.Uint32(seq[4:])) case OFPAT_SET_NW_TTL: return fmt.Sprintf("set_nw_ttl=%d", seq[4]) case OFPAT_DEC_NW_TTL: return "dec_nw_ttl" case OFPAT_SET_FIELD: return fmt.Sprintf("set_%v", oxm.Oxm(seq[4:])) case OFPAT_PUSH_PBB: return fmt.Sprintf("push_pbb=0x%04x", binary.BigEndian.Uint16(seq[4:])) case OFPAT_POP_PBB: return "pop_pbb" case OFPAT_EXPERIMENTER: if handler, ok := actionStringers[binary.BigEndian.Uint32(seq[4:])]; ok { return handler.FromAction(seq) } } return "?" }
func (self *ofmFlowMod) Map() Reducable { msg := ofp4.FlowMod(self.req) bufferId := msg.BufferId() switch msg.Command() { case ofp4.OFPFC_ADD: if err := self.pipe.addFlowEntry(msg); err != nil { if e, ok := err.(ofp4.ErrorMsg); ok { self.putError(e) } else { log.Print(err) } } case ofp4.OFPFC_MODIFY, ofp4.OFPFC_MODIFY_STRICT: reqMatch := match{} if err := reqMatch.UnmarshalBinary(msg.Match().OxmFields()); err != nil { log.Print(err) } else if msg.TableId() > ofp4.OFPTT_MAX { self.putError(ofp4.MakeErrorMsg(ofp4.OFPET_FLOW_MOD_FAILED, ofp4.OFPFMFC_BAD_TABLE_ID)) } else { filter := flowFilter{ cookie: msg.Cookie(), cookieMask: msg.CookieMask(), tableId: msg.TableId(), outPort: ofp4.OFPP_ANY, outGroup: ofp4.OFPG_ANY, match: reqMatch, } if msg.Command() == ofp4.OFPFC_MODIFY_STRICT { filter.priority = msg.Priority() filter.opStrict = true } for _, stat := range self.pipe.filterFlows(filter) { flow := stat.flow if err := func() error { flow.lock.Lock() defer flow.lock.Unlock() if msg.Flags()&ofp4.OFPFF_RESET_COUNTS != 0 { flow.packetCount = 0 flow.byteCount = 0 } return flow.importInstructions(msg.Instructions()) }(); err != nil { if e, ok := err.(ofp4.ErrorMsg); ok { self.putError(e) } else { log.Print(err) } } } } case ofp4.OFPFC_DELETE, ofp4.OFPFC_DELETE_STRICT: reqMatch := match{} if err := reqMatch.UnmarshalBinary(msg.Match().OxmFields()); err != nil { log.Print(err) } else { filter := flowFilter{ opUnregister: true, cookie: msg.Cookie(), cookieMask: msg.CookieMask(), tableId: msg.TableId(), outPort: msg.OutPort(), outGroup: msg.OutGroup(), match: reqMatch, } if msg.Command() == ofp4.OFPFC_DELETE_STRICT { filter.priority = msg.Priority() filter.opStrict = true } for _, stat := range self.pipe.filterFlows(filter) { if hdr, err := stat.flow.fields.MarshalBinary(); err != nil { log.Print(err) } else if portNo, act := hookDot11Action(oxm.Oxm(hdr)); portNo != 0 && len(act) != 0 { if port := self.pipe.getPort(portNo); port != nil { if err := port.Vendor(gopenflow.MgmtFrameRemove(act)).(error); err != nil { log.Print(err) } } } if stat.flow.flags&ofp4.OFPFF_SEND_FLOW_REM != 0 { self.pipe.sendFlowRem(stat.tableId, stat.priority, stat.flow, ofp4.OFPRR_DELETE) } } } bufferId = ofp4.OFP_NO_BUFFER // nothing to do with buffer by specification. } if bufferId != ofp4.OFP_NO_BUFFER { original, ok := func() (outputToPort, bool) { self.pipe.lock.Lock() defer self.pipe.lock.Unlock() original, ok := self.pipe.buffer[bufferId] if ok { delete(self.pipe.buffer, bufferId) } return original, ok }() if ok { pipe := self.pipe pipe.datapath <- &flowTask{ Frame: original.Frame, pipe: self.pipe, tableId: 0, } } else { self.putError(ofp4.MakeErrorMsg(ofp4.OFPET_BAD_REQUEST, ofp4.OFPBRC_BUFFER_UNKNOWN)) } } return self }