@Override public TableType getTableType(TableId tid) { switch (tid.getValue()) { case DELL_TABLE_IPV4_UNICAST: return TableType.IP; case DELL_TABLE_MPLS: return TableType.MPLS; case DELL_TABLE_ACL: return TableType.ACL; case DELL_TABLE_VLAN: return TableType.VLAN; case DELL_TABLE_TMAC: return TableType.ETHER; default: log.error("Table type for Table id {} is not supported in the driver", tid); return TableType.NONE; } }
private void sendFlowStatistic() { if (sw.getRole() != RoleState.MASTER) { return; } Match match = sw.factory().buildMatch().build(); //Long statsXid = xidAtomic.getAndIncrement(); OFFlowStatsRequest statsRequest = sw.factory() .buildFlowStatsRequest() .setXid(1127) .setMatch(match) .setOutPort(OFPort.ANY) .setTableId(TableId.ALL) .build(); sw.sendMsg(statsRequest); }
@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; }
private void ofFlowStatsRequestAllSend() { OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest() .setMatch(sw.factory().matchWildcardAll()) .setTableId(TableId.ALL) .setOutPort(OFPort.NO_MASK) .build(); synchronized (this) { // set the request xid to check the reply in OpenFlowRuleProvider // After processing the reply of this request message, // this must be set to NO_FLOW_MISSING_XID(-1) by provider setFlowMissingXid(request.getXid()); log.debug("ofFlowStatsRequestAllSend: request={}, dpid={}", request.toString(), sw.getStringId()); sw.sendMsg(request); } }
/** * 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()); }
protected OFTableFeaturesStatsReply createTableFeaturesStatsReply() { OFTableFeaturesStatsReply statsReply = factory.buildTableFeaturesStatsReply() .setEntries(Collections.singletonList(factory.buildTableFeatures() .setConfig(0) .setMaxEntries(100) .setMetadataMatch(U64.NO_MASK) .setMetadataWrite(U64.NO_MASK) .setName("MyTable") .setTableId(TableId.of(1)) .setProperties(Collections.singletonList((OFTableFeatureProp)factory.buildTableFeaturePropMatch() .setOxmIds(Collections.singletonList(U32.of(100))) .build()) ).build() ) ).build(); return statsReply; }
/** * {@inheritDoc} */ @Override public OFFlowStatsReply dumpFlowTable(final DatapathId dpid) { OFFlowStatsReply values = null; IOFSwitch sw = ofSwitchService.getSwitch(dpid); if (sw == null) { throw new IllegalArgumentException(String.format("Switch %s was not found", dpid.toString())); } OFFactory ofFactory = sw.getOFFactory(); OFFlowStatsRequest flowRequest = ofFactory.buildFlowStatsRequest() .setMatch(sw.getOFFactory().matchWildcardAll()) .setTableId(TableId.ALL) .setOutPort(OFPort.ANY) .setOutGroup(OFGroup.ANY) .setCookieMask(U64.ZERO) .build(); try { ListenableFuture<OFFlowStatsReply> future = sw.writeRequest(flowRequest); values = future.get(10, TimeUnit.SECONDS); } catch (ExecutionException | InterruptedException | TimeoutException e) { logger.error("Could not get flow stats: {}", e.getMessage()); } return values; }
@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); }
@Override public final void sendMsg(OFMessage m) { OFMessage newMsg = m; if (m.getType() == OFType.STATS_REQUEST) { OFStatsRequest sr = (OFStatsRequest) m; log.debug("Rebuilding stats request type {}", sr.getStatsType()); switch (sr.getStatsType()) { case FLOW: OFCalientFlowStatsRequest request = this.factory().buildCalientFlowStatsRequest() .setCookie(((OFFlowStatsRequest) sr).getCookie()) .setCookieMask(((OFFlowStatsRequest) sr).getCookieMask()) .setMatch(this.factory().matchWildcardAll()) .setOutGroup(((OFFlowStatsRequest) sr).getOutGroup().getGroupNumber()) .setOutPort(OFPort.ANY) .setTableId(TableId.ALL) .setXid(sr.getXid()) .setFlags(sr.getFlags()) .build(); newMsg = request; break; case PORT: // TODO break; default: break; } } super.sendMsg(newMsg); }
private void sendAggregateStatistic() { if (sw.getRole() != RoleState.MASTER) { return; } Match match = sw.factory().buildMatch().build(); //Long statsXid = xidAtomic.getAndIncrement(); OFAggregateStatsRequest statsRequest = sw.factory().buildAggregateStatsRequest() .setMatch(match) .setOutPort(OFPort.ANY) .setTableId(TableId.ALL) .setXid(1126) .build(); sw.sendMsg(statsRequest); }
@Override public void run() { if (sw.getRole() == RoleState.MASTER) { log.trace("Collecting stats for {}", sw.getStringId()); OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest() .setMatch(sw.factory().matchWildcardAll()) .setTableId(TableId.ALL) .setOutPort(OFPort.NO_MASK) .build(); sw.sendMsg(request); } }
private void ofFlowStatsRequestFlowSend(FlowEntry fe) { // set find match Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(), Optional.of(driverService)).buildMatch(); // set find tableId TableId tableId = TableId.of(fe.tableId()); // set output port Instruction ins = fe.treatment().allInstructions().stream() .filter(i -> (i.type() == Instruction.Type.OUTPUT)) .findFirst() .orElse(null); OFPort ofPort = OFPort.NO_MASK; if (ins != null) { Instructions.OutputInstruction out = (Instructions.OutputInstruction) ins; ofPort = OFPort.of((int) ((out.port().toLong()))); } OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest() .setMatch(match) .setTableId(tableId) .setOutPort(ofPort) .build(); synchronized (this) { if (getFlowMissingXid() != NO_FLOW_MISSING_XID) { log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet," + " set no flow missing xid anyway, for {}", sw.getStringId()); setFlowMissingXid(NO_FLOW_MISSING_XID); } sw.sendMsg(request); } }
@Override public void switchActivated(DatapathId switchId) { IOFSwitch sw = switchService.getSwitch(switchId); if (sw == null) { log.warn("Switch {} was activated but had no switch object in the switch service. Perhaps it quickly disconnected", switchId); return; } if (OFDPAUtils.isOFDPASwitch(sw)) { sw.write(sw.getOFFactory().buildFlowDelete() .setTableId(TableId.ALL) .build() ); sw.write(sw.getOFFactory().buildGroupDelete() .setGroup(OFGroup.ANY) .setGroupType(OFGroupType.ALL) .build() ); sw.write(sw.getOFFactory().buildGroupDelete() .setGroup(OFGroup.ANY) .setGroupType(OFGroupType.INDIRECT) .build() ); sw.write(sw.getOFFactory().buildBarrierRequest().build()); List<OFPortModeTuple> portModes = new ArrayList<OFPortModeTuple>(); for (OFPortDesc p : sw.getPorts()) { portModes.add(OFPortModeTuple.of(p.getPortNo(), OFPortMode.ACCESS)); } if (log.isWarnEnabled()) { log.warn("For OF-DPA switch {}, initializing VLAN {} on ports {}", new Object[] { switchId, VlanVid.ZERO, portModes}); } OFDPAUtils.addLearningSwitchPrereqs(sw, VlanVid.ZERO, portModes); } }
/** * @param sw * the switch object that we wish to get flows from * @param outPort * the output action port we wish to find flows with * @return a list of OFFlowStatisticsReply objects or essentially flows */ public List<OFFlowStatsReply> getFlows(IOFSwitch sw, OFPort outPort) { statsReply = new ArrayList<OFFlowStatsReply>(); List<OFFlowStatsReply> values = null; Future<List<OFFlowStatsReply>> future; // Statistics request object for getting flows OFFlowStatsRequest req = sw.getOFFactory().buildFlowStatsRequest() .setMatch(sw.getOFFactory().buildMatch().build()) .setOutPort(outPort) .setTableId(TableId.ALL) .build(); try { // System.out.println(sw.getStatistics(req)); future = sw.writeStatsRequest(req); values = future.get(10, TimeUnit.SECONDS); if (values != null) { for (OFFlowStatsReply stat : values) { statsReply.add(stat); } } } catch (Exception e) { log.error("Failure retrieving statistics from switch " + sw, e); } return statsReply; }
public OFSwitch(IOFConnectionBackend connection, @Nonnull OFFactory factory, @Nonnull IOFSwitchManager switchManager, @Nonnull DatapathId datapathId) { if(connection == null) throw new NullPointerException("connection must not be null"); if(!connection.getAuxId().equals(OFAuxId.MAIN)) throw new IllegalArgumentException("connection must be the main connection"); if(factory == null) throw new NullPointerException("factory must not be null"); if(switchManager == null) throw new NullPointerException("switchManager must not be null"); this.connected = true; this.factory = factory; this.switchManager = switchManager; this.datapathId = datapathId; this.attributes = new ConcurrentHashMap<Object, Object>(); this.role = null; this.description = new SwitchDescription(); this.portManager = new PortManager(); this.status = SwitchStatus.HANDSHAKE; // Connections this.connections = new ConcurrentHashMap<OFAuxId, IOFConnectionBackend>(); this.connections.put(connection.getAuxId(), connection); // Switch's controller connection this.controllerConnections = ImmutableMap.of(); // Defaults properties for an ideal switch this.setAttribute(PROP_FASTWILDCARDS, EnumSet.allOf(OFFlowWildcards.class)); this.setAttribute(PROP_SUPPORTS_OFPP_FLOOD, Boolean.TRUE); this.setAttribute(PROP_SUPPORTS_OFPP_TABLE, Boolean.TRUE); this.tableFeaturesByTableId = new HashMap<TableId, TableFeatures>(); this.tables = new ArrayList<TableId>(); this.securityKernel = switchManager.getSecurityKernelService(); }
@Override public TableId setMaxTableForTableMissFlow(TableId max) { if (max.getValue() >= nTables) { maxTableToGetTableMissFlow = TableId.of(nTables - 1 < 0 ? 0 : nTables - 1); } else { maxTableToGetTableMissFlow = max; } return maxTableToGetTableMissFlow; }
/** * Adds an initial table-miss flow to each * and every table on the switch. This replaces the default behavior of * forwarding table-miss packets to the controller. The table-miss flows * inserted will forward all packets that do not match a flow to the * controller for processing. * * Adding the default flow only applies to OpenFlow 1.3+ switches, which * remove the default forward-to-controller behavior of flow tables. */ private void addDefaultFlows() { /* * Only for OF1.3+, insert the default forward-to-controller flow for * each table. This is priority=0 with no Match. */ if (this.sw.getOFFactory().getVersion().compareTo(OFVersion.OF_13) >= 0) { /* * Remove the default flow if it's present. */ OFFlowDeleteStrict deleteFlow = this.factory.buildFlowDeleteStrict() .setTableId(TableId.ALL) .setOutPort(OFPort.CONTROLLER) .build(); this.sw.write(deleteFlow); ArrayList<OFAction> actions = new ArrayList<OFAction>(1); actions.add(factory.actions().output(OFPort.CONTROLLER, 0xffFFffFF)); ArrayList<OFMessage> flows = new ArrayList<OFMessage>(); for (int tableId = 0; tableId < this.sw.getTables(); tableId++) { OFFlowAdd defaultFlow = this.factory.buildFlowAdd() .setTableId(TableId.of(tableId)) .setPriority(0) .setActions(actions) .build(); flows.add(defaultFlow); } this.sw.write(flows); } }
public OFSwitch(IOFConnectionBackend connection, @Nonnull OFFactory factory, @Nonnull IOFSwitchManager switchManager, @Nonnull DatapathId datapathId) { if(connection == null) throw new NullPointerException("connection must not be null"); if(!connection.getAuxId().equals(OFAuxId.MAIN)) throw new IllegalArgumentException("connection must be the main connection"); if(factory == null) throw new NullPointerException("factory must not be null"); if(switchManager == null) throw new NullPointerException("switchManager must not be null"); this.connected = true; this.factory = factory; this.switchManager = switchManager; this.datapathId = datapathId; this.attributes = new ConcurrentHashMap<Object, Object>(); this.role = null; this.description = new SwitchDescription(); this.portManager = new PortManager(); this.status = SwitchStatus.HANDSHAKE; // Connections this.connections = new ConcurrentHashMap<OFAuxId, IOFConnectionBackend>(); this.connections.put(connection.getAuxId(), connection); // Switch's controller connection this.controllerConnections = ImmutableMap.of(); // Defaults properties for an ideal switch this.setAttribute(PROP_FASTWILDCARDS, EnumSet.allOf(OFFlowWildcards.class)); this.setAttribute(PROP_SUPPORTS_OFPP_FLOOD, Boolean.TRUE); this.setAttribute(PROP_SUPPORTS_OFPP_TABLE, Boolean.TRUE); this.tableFeaturesByTableId = new HashMap<TableId, TableFeatures>(); this.tables = new ArrayList<TableId>(); }