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 }
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 }