public ImmutablePair<Long, Boolean> deleteMeter(IOFSwitch sw, final DatapathId dpid, final long meterId) { logger.debug("deleting meter {} from switch {}", meterId, dpid); OFFactory ofFactory = sw.getOFFactory(); OFMeterMod.Builder meterDeleteBuilder = ofFactory.buildMeterMod() .setMeterId(meterId) .setCommand(OFMeterModCommand.DELETE); if (sw.getOFFactory().getVersion().compareTo(OF_13) > 0) { meterDeleteBuilder.setBands(emptyList()); } else { meterDeleteBuilder.setMeters(emptyList()); } OFMeterMod meterDelete = meterDeleteBuilder.build(); boolean response = sw.write(meterDelete); return new ImmutablePair<>(meterDelete.getXid(), response); }
private Capture<OFMeterMod> prepareForMeterTest() { Capture<OFMeterMod> capture = EasyMock.newCapture(); expect(ofSwitchService.getSwitch(dpid)).andStubReturn(iofSwitch); expect(iofSwitch.getOFFactory()).andStubReturn(ofFactory); expect(iofSwitch.getSwitchDescription()).andStubReturn(switchDescription); expect(switchDescription.getManufacturerDescription()).andStubReturn(""); expect(iofSwitch.write(capture(capture))).andReturn(true); EasyMock.expectLastCall(); replay(ofSwitchService); replay(iofSwitch); replay(switchDescription); return capture; }
private OFMeterMod.Builder builderMeterMod() { OFMeterMod.Builder builder = factory.buildMeterMod(); int flags = 0; if (burst) { // covering loxi short comings. flags |= 1 << OFMeterFlags.BURST.ordinal(); } switch (unit) { case PKTS_PER_SEC: flags |= 1 << OFMeterFlags.PKTPS.ordinal(); break; case KB_PER_SEC: flags |= 1 << OFMeterFlags.KBPS.ordinal(); break; default: log.warn("Unknown unit type {}", unit); } //FIXME: THIS WILL CHANGE IN OF1.4 to setBands. builder.setMeters(buildBands()); builder.setFlags(flags) .setMeterId(id) .setXid(xid); return builder; }
private ImmutablePair<Long, Boolean> installMeter(final IOFSwitch sw, final DatapathId dpid, final long bandwidth, final long burstSize, final long meterId) { logger.debug("installing meter {} on switch {} width bandwidth {}", meterId, dpid, bandwidth); Set<OFMeterFlags> flags = new HashSet<>(Arrays.asList(OFMeterFlags.KBPS, OFMeterFlags.BURST)); OFFactory ofFactory = sw.getOFFactory(); OFMeterBandDrop.Builder bandBuilder = ofFactory.meterBands() .buildDrop() .setRate(bandwidth) .setBurstSize(burstSize); OFMeterMod.Builder meterModBuilder = ofFactory.buildMeterMod() .setMeterId(meterId) .setCommand(OFMeterModCommand.ADD) .setFlags(flags); if (sw.getOFFactory().getVersion().compareTo(OF_13) > 0) { meterModBuilder.setBands(singletonList(bandBuilder.build())); } else { meterModBuilder.setMeters(singletonList(bandBuilder.build())); } OFMeterMod meterMod = meterModBuilder.build(); boolean response = sw.write(meterMod); return new ImmutablePair<>(meterMod.getXid(), response); }
default OFMeterMod installMeter(long bandwidth, long burstSize, long meterId) { return ofFactory.buildMeterMod() .setMeterId(meterId) .setCommand(ADD) .setMeters(singletonList(ofFactory.meterBands() .buildDrop() .setRate(bandwidth) .setBurstSize(burstSize).build())) .setFlags(new HashSet<>(Arrays.asList(KBPS, BURST))) .setXid(0L) .build(); }
@Test public void deleteMeter() { final Capture<OFMeterMod> capture = prepareForMeterTest(); switchManager.deleteMeter(dpid, meterId); final OFMeterMod meterMod = capture.getValue(); assertEquals(meterMod.getCommand(), OFMeterModCommand.DELETE); assertEquals(meterMod.getMeterId(), meterId); }
@Test public void installOneSwitchNoneFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_one_switch_none_flow.json"), Charsets.UTF_8); InstallOneSwitchFlow data = (InstallOneSwitchFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.oneSwitchNoneFlowMod(data.getInputPort(), data.getOutputPort(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installOneSwitchReplaceFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_one_switch_replace_flow.json"), Charsets.UTF_8); InstallOneSwitchFlow data = (InstallOneSwitchFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.oneSwitchReplaceFlowMod(data.getInputPort(), data.getOutputPort(), data.getInputVlanId(), data.getOutputVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installOneSwitchPushFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_one_switch_push_flow.json"), Charsets.UTF_8); InstallOneSwitchFlow data = (InstallOneSwitchFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.oneSwitchPushFlowMod(data.getInputPort(), data.getOutputPort(), data.getOutputVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installOneSwitchPopFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_one_switch_pop_flow.json"), Charsets.UTF_8); InstallOneSwitchFlow data = (InstallOneSwitchFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.oneSwitchPopFlowMod(data.getInputPort(), data.getOutputPort(), data.getInputVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installIngressNoneFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_ingress_none_flow.json"), Charsets.UTF_8); InstallIngressFlow data = (InstallIngressFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.ingressNoneFlowMod(data.getInputPort(), data.getOutputPort(), data.getTransitVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installIngressReplaceFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_ingress_replace_flow.json"), Charsets.UTF_8); InstallIngressFlow data = (InstallIngressFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.ingressReplaceFlowMod(data.getInputPort(), data.getOutputPort(), data.getInputVlanId(), data.getTransitVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installIngressPushFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_ingress_push_flow.json"), Charsets.UTF_8); InstallIngressFlow data = (InstallIngressFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.ingressPushFlowMod(data.getInputPort(), data.getOutputPort(), data.getTransitVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
@Test public void installIngressPopFlow() throws IOException, InterruptedException { String value = Resources.toString(getClass().getResource("/install_ingress_pop_flow.json"), Charsets.UTF_8); InstallIngressFlow data = (InstallIngressFlow) prepareData(value); OFMeterMod meterCommand = scheme.installMeter(data.getBandwidth(), 1024, data.getMeterId()); OFFlowAdd flowCommand = scheme.ingressPopFlowMod(data.getInputPort(), data.getOutputPort(), data.getInputVlanId(), data.getTransitVlanId(), data.getMeterId(), 123L); runTest(value, flowCommand, meterCommand, null, null); }
/** * Runs test case. * * @param value data string from json resource file * @param flowCommand OFFlowAdd instance to compare result with * @throws InterruptedException if test was interrupted during run */ private void runTest(final String value, final OFFlowAdd flowCommand, final OFMeterMod meterCommand, final OFFlowAdd reverseFlowCommand, final OFMeterMod reverseMeterCommand) throws InterruptedException { // construct kafka message ConsumerRecord<String, String> record = new ConsumerRecord<>("", 0, 0, "", value); // create parser instance KafkaMessageCollector.ParseRecord parseRecord = collector.new ParseRecord(record); // init test mocks Capture<OFFlowAdd> flowAddCapture = flowCommand == null ? null : newCapture(CaptureType.ALL); Capture<OFMeterMod> meterAddCapture = meterCommand == null ? null : newCapture(CaptureType.ALL); prepareMocks(flowAddCapture, meterAddCapture, reverseFlowCommand != null, reverseMeterCommand != null); // run parser and wait for termination or timeout parseRecordExecutor.execute(parseRecord); parseRecordExecutor.shutdown(); parseRecordExecutor.awaitTermination(10, TimeUnit.SECONDS); // verify results if (meterCommand != null) { assertEquals(meterCommand, meterAddCapture.getValues().get(0)); if (reverseMeterCommand != null) { assertEquals(reverseMeterCommand, meterAddCapture.getValues().get(1)); } } if (flowCommand != null) { assertEquals(flowCommand, flowAddCapture.getValues().get(0)); if (reverseFlowCommand != null) { assertEquals(reverseFlowCommand, flowAddCapture.getValues().get(1)); } } }
/** * Prepares test mocks for run. * * @param flowAddCapture Capture for FlowAdd command * @param meterAddCapture Capture for MeterMod<Add> command */ private void prepareMocks(Capture<OFFlowAdd> flowAddCapture, Capture<OFMeterMod> meterAddCapture, boolean needCheckReverseFlow, boolean needCheckReverseMeter) { IOFSwitch iofSwitch = createMock(IOFSwitch.class); expect(ofSwitchService.getSwitch(anyObject(DatapathId.class))).andStubReturn(iofSwitch); expect(iofSwitch.getOFFactory()).andStubReturn(ofFactory); expect(iofSwitch.getSwitchDescription()).andStubReturn(switchDescription); if (meterAddCapture != null) { expect(iofSwitch.write(capture(meterAddCapture))).andReturn(true); if (flowAddCapture != null) { expect(iofSwitch.write(capture(flowAddCapture))).andReturn(true); } if (needCheckReverseMeter) { expect(iofSwitch.write(capture(meterAddCapture))).andReturn(true); } if (needCheckReverseFlow) { expect(iofSwitch.write(capture(flowAddCapture))).andReturn(true); } } else if (flowAddCapture != null) { expect(iofSwitch.write(capture(flowAddCapture))).andReturn(true).times(needCheckReverseFlow ? 2 : 1); } replay(ofSwitchService); replay(iofSwitch); }
@Override public void startDriverHandshake() { if (startDriverHandshakeCalled) { throw new SwitchDriverSubHandshakeAlreadyStarted(); } startDriverHandshakeCalled = true; OFFlowMod fm = factory().buildFlowDelete() .setTableId(TableId.ALL) .setOutGroup(OFGroup.ANY) .build(); sendMsg(Collections.singletonList(fm)); OFGroupMod gm = factory().buildGroupDelete() .setGroup(OFGroup.ALL) .setGroupType(OFGroupType.ALL) .build(); sendMsg(Collections.singletonList(gm)); OFMeterMod mm = factory().buildMeterMod() .setMeterId(MeterId.ALL.id()) .build(); sendMsg(Collections.singletonList(mm)); barrierXid = getNextTransactionId(); OFBarrierRequest barrier = factory().buildBarrierRequest() .setXid(barrierXid).build(); sendHandshakeMessage(barrier); }
private OFMeterMod.Builder builderMeterMod() { OFMeterMod.Builder builder = factory.buildMeterMod(); Set<OFMeterFlags> flags = EnumSet.noneOf(OFMeterFlags.class); if (burst) { flags.add(OFMeterFlags.BURST); } switch (unit) { case PKTS_PER_SEC: flags.add(OFMeterFlags.PKTPS); break; case KB_PER_SEC: flags.add(OFMeterFlags.KBPS); break; default: log.warn("Unknown unit type {}", unit); } if (factory.getVersion().getWireVersion() >= OFVersion.OF_14.getWireVersion()) { builder.setBands(buildBands()); } else { builder.setMeters(buildBands()); } builder.setFlags(flags) .setMeterId(id) .setXid(xid); return builder; }
private void meterModError(OFMeterMod meterMod, OFMeterModFailedCode code, Channel channel) { OFMeterModFailedErrorMsg errorMsg = FACTORY.errorMsgs() .buildMeterModFailedErrorMsg() .setXid(meterMod.getXid()) .setCode(code) .build(); channel.writeAndFlush(Collections.singletonList(errorMsg)); log.debug("Sent meterMod error {}", code); }
private void processMeterMod(OFMeterMod meterMod, Channel channel) { log.debug("processing METER_MOD {} message", meterMod.getCommand()); long meterModId = meterMod.getMeterId(); Meter existingMeter = meterService.getMeter(deviceId, MeterId.meterId(meterModId)); MeterRequest meterRequest = null; switch (meterMod.getCommand()) { case ADD: if (existingMeter != null) { meterModError(meterMod, OFMeterModFailedCode.METER_EXISTS, channel); return; } meterRequest = meterRequestBuilder(meterMod).add(); break; case MODIFY: if (existingMeter == null) { meterModError(meterMod, OFMeterModFailedCode.UNKNOWN_METER, channel); return; } meterRequest = meterRequestBuilder(meterMod).add(); break; case DELETE: // non-existing meter id will not result in OFMeterModFailedErrorMsg // being sent to the controller meterRequest = meterRequestBuilder(meterMod).remove(); break; default: log.warn("Unexpected message {} received for switch {}", meterMod.getCommand(), this); return; } meterService.submit(meterRequest); }
@Override public void processControllerCommand(Channel channel, OFMessage msg) { OFControllerRole myRole = role(channel); if (OFControllerRole.ROLE_SLAVE.equals(myRole)) { OFBadRequestErrorMsg errorMsg = FACTORY.errorMsgs() .buildBadRequestErrorMsg() .setXid(msg.getXid()) .setCode(OFBadRequestCode.IS_SLAVE) .build(); channel.writeAndFlush(Collections.singletonList(errorMsg)); return; } switch (msg.getType()) { case PORT_MOD: OFPortMod portMod = (OFPortMod) msg; processPortMod(portMod); break; case FLOW_MOD: OFFlowMod flowMod = (OFFlowMod) msg; processFlowMod(flowMod); break; case GROUP_MOD: OFGroupMod groupMod = (OFGroupMod) msg; processGroupMod(groupMod); break; case METER_MOD: OFMeterMod meterMod = (OFMeterMod) msg; processMeterMod(meterMod, channel); break; case TABLE_MOD: log.debug("processControllerCommand: {} not yet supported for {}", msg.getType(), msg); break; default: log.warn("Unexpected message {} received for switch {}", msg.getType(), this); } }
public OFMeterMod add() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.ADD.ordinal()); return builder.build(); }
public OFMeterMod remove() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.DELETE.ordinal()); return builder.build(); }
public OFMeterMod modify() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.MODIFY.ordinal()); return builder.build(); }
public OFMeterMod add() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.ADD); return builder.build(); }
public OFMeterMod remove() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.DELETE); return builder.build(); }
public OFMeterMod modify() { validate(); OFMeterMod.Builder builder = builderMeterMod(); builder.setCommand(OFMeterModCommand.MODIFY); return builder.build(); }
private MeterRequest.Builder meterRequestBuilder(OFMeterMod meterMod) { Collection<Band> bands = meterMod.getBands().stream() .map(ofMeterBand -> band(ofMeterBand)).collect(Collectors.toList()); return DefaultMeterRequest.builder().forDevice(deviceId) .withBands(bands).fromApp(ofSwitchService.appId()); }