/** * Builds a switch message type. * * @param sw switch instance * @param eventType type of event * @return Message */ private Message buildSwitchMessage(final IOFSwitch sw, final SwitchState eventType) { String switchId = sw.getId().toString(); InetSocketAddress address = (InetSocketAddress) sw.getInetAddress(); InetSocketAddress controller =(InetSocketAddress) sw.getConnectionByCategory( LogicalOFMessageCategory.MAIN).getRemoteInetAddress(); InfoData data = new SwitchInfoData( switchId, eventType, String.format("%s:%d", address.getHostString(), address.getPort()), address.getHostName(), String.format("%s %s %s", sw.getSwitchDescription().getManufacturerDescription(), sw.getOFFactory().getVersion().toString(), sw.getSwitchDescription().getSoftwareDescription()), controller.getHostString()); return buildMessage(data); }
@Test public void testInvalidLogicalOFMessageCategory() { LogicalOFMessageCategory bad = new LogicalOFMessageCategory("bad", 2); assertFalse("Controller should not any logical OFMessage categories", switchManager.isCategoryRegistered(bad)); reset(switchManager); expect(switchManager.isCategoryRegistered(bad)).andReturn(false); replay(switchManager); try{ sw.write(testMessage, bad); fail("Expected exception not thrown"); } catch(IllegalArgumentException e){ /* expected */ } verify(switchManager); }
@Test public void testValidLogicalOFMessageCategory() { LogicalOFMessageCategory category = new LogicalOFMessageCategory("test", 1); assertFalse("Controller should not have any logical OFMessage categories", switchManager.isCategoryRegistered(category)); reset(switchManager); expect(switchManager.isCategoryRegistered(category)).andReturn(true); switchManager.handleOutgoingMessage(sw, testMessage); expectLastCall().once(); replay(switchManager); sw.write(testMessage, category); verify(switchManager); }
/** * Initialize internal data structures */ public void init(Map<String, String> configParams) throws FloodlightModuleException { this.moduleLoaderState = ModuleLoaderState.INIT; // These data structures are initialized here because other // module's startUp() might be called before ours this.messageListeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType, IOFMessageListener>>(); this.haListeners = new ListenerDispatcher<HAListenerTypeMarker, IHAListener>(); this.controllerNodeIPsCache = new HashMap<String, String>(); this.updates = new LinkedBlockingQueue<IUpdate>(); this.providerMap = new HashMap<String, List<IInfoProvider>>(); setConfigParams(configParams); HARole initialRole = getInitialRole(configParams); this.notifiedRole = initialRole; this.shutdownService = new ShutdownServiceImpl(); this.roleManager = new RoleManager(this, this.shutdownService, this.notifiedRole, INITIAL_ROLE_CHANGE_DESCRIPTION); this.timer = new HashedWheelTimer(); // Switch Service Startup this.switchService.registerLogicalOFMessageCategory(LogicalOFMessageCategory.MAIN); this.switchService.addOFSwitchListener(new NotificationSwitchListener()); this.counters = new ControllerCounters(debugCounterService); }
public IOFConnection getConnection(LogicalOFMessageCategory category) { if (switchManager.isCategoryRegistered(category)) { return getConnection(category.getAuxId()); } else{ throw new IllegalArgumentException(category + " is not registered with the floodlight provider service."); } }
/** * Initialize internal data structures */ public void init(Map<String, String> configParams) throws FloodlightModuleException { this.moduleLoaderState = ModuleLoaderState.INIT; // These data structures are initialized here because other // module's startUp() might be called before ours this.messageListeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType, IOFMessageListener>>(); this.haListeners = new ListenerDispatcher<HAListenerTypeMarker, IHAListener>(); this.controllerNodeIPsCache = new HashMap<String, String>(); this.updates = new LinkedBlockingQueue<IUpdate>(); this.providerMap = new HashMap<String, List<IInfoProvider>>(); this.completionListeners = new ConcurrentLinkedQueue<IControllerCompletionListener>(); setConfigParams(configParams); HARole initialRole = getInitialRole(configParams); this.notifiedRole = initialRole; this.shutdownService = new ShutdownServiceImpl(); this.roleManager = new RoleManager(this, this.shutdownService, this.notifiedRole, INITIAL_ROLE_CHANGE_DESCRIPTION); this.timer = new HashedWheelTimer(); // Switch Service Startup this.switchService.registerLogicalOFMessageCategory(LogicalOFMessageCategory.MAIN); this.switchService.addOFSwitchListener(new NotificationSwitchListener()); this.counters = new ControllerCounters(debugCounterService); }
private int calcNumRequiredConnections() { if(!this.logicalOFMessageCategories.isEmpty()){ // We use tree set here to maintain ordering TreeSet<OFAuxId> auxConnections = new TreeSet<OFAuxId>(); for(LogicalOFMessageCategory category : this.logicalOFMessageCategories){ auxConnections.add(category.getAuxId()); } OFAuxId first = auxConnections.first(); OFAuxId last = auxConnections.last(); // Check for contiguous set (1....size()) if(first.equals(OFAuxId.MAIN)) { if(last.getValue() != auxConnections.size() - 1){ throw new IllegalStateException("Logical OF message categories must maintain contiguous OF Aux Ids! i.e. (0,1,2,3,4,5)"); } return auxConnections.size() - 1; } else if(first.equals(OFAuxId.of(1))) { if(last.getValue() != auxConnections.size()){ throw new IllegalStateException("Logical OF message categories must maintain contiguous OF Aux Ids! i.e. (1,2,3,4,5)"); } return auxConnections.size(); } else { throw new IllegalStateException("Logical OF message categories must start at 0 (MAIN) or 1"); } } else { return 0; } }
@Test public void testRegisterCategory() { // Must be in INIT state Timer timer = createMock(Timer.class); replay(timer); switchManager = new OFSwitchManager(); switchManager.loadLogicalCategories(); assertTrue("Connections should be empty", switchManager.getNumRequiredConnections() == 0); // Add initial category switchManager = new OFSwitchManager(); LogicalOFMessageCategory category = new LogicalOFMessageCategory("aux1", 1); switchManager.registerLogicalOFMessageCategory(category); switchManager.loadLogicalCategories(); assertTrue("Required connections should be 1", switchManager.getNumRequiredConnections() == 1); // Multiple categories on the same auxId should produce one required connection switchManager = new OFSwitchManager(); switchManager.registerLogicalOFMessageCategory(new LogicalOFMessageCategory("aux1", 1)); switchManager.registerLogicalOFMessageCategory(new LogicalOFMessageCategory("aux1-2", 1)); switchManager.loadLogicalCategories(); assertTrue("Required connections should be 1", switchManager.getNumRequiredConnections() == 1); // Adding a category on a different aux ID should increase the required connection count switchManager = new OFSwitchManager(); switchManager.registerLogicalOFMessageCategory(new LogicalOFMessageCategory("aux1", 1)); switchManager.registerLogicalOFMessageCategory(new LogicalOFMessageCategory("aux2", 2)); switchManager.loadLogicalCategories(); assertTrue("Required connections should be 2", switchManager.getNumRequiredConnections() == 2); }
@Test public void testMasterSlaveWrites() { OFFactory factory = OFFactories.getFactory(OFVersion.OF_13); OFFlowAdd fa = factory.buildFlowAdd().build(); OFFlowStatsRequest fsr = factory.buildFlowStatsRequest().build(); List<OFMessage> msgList = new ArrayList<OFMessage>(); msgList.add(fa); msgList.add(fsr); reset(switchManager); expect(switchManager.isCategoryRegistered(LogicalOFMessageCategory.MAIN)).andReturn(true).times(6); switchManager.handleOutgoingMessage(sw, fa); expectLastCall().times(2); switchManager.handleOutgoingMessage(sw, fsr); expectLastCall().times(4); replay(switchManager); /* test master -- both messages should be written */ sw.setControllerRole(OFControllerRole.ROLE_MASTER); assertTrue(sw.write(fa)); assertTrue(sw.write(fsr)); assertEquals(Collections.<OFMessage>emptyList(), sw.write(msgList)); /* test slave -- flow-add (mod op) should fail each time; flow stats (read op) should pass */ sw.setControllerRole(OFControllerRole.ROLE_SLAVE); assertFalse(sw.write(fa)); /* flow-add should be stopped (mod op) */ assertTrue(sw.write(fsr)); /* stats request makes it (read op) */ assertEquals(Collections.<OFMessage>singletonList(fa), sw.write(msgList)); /* return bad flow-add */ }
@Override public Collection<OFMessage> write(Iterable<OFMessage> msgList, LogicalOFMessageCategory category) { IOFConnection conn = this.getConnection(category); /* do first to check for supported category */ Collection<OFMessage> validMsgs = new ArrayList<OFMessage>(); Collection<OFMessage> invalidMsgs = SwitchRoleMessageValidator.pruneInvalidMessages( msgList, validMsgs, this.getOFFactory().getVersion(), this.isActive()); if (log.isDebugEnabled()) { log.debug("MESSAGES: {}, VALID: {}, INVALID: {}", new Object[] { msgList, validMsgs, invalidMsgs}); } /* Try to write all valid messages */ Collection<OFMessage> unsent = conn.write(validMsgs); for (OFMessage m : validMsgs) { if (!unsent.contains(m)) { switchManager.handleOutgoingMessage(this, m); } } /* Collect invalid and unsent messages */ Collection<OFMessage> ret = null; if (!unsent.isEmpty()) { log.warn("Could not send messages {} due to channel disconnection on switch {}", unsent, this.getId()); ret = IterableUtils.toCollection(unsent); } if (!invalidMsgs.isEmpty()) { log.warn("Could not send messages {} while in SLAVE role on switch {}", invalidMsgs, this.getId()); if (ret == null) { ret = IterableUtils.toCollection(invalidMsgs); } else { ret.addAll(IterableUtils.toCollection(invalidMsgs)); } } if (ret == null) { return Collections.emptyList(); } else { return ret; } }
@Override public boolean isCategoryRegistered(LogicalOFMessageCategory category) { return false; }
@Override public void registerLogicalOFMessageCategory(LogicalOFMessageCategory category) { // do nothing }
/** * TODO This method must be moved to a layer below forwarding * so that anyone can use it. * @param packetData * @param sw * @param ports * @param cntx */ public void doMultiActionPacketOut(byte[] packetData, IOFSwitch sw, Set<OFPort> ports, FloodlightContext cntx) { if (ports == null) return; if (packetData == null || packetData.length <= 0) return; //OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT); OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); List<OFAction> actions = new ArrayList<OFAction>(); for(OFPort p: ports) { //actions.add(new OFActionOutput(p, (short) 0)); actions.add(sw.getOFFactory().actions().output(p, 0)); } // set actions pob.setActions(actions); // set action length //po.setActionsLength((short) (OFActionOutput.MINIMUM_LENGTH * ports.size())); // set buffer-id to BUFFER_ID_NONE pob.setBufferId(OFBufferId.NO_BUFFER); // set in-port to OFPP_NONE pob.setInPort(OFPort.ZERO); // set packet data pob.setData(packetData); // compute and set packet length. //short poLength = (short)(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength() + packetData.length); //po.setLength(poLength); //ctrIncoming.updatePktOutFMCounterStore(sw, po); if (log.isTraceEnabled()) { log.trace("write broadcast packet on switch-id={} " + "interaces={} packet-data={} packet-out={}", new Object[] {sw.getId(), ports, packetData, pob.build()}); } sw.write(pob.build(), LogicalOFMessageCategory.MAIN); }
@Override public boolean write(OFMessage m, LogicalOFMessageCategory category) { return this.write(Collections.singletonList(m), category).isEmpty(); }
@Override public OFConnection getConnectionByCategory(LogicalOFMessageCategory category){ return (OFConnection) this.getConnection(category); }
@Override public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request, LogicalOFMessageCategory category) { return getConnection(category).writeRequest(request); }
@Override public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request) { return writeRequest(request, LogicalOFMessageCategory.MAIN); }