Example #1
0
func (entry *flowEntry) importInstructions(instructions ofp4.Instruction) error {
	for _, inst := range instructions.Iter() {
		switch inst.Type() {
		default:
			return ofp4.MakeErrorMsg(
				ofp4.OFPET_BAD_INSTRUCTION,
				ofp4.OFPBIC_UNKNOWN_INST,
			)
		case ofp4.OFPIT_GOTO_TABLE:
			entry.instGoto = ofp4.InstructionGotoTable(inst).TableId()
		case ofp4.OFPIT_WRITE_METADATA:
			i := ofp4.InstructionWriteMetadata(inst)
			if i.Metadata()&^i.MetadataMask() != 0 {
				return errors.New("invalid value/mask pair")
			}
			entry.instMetadata = &metadataInstruction{
				i.Metadata(),
				i.MetadataMask(),
			}
		case ofp4.OFPIT_WRITE_ACTIONS, ofp4.OFPIT_APPLY_ACTIONS, ofp4.OFPIT_CLEAR_ACTIONS:
			i := ofp4.InstructionActions(inst)
			switch inst.Type() {
			case ofp4.OFPIT_WRITE_ACTIONS:
				var aset actionSet
				if err := aset.UnmarshalBinary(i.Actions()); err != nil {
					return err
				}
				entry.instWrite = aset
			case ofp4.OFPIT_APPLY_ACTIONS:
				var alist actionList
				if err := alist.UnmarshalBinary(i.Actions()); err != nil {
					return err
				}
				entry.instApply = alist
			case ofp4.OFPIT_CLEAR_ACTIONS:
				entry.instClear = true
			}
		case ofp4.OFPIT_METER:
			entry.instMeter = ofp4.InstructionMeter(inst).MeterId()
		case ofp4.OFPIT_EXPERIMENTER:
			experimenter := ofp4.InstructionExperimenter(inst).Experimenter()
			data := inst[8:]
			if handler, ok := instructionHandlers[experimenter]; ok {
				pos := handler.Order(data)
				entry.instExp[pos] = append(entry.instExp[pos], instExperimenter{
					Experimenter: experimenter,
					Data:         data,
					Handler:      handler,
				})
			} else {
				return ofp4.MakeErrorMsg(ofp4.OFPET_BAD_INSTRUCTION, ofp4.OFPBIC_UNSUP_INST)
			}
		}
	}
	return nil
}
Example #2
0
func (self *flowTableFeature) importProps(props ofp4.TableFeaturePropHeader) error {
	for _, prop := range props.Iter() {
		switch prop.Type() {
		case ofp4.OFPTFPT_INSTRUCTIONS, ofp4.OFPTFPT_INSTRUCTIONS_MISS:
			var ids []instructionKey
			for _, inst := range ofp4.TableFeaturePropInstructions(prop).InstructionIds().Iter() {
				if inst.Type() == ofp4.OFPIT_EXPERIMENTER {
					ids = append(ids, ofp4.InstructionExperimenter(inst).Experimenter())
				} else {
					ids = append(ids, inst.Type())
				}
			}
			switch prop.Type() {
			case ofp4.OFPTFPT_INSTRUCTIONS:
				self.hit.inst = ids
			case ofp4.OFPTFPT_INSTRUCTIONS_MISS:
				self.miss.inst = ids
			}
		case ofp4.OFPTFPT_NEXT_TABLES:
			self.hit.next = ofp4.TableFeaturePropNextTables(prop).NextTableIds()
		case ofp4.OFPTFPT_NEXT_TABLES_MISS:
			self.miss.next = ofp4.TableFeaturePropNextTables(prop).NextTableIds()
		case ofp4.OFPTFPT_WRITE_ACTIONS, ofp4.OFPTFPT_WRITE_ACTIONS_MISS,
			ofp4.OFPTFPT_APPLY_ACTIONS, ofp4.OFPTFPT_APPLY_ACTIONS_MISS:
			var ids []actionKey
			for _, act := range ofp4.TableFeaturePropActions(prop).ActionIds().Iter() {
				if act.Type() == ofp4.OFPAT_EXPERIMENTER {
					ids = append(ids, ofp4.ActionExperimenterHeader(act).Experimenter())
				} else {
					ids = append(ids, act.Type())
				}
			}
			switch prop.Type() {
			case ofp4.OFPTFPT_WRITE_ACTIONS:
				self.hit.writeActions = ids
			case ofp4.OFPTFPT_WRITE_ACTIONS_MISS:
				self.miss.writeActions = ids
			case ofp4.OFPTFPT_APPLY_ACTIONS:
				self.hit.applyActions = ids
			case ofp4.OFPTFPT_APPLY_ACTIONS_MISS:
				self.miss.applyActions = ids
			}
		case ofp4.OFPTFPT_MATCH, ofp4.OFPTFPT_WILDCARDS,
			ofp4.OFPTFPT_WRITE_SETFIELD, ofp4.OFPTFPT_WRITE_SETFIELD_MISS,
			ofp4.OFPTFPT_APPLY_SETFIELD, ofp4.OFPTFPT_APPLY_SETFIELD_MISS:
			var ids []oxmId
			for _, oxm := range ofp4.TableFeaturePropOxm(prop).OxmIds().Iter() {
				hdr := oxm.Header()
				if hdr.Class() == ofp4.OFPXMC_EXPERIMENTER {
					exp := ofp4.OxmExperimenterHeader(oxm).Experimenter()
					ids = append(ids, [...]uint32{oxmHandlers[exp].OxmId(uint32(oxm.Header())), exp})
				} else {
					ids = append(ids, hdr.Type())
				}
			}
			switch prop.Type() {
			case ofp4.OFPTFPT_MATCH:
				self.match = ids
			case ofp4.OFPTFPT_WILDCARDS:
				self.wildcards = ids
			case ofp4.OFPTFPT_WRITE_SETFIELD:
				self.hit.writeSetfield = ids
			case ofp4.OFPTFPT_WRITE_SETFIELD_MISS:
				self.miss.writeSetfield = ids
			case ofp4.OFPTFPT_APPLY_SETFIELD:
				self.hit.applySetfield = ids
			case ofp4.OFPTFPT_APPLY_SETFIELD_MISS:
				self.miss.applySetfield = ids
			}
		case ofp4.OFPTFPT_EXPERIMENTER, ofp4.OFPTFPT_EXPERIMENTER_MISS:
			msg := ofp4.TableFeaturePropExperimenter(prop)
			eKey := experimenterKey{
				Experimenter: msg.Experimenter(),
				ExpType:      msg.ExpType(),
			}
			if _, ok := tableHandlers[eKey]; !ok {
				return ofp4.MakeErrorMsg(
					ofp4.OFPET_TABLE_FEATURES_FAILED,
					ofp4.OFPTFFC_BAD_ARGUMENT,
				)
			}
			exp := experimenterProp{
				experimenterKey: eKey,
				Data:            msg.ExperimenterData(),
			}
			switch prop.Type() {
			case ofp4.OFPTFPT_EXPERIMENTER:
				self.hit.experimenter = append(self.hit.experimenter, exp)
			case ofp4.OFPTFPT_EXPERIMENTER_MISS:
				self.miss.experimenter = append(self.hit.experimenter, exp)
			}
		}
	}
	return nil
}