/** * {@inheritDoc} */ @Override public ImmutablePair<Long, Boolean> installTransitFlow(final DatapathId dpid, final String flowId, final Long cookie, final int inputPort, final int outputPort, final int transitVlanId) { List<OFAction> actionList = new ArrayList<>(); IOFSwitch sw = ofSwitchService.getSwitch(dpid); // build match by input port and transit vlan id Match match = matchFlow(sw, inputPort, transitVlanId); // transmit packet from outgoing port actionList.add(actionSetOutputPort(sw, outputPort)); // build instruction with action list OFInstructionApplyActions actions = buildInstructionApplyActions(sw, actionList); // build FLOW_MOD command, no meter OFFlowMod flowMod = buildFlowMod(sw, match, null, actions, cookie & FLOW_COOKIE_MASK, FlowModUtils.PRIORITY_VERY_HIGH); // send FLOW_MOD to the switch boolean response = pushFlow(flowId, dpid, flowMod); return new ImmutablePair<>(flowMod.getXid(), response); }
/** * Create an OFFlowMod that can be passed to StaticEntryPusher. * * @param sw switch object * @param match match for the flow * @param meter meter for the flow * @param actions actions for the flow * @param cookie cookie for the flow * @param priority priority to set on the flow * @return {@link OFFlowMod} */ private OFFlowMod buildFlowMod(final IOFSwitch sw, final Match match, final OFInstructionMeter meter, final OFInstructionApplyActions actions, final long cookie, final int priority) { OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd(); fmb.setIdleTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setHardTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setBufferId(OFBufferId.NO_BUFFER); fmb.setCookie(U64.of(cookie)); fmb.setPriority(priority); List<OFInstruction> instructions = new ArrayList<>(2); if (meter != null) { // If no meter then no bandwidth limit instructions.add(meter); } if (actions != null) { // If no instruction then Drops packet instructions.add(actions); } if (match != null) { // If no then match everything fmb.setMatch(match); } return fmb.setInstructions(instructions).build(); }
/** * Installs the verification rule * * @param dpid datapathId of switch * @param isBroadcast if broadcast then set a generic match; else specific to switch Id * @return true if the command is accepted to be sent to switch, false otherwise - switch is disconnected or in * SLAVE mode */ private boolean installVerificationRule(final DatapathId dpid, final boolean isBroadcast) { IOFSwitch sw = ofSwitchService.getSwitch(dpid); Match match = matchVerification(sw, isBroadcast); ArrayList<OFAction> actionList = new ArrayList<>(2); actionList.add(actionSendToController(sw)); actionList.add(actionSetDstMac(sw, dpidToMac(sw))); OFInstructionApplyActions instructionApplyActions = sw.getOFFactory().instructions() .applyActions(actionList).createBuilder().build(); final long cookie = isBroadcast ? 0x8000000000000002L : 0x8000000000000003L; OFFlowMod flowMod = buildFlowMod(sw, match, null, instructionApplyActions, cookie, FlowModUtils.PRIORITY_VERY_HIGH); String flowname = (isBroadcast) ? "Broadcast" : "Unicast"; flowname += "--VerificationFlow--" + dpid.toString(); return pushFlow(flowname, dpid, flowMod); }
@Override public void sendMsg(OFMessage msg) { // Ignore everything but flow mods and stat requests if (!(msg instanceof OFFlowMod || msg instanceof OFFlowStatsRequest)) { super.sendMsg(msg); return; } Match newMatch; OFMessage newMsg = null; if (msg instanceof OFFlowStatsRequest) { // Rewrite match only OFFlowStatsRequest fsr = (OFFlowStatsRequest) msg; newMatch = rewriteMatch(fsr.getMatch()); newMsg = fsr.createBuilder().setMatch(newMatch).build(); } else if (msg instanceof OFFlowMod) { // Rewrite match and actions OFFlowMod fm = (OFFlowMod) msg; newMatch = rewriteMatch(fm.getMatch()); List<OFAction> actions = rewriteActions(fm.getActions()); newMsg = fm.createBuilder().setMatch(newMatch).setActions(actions).build(); } super.sendMsg(newMsg); }
@Override public OFFlowMod buildFlowDel() { Match match = buildMatch(); long cookie = flowRule().id().value(); OFFlowDeleteStrict fm = factory().buildFlowDeleteStrict() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .setMatch(match) .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) .setPriority(flowRule().priority()) .setTableId(TableId.of(flowRule().tableId())) .build(); return fm; }
@Override public OFFlowMod buildFlowMod() { Match match = buildMatch(); List<OFAction> actions = buildActions(); long cookie = flowRule().id().value(); OFFlowMod fm = factory().buildFlowModify() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .setActions(actions) .setMatch(match) .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) .setPriority(flowRule().priority()) .build(); return fm; }
private OFFlowMod createFRESCOFlowMod(IOFSwitch sw, Match match, List<OFAction> actions, int priority){ OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd();; fmb.setIdleTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setHardTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setBufferId(OFBufferId.NO_BUFFER); fmb.setOutPort(OFPort.ANY); fmb.setCookie(U64.of(0)); fmb.setPriority(U16.t(priority)); fmb.setMatch(match); fmb.setActions(actions); return fmb.build(); }
/** * Reads from our entriesFromStorage for the specified switch and * sends the FlowMods down to the controller in <b>sorted</b> order. * * Sorted is important to maintain correctness of the switch: * if a packet would match both a lower and a higher priority * rule, then we want it to match the higher priority or nothing, * but never just the lower priority one. Inserting from high to * low priority fixes this. * * TODO consider adding a "block all" flow mod and then removing it * while starting up. * * @param sw The switch to send entries to */ protected void sendEntriesToSwitch(DatapathId switchId) { IOFSwitch sw = switchService.getSwitch(switchId); if (sw == null) return; String stringId = sw.getId().toString(); if ((entriesFromStorage != null) && (entriesFromStorage.containsKey(stringId))) { Map<String, OFFlowMod> entries = entriesFromStorage.get(stringId); List<String> sortedList = new ArrayList<String>(entries.keySet()); // weird that Collections.sort() returns void Collections.sort( sortedList, new FlowModSorter(stringId)); for (String entryName : sortedList) { OFFlowMod flowMod = entries.get(entryName); if (flowMod != null) { if (log.isDebugEnabled()) { log.debug("Pushing static entry {} for {}", stringId, entryName); } writeFlowModToSwitch(sw, flowMod); } } } }
/** * Read entries from storageSource, and store them in a hash * * @return */ private Map<String, Map<String, OFFlowMod>> readEntriesFromStorage() { Map<String, Map<String, OFFlowMod>> entries = new ConcurrentHashMap<String, Map<String, OFFlowMod>>(); try { Map<String, Object> row; // null1=no predicate, null2=no ordering IResultSet resultSet = storageSourceService.executeQuery(TABLE_NAME, ColumnNames, null, null); for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) { row = it.next().getRow(); parseRow(row, entries); } } catch (StorageException e) { log.error("failed to access storage: {}", e.getMessage()); // if the table doesn't exist, then wait to populate later via // setStorageSource() } return entries; }
/** * Adds the instructions to the list of OFInstructions in the OFFlowMod. Any pre-existing * instruction of the same type is replaced with OFInstruction inst. * @param fmb, the flow mod to append the instruction to * @param inst, the instuction to append */ public static void appendInstruction(OFFlowMod.Builder fmb, OFInstruction inst) { List<OFInstruction> newIl = new ArrayList<OFInstruction>(); List<OFInstruction> oldIl = fmb.getInstructions(); if (oldIl != null) { // keep any existing instructions that were added earlier newIl.addAll(fmb.getInstructions()); } for (OFInstruction i : newIl) { // remove any duplicates. Only one of each instruction. if (i.getType() == inst.getType()) { newIl.remove(i); } } newIl.add(inst); fmb.setInstructions(newIl); }
/** * Convert the string representation of an OFInstructionGotoTable to * an OFInstructionGotoTable. The instruction will be set within the * OFFlowMod.Builder provided. Notice nothing is returned, but the * side effect is the addition of an instruction in the OFFlowMod.Builder. * @param fmb; The FMB in which to append the new instruction * @param instStr; The string to parse the instruction from * @param log */ public static void gotoTableFromString(OFFlowMod.Builder fmb, String inst, Logger log) { if (inst == null || inst.equals("")) { return; } if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) { log.error("Goto Table Instruction not supported in OpenFlow 1.0"); return; } OFInstructionGotoTable.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildGotoTable(); // Get the table ID if (inst.startsWith("0x")) { ib.setTableId(TableId.of(Integer.parseInt(inst.replaceFirst("0x", ""), 16))); } else { ib.setTableId(TableId.of(Integer.parseInt(inst))).build(); } log.debug("Appending GotoTable instruction: {}", ib.build()); appendInstruction(fmb, ib.build()); log.debug("All instructions after append: {}", fmb.getInstructions()); }
/** * Convert the string representation of an OFInstructionClearActions to * an OFInstructionClearActions. The instruction will be set within the * OFFlowMod.Builder provided. Notice nothing is returned, but the * side effect is the addition of an instruction in the OFFlowMod.Builder. * @param fmb; The FMB in which to append the new instruction * @param instStr; The string to parse the instruction from * @param log */ public static void clearActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) { if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) { log.error("Clear Actions Instruction not supported in OpenFlow 1.0"); return; } if (inst != null && inst.trim().isEmpty()) { /* Allow the empty string, since this is what specifies clear (i.e. key clear does not have any defined values). */ OFInstructionClearActions i = OFFactories.getFactory(fmb.getVersion()).instructions().clearActions(); log.debug("Appending ClearActions instruction: {}", i); appendInstruction(fmb, i); log.debug("All instructions after append: {}", fmb.getInstructions()); } else { log.error("Got non-empty or null string, but ClearActions should not have any String sub-fields: {}", inst); } }
/** * Convert the string representation of an OFInstructionExperimenter to * an OFInstructionExperimenter. The instruction will be set within the * OFFlowMod.Builder provided. Notice nothing is returned, but the * side effect is the addition of an instruction in the OFFlowMod.Builder. * @param fmb; The FMB in which to append the new instruction * @param instStr; The string to parse the instruction from * @param log */ public static void experimenterFromString(OFFlowMod.Builder fmb, String inst, Logger log) { /* TODO This is a no-op right now. */ /* if (inst == null || inst.equals("")) { return; // TODO @Ryan quietly fail? } OFInstructionExperimenter.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildExperimenter(); String[] keyValue = inst.split("="); if (keyValue.length != 2) { throw new IllegalArgumentException("[Key, Value] " + keyValue + " does not have form 'key=value' parsing " + inst); } switch (keyValue[0]) { case STR_SUB_GOTO_METER_METER_ID: ib.setExperimenter(Long.parseLong(keyValue[1])); break; default: log.error("Invalid String key for OFInstructionExperimenter: {}", keyValue[0]); } appendInstruction(fmb, ib.build()); */ }
/** * Convert the string representation of an OFInstructionMeter to * an OFInstructionMeter. The instruction will be set within the * OFFlowMod.Builder provided. Notice nothing is returned, but the * side effect is the addition of an instruction in the OFFlowMod.Builder. * @param fmb; The FMB in which to append the new instruction * @param instStr; The string to parse the instruction from * @param log */ public static void meterFromString(OFFlowMod.Builder fmb, String inst, Logger log) { if (inst == null || inst.isEmpty()) { return; } if (fmb.getVersion().compareTo(OFVersion.OF_13) < 0) { log.error("Goto Meter Instruction not supported in OpenFlow 1.0, 1.1, or 1.2"); return; } OFInstructionMeter.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildMeter(); if (inst.startsWith("0x")) { ib.setMeterId(Long.valueOf(inst.replaceFirst("0x", ""), 16)); } else { ib.setMeterId(Long.valueOf(inst)); } log.debug("Appending (Goto)Meter instruction: {}", ib.build()); appendInstruction(fmb, ib.build()); log.debug("All instructions after append: {}", fmb.getInstructions()); }
@Get("json") public OFFlowModMap ListStaticFlowEntries() { IStaticFlowEntryPusherService sfpService = (IStaticFlowEntryPusherService)getContext().getAttributes(). get(IStaticFlowEntryPusherService.class.getCanonicalName()); String param = (String) getRequestAttributes().get("switch"); if (log.isDebugEnabled()) log.debug("Listing all static flow entires for switch: " + param); if (param.toLowerCase().equals("all")) { return new OFFlowModMap(sfpService.getFlows()); } else { try { Map<String, Map<String, OFFlowMod>> retMap = new HashMap<String, Map<String, OFFlowMod>>(); retMap.put(param, sfpService.getFlows(DatapathId.of(param))); return new OFFlowModMap(retMap); } catch (NumberFormatException e){ setStatus(Status.CLIENT_ERROR_BAD_REQUEST, ControllerSwitchesResource.DPID_ERROR); } } return null; }
/** * Read entries from storageSource, and store them in a hash * * @return */ @LogMessageDoc(level="ERROR", message="failed to access storage: {reason}", explanation="Could not retrieve static flows from the system " + "database", recommendation=LogMessageDoc.CHECK_CONTROLLER) private Map<String, Map<String, OFFlowMod>> readEntriesFromStorage() { Map<String, Map<String, OFFlowMod>> entries = new ConcurrentHashMap<String, Map<String, OFFlowMod>>(); try { Map<String, Object> row; // null1=no predicate, null2=no ordering IResultSet resultSet = storageSourceService.executeQuery(TABLE_NAME, ColumnNames, null, null); for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) { row = it.next().getRow(); parseRow(row, entries); } } catch (StorageException e) { log.error("failed to access storage: {}", e.getMessage()); // if the table doesn't exist, then wait to populate later via // setStorageSource() } return entries; }
/** * {@inheritDoc} */ @Override public ImmutablePair<Long, Boolean> installEgressFlow(final DatapathId dpid, String flowId, final Long cookie, final int inputPort, final int outputPort, final int transitVlanId, final int outputVlanId, final OutputVlanType outputVlanType) { List<OFAction> actionList = new ArrayList<>(); IOFSwitch sw = ofSwitchService.getSwitch(dpid); // build match by input port and transit vlan id Match match = matchFlow(sw, inputPort, transitVlanId); // output action based on encap scheme actionList.addAll(outputVlanTypeToOFActionList(sw, outputVlanId, outputVlanType)); // transmit packet from outgoing port actionList.add(actionSetOutputPort(sw, outputPort)); // build instruction with action list OFInstructionApplyActions actions = buildInstructionApplyActions(sw, actionList); // build FLOW_MOD command, no meter OFFlowMod flowMod = buildFlowMod(sw, match, null, actions, cookie & FLOW_COOKIE_MASK, FlowModUtils.PRIORITY_VERY_HIGH); // send FLOW_MOD to the switch boolean response = pushFlow(flowId, dpid, flowMod); return new ImmutablePair<>(flowMod.getXid(), response); }
/** * Convert the string representation of an OFInstructionWriteActions to * an OFInstructionWriteActions. The instruction will be set within the * OFFlowMod.Builder provided. Notice nothing is returned, but the * side effect is the addition of an instruction in the OFFlowMod.Builder. * @param fmb; The FMB in which to append the new instruction * @param instStr; The string to parse the instruction from * @param log */ public static void writeActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) { if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) { log.error("Write Actions Instruction not supported in OpenFlow 1.0"); return; } OFFlowMod.Builder tmpFmb = OFFactories.getFactory(fmb.getVersion()).buildFlowModify(); // ActionUtils.fromString() will use setActions(), which should not be used for OF1.3; use temp to avoid overwriting any applyActions data OFInstructionWriteActions.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildWriteActions(); ActionUtils.fromString(tmpFmb, inst, log); ib.setActions(tmpFmb.getActions()); log.debug("Appending WriteActions instruction: {}", ib.build()); appendInstruction(fmb, ib.build()); log.debug("All instructions after append: {}", fmb.getInstructions()); }
private void verifyFlowMod(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) { verifyMatch(testFlowMod, goodFlowMod); verifyActions(testFlowMod, goodFlowMod); // dont' bother testing the cookie; just copy it over goodFlowMod = goodFlowMod.createBuilder().setCookie(testFlowMod.getCookie()).build(); // .. so we can continue to use .equals() assertTrue(OFMessageUtils.equalsIgnoreXid(goodFlowMod, testFlowMod)); }
@Test public void installIngressFlowPushAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installIngressFlow(dpid, cookieHex, cookie, inputPort, outputPort, 0, transitVlanId, OutputVlanType.PUSH, meterId); assertEquals( scheme.ingressPushFlowMod(inputPort, outputPort, transitVlanId, meterId, cookie), capture.getValue()); }
@Test public void installEgressFlowNoneAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installEgressFlow(dpid, cookieHex, cookie, inputPort, outputPort, transitVlanId, 0, OutputVlanType.NONE); assertEquals( scheme.egressNoneFlowMod(inputPort, outputPort, transitVlanId, cookie), capture.getValue()); }
@Test public void installEgressFlowPushAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installEgressFlow(dpid, cookieHex, cookie, inputPort, outputPort, transitVlanId, outputVlanId, OutputVlanType.PUSH); assertEquals( scheme.egressPushFlowMod(inputPort, outputPort, transitVlanId, outputVlanId, cookie), capture.getValue()); }
@Test public void installEgressFlowReplaceAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installEgressFlow(dpid, cookieHex, cookie, inputPort, outputPort, transitVlanId, outputVlanId, OutputVlanType.REPLACE); assertEquals( scheme.egressReplaceFlowMod(inputPort, outputPort, transitVlanId, outputVlanId, cookie), capture.getValue()); }
@Test public void installTransitFlow() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installTransitFlow(dpid, cookieHex, cookie, inputPort, outputPort, transitVlanId); assertEquals( scheme.transitFlowMod(inputPort, outputPort, transitVlanId, cookie), capture.getValue()); }
@Test public void installOneSwitchFlowReplaceAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installOneSwitchFlow(dpid, cookieHex, cookie, inputPort, outputPort, inputVlanId, outputVlanId, OutputVlanType.REPLACE, meterId); assertEquals( scheme.oneSwitchReplaceFlowMod(inputPort, outputPort, inputVlanId, outputVlanId, meterId, cookie), capture.getValue()); }
@Test public void installOneSwitchFlowPushAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installOneSwitchFlow(dpid, cookieHex, cookie, inputPort, outputPort, 0, outputVlanId, OutputVlanType.PUSH, meterId); assertEquals( scheme.oneSwitchPushFlowMod(inputPort, outputPort, outputVlanId, meterId, cookie), capture.getValue()); }
@Test public void installOneSwitchFlowPopAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installOneSwitchFlow(dpid, cookieHex, cookie, inputPort, outputPort, inputVlanId, 0, OutputVlanType.POP, meterId); assertEquals( scheme.oneSwitchPopFlowMod(inputPort, outputPort, inputVlanId, meterId, cookie), capture.getValue()); }
@Test public void installOneSwitchFlowNoneAction() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.installOneSwitchFlow(dpid, cookieHex, cookie, inputPort, outputPort, 0, 0, OutputVlanType.NONE, meterId); assertEquals( scheme.oneSwitchNoneFlowMod(inputPort, outputPort, meterId, cookie), capture.getValue()); }
@Test public void deleteFlow() throws Exception { Capture<OFFlowMod> capture = prepareForInstallTest(); switchManager.deleteFlow(dpid, cookieHex, cookie); final OFFlowMod actual = capture.getValue(); assertEquals(OFFlowModCommand.DELETE, actual.getCommand()); assertEquals(Long.valueOf(cookieHex, 16).longValue(), actual.getCookie().getValue()); assertEquals(SwitchManager.NON_SYSTEM_MASK, actual.getCookieMask()); }
public static OFFlowModifyStrict toFlowModifyStrict(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowModifyStrict.Builder b = OFFactories.getFactory(version).buildFlowModifyStrict(); if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } }
@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); }
public static OFFlowModify toFlowModify(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowModify.Builder b = OFFactories.getFactory(version).buildFlowModify(); if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } }
private void enforceBlockAction(BlockAction ba){ //block flow rule lists to instaled in data plane ArrayList<OFFlowMod> blockFMs = new ArrayList<>(); OFFlowMod blockFM; IDevice blockedDevice = getDeviceFromIP(ba.getBlockedIP()); if (blockedDevice == null){ log.error("[FRESCO] Block host " + IPv4Address.of(ba.getBlockedIP()) + " fail because cannot locate the host location"); return; } SwitchPort blockedLocation = getLocationFromDevice(blockedDevice); IOFSwitch inSW = switchService.getSwitch(blockedLocation.getSwitchDPID()); Match.Builder mb = inSW.getOFFactory().buildMatch(); mb.setExact(MatchField.IPV4_SRC, IPv4Address.of(ba.getBlockedIP())); List<OFAction> blockActions = new ArrayList<OFAction>(); blockFM = createFRESCOFlowMod(inSW, mb.build(), blockActions, SEC_PRIORITY_0); blockFMs.add(blockFM); //enforce block flow rules for (OFFlowMod fm : blockFMs){ try { messageDamper.write(inSW, fm); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) { OFPort inPort = (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)); Match m = createMatchFromPacket(sw, inPort, cntx); OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd(); // this will be a drop-flow; a flow that will not output to any ports List<OFAction> actions = new ArrayList<OFAction>(); // set no action to drop U64 cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0); log.info("Droppingggg"); fmb.setCookie(cookie) .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT) .setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setBufferId(OFBufferId.NO_BUFFER) .setMatch(m) .setPriority(FLOWMOD_DEFAULT_PRIORITY); FlowModUtils.setActions(fmb, actions, sw); try { if (log.isDebugEnabled()) { log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] { sw, m, fmb.build() }); } boolean dampened = messageDamper.write(sw, fmb.build()); log.debug("OFMessage dampened: {}", dampened); } catch (IOException e) { log.error("Failure writing drop flow mod", e); } }
/** * Writes a FlowMod to a switch that inserts a drop flow. * @param sw The switch to write the FlowMod to. * @param pi The corresponding OFPacketIn. Used to create the OFMatch structure. * @param cntx The FloodlightContext that gets passed to the switch. */ protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) { if (log.isTraceEnabled()) { log.trace("doDropFlow pi={} srcSwitch={}", new Object[] { pi, sw }); } if (sw == null) { log.warn("Switch is null, not installing drop flowmod for PacketIn {}", pi); return; } // Create flow-mod based on packet-in and src-switch OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowModify(); List<OFAction> actions = new ArrayList<OFAction>(); // no actions = drop U64 cookie = AppCookie.makeCookie(APP_ID, 0); fmb.setCookie(cookie) .setIdleTimeout(ForwardingBase.FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setHardTimeout(ForwardingBase.FLOWMOD_DEFAULT_HARD_TIMEOUT) .setBufferId(OFBufferId.NO_BUFFER) .setMatch(pi.getMatch()) .setActions(actions); if (log.isTraceEnabled()) { log.trace("write drop flow-mod srcSwitch={} match={} " + "pi={} flow-mod={}", new Object[] {sw, pi.getMatch(), pi, fmb.build()}); } sw.write(fmb.build()); return; }
public static OFFlowDelete toFlowDelete(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowDelete.Builder b = OFFactories.getFactory(version).buildFlowDelete(); if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setActions(fm.getActions()) .setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } }