Example #1
0
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
}
Example #2
0
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, ",")
}
Example #3
0
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
}
Example #4
0
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, ",")
}
Example #5
0
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))
		}
	}
}
Example #6
0
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 "?"
}
Example #7
0
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
}