public void dispatchMessage(IOFSwitch sw, OFMessage msg, FloodlightContext bc) { List<IOFMessageListener> theListeners = listeners.get(msg.getType()).getOrderedListeners(); if (theListeners != null) { Command result = Command.CONTINUE; Iterator<IOFMessageListener> it = theListeners.iterator(); if (OFType.PACKET_IN.equals(msg.getType())) { OFPacketIn pi = (OFPacketIn)msg; Ethernet eth = new Ethernet(); eth.deserialize(pi.getData(), 0, pi.getData().length); IFloodlightProviderService.bcStore.put(bc, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } while (it.hasNext() && !Command.STOP.equals(result)) { result = it.next().receive(sw, msg, bc); } } // paag for (IControllerCompletionListener listener:completionListeners) listener.onMessageConsumed(sw, msg, bc); }
private void logListeners() { for (Map.Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> entry : listeners.entrySet()) { OFType type = entry.getKey(); ListenerDispatcher<OFType, IOFMessageListener> ldd = entry.getValue(); StringBuffer sb = new StringBuffer(); sb.append("OFListeners for "); sb.append(type); sb.append(": "); for (IOFMessageListener l : ldd.getOrderedListeners()) { sb.append(l.getName()); sb.append(","); } log.debug(sb.toString()); } }
@Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProviderService = context.getServiceImpl(IFloodlightProviderService.class); threadPoolService = context.getServiceImpl(IThreadPoolService.class); debugCounterService = context.getServiceImpl(IDebugCounterService.class); flowQueue = new PriorityPendingQueue<OFMatchReconcile>(); flowReconcileListeners = new ListenerDispatcher<OFType, IFlowReconcileListener>(); Map<String, String> configParam = context.getConfigParams(this); String enableValue = configParam.get(EnableConfigKey); registerFlowReconcileManagerDebugCounters(); // Set flowReconcile default to true flowReconcileEnabled = true; if (enableValue != null && enableValue.equalsIgnoreCase("false")) { flowReconcileEnabled = false; } flowReconcileThreadRunCount = new AtomicInteger(0); lastReconcileTime = new Date(0); logger.debug("FlowReconcile is {}", flowReconcileEnabled); }
@Override public void write(OFMessage m) { if (!isConnected()) { if (logger.isDebugEnabled()) logger.debug("{}: not connected - dropping message {}", this, m); return; } if (logger.isDebugEnabled()) logger.debug("{}: send {}", this, m); List<OFMessage> msgBuffer = localMsgBuffer.get(); if (msgBuffer == null) { msgBuffer = new ArrayList<OFMessage>(); localMsgBuffer.set(msgBuffer); } counters.updateWriteStats(m); msgBuffer.add(m); if ((msgBuffer.size() >= Controller.BATCH_MAX_SIZE) || ((m.getType() != OFType.PACKET_OUT) && (m.getType() != OFType.FLOW_MOD))) { this.write(msgBuffer); localMsgBuffer.set(null); } }
/** Move the channel from scratch to WAIT_DESCRIPTION_STAT_REPLY state * Builds on moveToWaitConfigReply() * adds testing for WAIT_CONFIG_REPLY state */ @Test public void moveToWaitDescriptionStatReply() throws Exception { moveToWaitConfigReply(); connection.clearMessages(); OFGetConfigReply cr = factory.buildGetConfigReply() .setMissSendLen(0xFFFF) .build(); switchHandler.processOFMessage(cr); OFMessage msg = connection.retrieveMessage(); assertEquals(OFType.STATS_REQUEST, msg.getType()); OFStatsRequest<?> sr = (OFStatsRequest<?>)msg; assertEquals(OFStatsType.DESC, sr.getStatsType()); verifyUniqueXids(msg); assertThat(switchHandler.getStateForTesting(), CoreMatchers.instanceOf(OFSwitchHandshakeHandler.WaitDescriptionStatReplyState.class)); }
@Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); deviceService = context.getServiceImpl(IDeviceService.class); routingService = context.getServiceImpl(IRoutingService.class); switchService = context.getServiceImpl(IOFSwitchService.class); linkService = context.getServiceImpl(ILinkDiscoveryService.class); messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY, EnumSet.of(OFType.FLOW_MOD), OFMESSAGE_DAMPER_TIMEOUT); library = new FP_LibFloodlight( LoggerFactory.getLogger( getClass() )); }
/** Move the channel from scratch to WAIT_CONFIG_REPLY state * adds testing for beginHandshake() which moves the state from * InitState to WaitConfigReply. */ @Test public void moveToWaitConfigReply() throws Exception { moveToPreConfigReply(); List<OFMessage> msgs = connection.getMessages(); assertEquals(3, msgs.size()); assertEquals(OFType.SET_CONFIG, msgs.get(0).getType()); OFSetConfig sc = (OFSetConfig)msgs.get(0); assertEquals(0xffff, sc.getMissSendLen()); assertEquals(OFType.BARRIER_REQUEST, msgs.get(1).getType()); assertEquals(OFType.GET_CONFIG_REQUEST, msgs.get(2).getType()); verifyUniqueXids(msgs); msgs.clear(); assertThat(switchHandler.getStateForTesting(), CoreMatchers.instanceOf(OFSwitchHandshakeHandler.WaitConfigReplyState.class)); verifyAll(); }
@Override public void startUp(FloodlightModuleContext context) { clearCurrentTopology(); // Initialize role to floodlight provider role. this.role = floodlightProviderService.getRole(); ScheduledExecutorService ses = threadPoolService.getScheduledExecutor(); newInstanceTask = new SingletonTask(ses, new UpdateTopologyWorker()); if (role != HARole.STANDBY) { newInstanceTask.reschedule(TOPOLOGY_COMPUTE_INTERVAL_MS, TimeUnit.MILLISECONDS); } linkDiscoveryService.addListener(this); floodlightProviderService.addOFMessageListener(OFType.PACKET_IN, this); floodlightProviderService.addHAListener(this.haListener); addRestletRoutable(); }
@Test public void moveToWaitHello() throws Exception { resetChannel(); channel.write(capture(writeCapture)); expectLastCall().andReturn(null).once(); replay(channel); // replay unused mocks replay(messageEvent); handler.channelConnected(ctx, channelStateEvent); List<OFMessage> msgs = getMessagesFromCapture(); assertEquals(1, msgs.size()); assertEquals(OFType.HELLO, msgs.get(0).getType()); assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitHelloState.class)); verifyUniqueXids(msgs); }
/** Move the channel from scratch to WAIT_FEATURES_REPLY state * Builds on moveToWaitHello() * adds testing for WAIT_HELLO state */ @Test public void moveToWaitFeaturesReply() throws Exception { moveToWaitHello(); resetChannel(); expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once(); replay(channel); OFMessage hello = factory.buildHello().build(); sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(hello)); List<OFMessage> msgs = getMessagesFromCapture(); assertEquals(1, msgs.size()); assertEquals(OFType.FEATURES_REQUEST, msgs.get(0).getType()); verifyUniqueXids(msgs); assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitFeaturesReplyState.class)); }
/** * Sorts any invalid messages by moving them from the msgList. The net result * is a new list returned containing the invalid messages and a pruned msgList * containing only those messages that are valid for the given role of the controller * and OpenFlow version of the switch. * * @param msgList the list of messages to sort * @param valid the list of valid messages (caller must allocate) * @param swVersion the OFVersion of the switch * @param isSlave true if controller is slave; false otherwise * @return list of messages that are not valid, removed from input parameter msgList */ protected static Collection<OFMessage> pruneInvalidMessages(Iterable<OFMessage> msgList, Collection<OFMessage> valid, OFVersion swVersion, boolean isActive) { if (isActive) { /* master or equal/other support all */ valid.addAll(IterableUtils.toCollection(msgList)); return Collections.emptyList(); } else { /* slave */ Set<OFType> invalidSlaveMsgs = invalidSlaveMsgsByOFVersion.get(swVersion); List<OFMessage> invalid = new ArrayList<OFMessage>(); Iterator<OFMessage> itr = msgList.iterator(); while (itr.hasNext()) { OFMessage m = itr.next(); if (invalidSlaveMsgs.contains(m.getType())) { invalid.add(m); } else { valid.add(m); } } return invalid; } }
/** Move the channel from scratch to WAIT_FEATURES_REPLY state * Builds on moveToWaitHello() * adds testing for WAIT_HELLO state */ @Test public void moveToWaitFeaturesReply() throws Exception { moveToWaitHello(); resetChannel(); channel.write(capture(writeCapture)); expectLastCall().andReturn(null).atLeastOnce(); replay(channel); OFMessage hello = factory.buildHello().build(); sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(hello)); List<OFMessage> msgs = getMessagesFromCapture(); assertEquals(1, msgs.size()); assertEquals(OFType.FEATURES_REQUEST, msgs.get(0).getType()); verifyUniqueXids(msgs); assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitFeaturesReplyState.class)); }
/** * 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); }
@Override public synchronized void addFlowReconcileListener( IFlowReconcileListener listener) { flowReconcileListeners.addListener(OFType.FLOW_MOD, listener); if (logger.isTraceEnabled()) { StringBuffer sb = new StringBuffer(); sb.append("FlowMod listeners: "); for (IFlowReconcileListener l : flowReconcileListeners.getOrderedListeners()) { sb.append(l.getName()); sb.append(","); } logger.trace(sb.toString()); } }
@Override public void startUp(FloodlightModuleContext context) { floodlightProviderService.addOFMessageListener(OFType.PACKET_IN, this); restApiService.addRestletRoutable(new LoadBalancerWebRoutable()); debugCounterService.registerModule(this.getName()); counterPacketOut = debugCounterService.registerCounter(this.getName(), "packet-outs-written", "Packet outs written by the LoadBalancer", MetaData.WARN); }
/** * {@inheritDoc} */ @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { logger.info("Starting " + SwitchEventCollector.class.getCanonicalName()); restApiService.addRestletRoutable(new SwitchManagerWebRoutable()); floodlightProvider.addOFMessageListener(OFType.ERROR, this); }
/** * {@inheritDoc} */ @Override public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { logger.debug("OF_ERROR: {}", msg); // TODO: track xid for flow id if (OFType.ERROR.equals(msg.getType())) { ErrorMessage error = new ErrorMessage( new ErrorData(ErrorType.INTERNAL_ERROR, ((OFErrorMsg) msg).getErrType().toString(), null), System.currentTimeMillis(), DEFAULT_CORRELATION_ID, Destination.WFM_TRANSACTION); // TODO: Most/all commands are flow related, but not all. 'kilda.flow' might // not be the best place to send a generic error. kafkaProducer.postMessage("kilda.flow", error); } return Command.CONTINUE; }
@Test public void testHandleMessageWithContext() throws Exception { IOFSwitch sw = createMock(IOFSwitch.class); expect(sw.getId()).andReturn(DatapathId.NONE).anyTimes(); IOFMessageListener test1 = createMock(IOFMessageListener.class); expect(test1.getName()).andReturn("test1").anyTimes(); expect(test1.isCallbackOrderingPrereq((OFType)anyObject(), (String)anyObject())) .andReturn(false).anyTimes(); expect(test1.isCallbackOrderingPostreq((OFType)anyObject(), (String)anyObject())) .andReturn(false).anyTimes(); FloodlightContext cntx = new FloodlightContext(); expect(test1.receive(same(sw), same(pi) , same(cntx))) .andReturn(Command.CONTINUE); IOFMessageListener test2 = createMock(IOFMessageListener.class); expect(test2.getName()).andReturn("test2").anyTimes(); expect(test2.isCallbackOrderingPrereq((OFType)anyObject(), (String)anyObject())) .andReturn(false).anyTimes(); expect(test2.isCallbackOrderingPostreq((OFType)anyObject(), (String)anyObject())) .andReturn(false).anyTimes(); // test2 will not receive any message! replay(test1, test2, sw); controller.addOFMessageListener(OFType.PACKET_IN, test1); controller.addOFMessageListener(OFType.ERROR, test2); controller.handleMessage(sw, pi, cntx); verify(test1, test2, sw); Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); assertArrayEquals(testPacket.serialize(), eth.serialize()); }
@Override void processOFMessage(OFMessage m) { if(m.getType() == OFType.PORT_STATUS){ OFPortStatus status = (OFPortStatus) m; handlePortStatusMessage(status, false); } else if(plugin != null){ this.plugin.processOFMessage(m); } else{ super.processOFMessage(m); } }
@Before public void setUp() throws Exception { super.setUp(); OFPacketOut packetOut = pvs.generateVerificationPacket(sw1, OFPort.of(1)); ofPacketIn = EasyMock.createMock(OFPacketIn.class); context = new FloodlightContext(); expect(ofPacketIn.getType()).andReturn(OFType.PACKET_IN).anyTimes(); expect(ofPacketIn.getXid()).andReturn(0L).anyTimes(); expect(ofPacketIn.getVersion()).andReturn(packetOut.getVersion()).anyTimes(); Match match = EasyMock.createMock(Match.class); expect(match.get(MatchField.IN_PORT)).andReturn(OFPort.of(1)).anyTimes(); replay(match); expect(ofPacketIn.getMatch()).andReturn(match).anyTimes(); replay(ofPacketIn); IPacket expected = new Ethernet().deserialize(packetOut.getData(), 0, packetOut.getData().length); context.getStorage().put(IFloodlightProviderService.CONTEXT_PI_PAYLOAD, expected); HashMap<DatapathId, IOFSwitch> switches = new HashMap<>(); switches.put(sw1.getId(), sw1); switches.put(sw2.getId(), sw2); mockSwitchManager.setSwitches(switches); reset(producer); pvs.setKafkaProducer(producer); }
@Override public synchronized void addOFMessageListener(OFType type, IOFMessageListener listener) { ListenerDispatcher<OFType, IOFMessageListener> ldd = listeners.get(type); if (ldd == null) { ldd = new ListenerDispatcher<OFType, IOFMessageListener>(); listeners.put(type, ldd); } ldd.addListener(type, listener); }
@Override public synchronized void removeOFMessageListener(OFType type, IOFMessageListener listener) { ListenerDispatcher<OFType, IOFMessageListener> ldd = listeners.get(type); if (ldd != null) { ldd.removeListener(listener); } }
/** * @return the listeners */ @Override public Map<OFType, List<IOFMessageListener>> getListeners() { Map<OFType, List<IOFMessageListener>> lers = new HashMap<OFType, List<IOFMessageListener>>(); for(Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e : listeners.entrySet()) { lers.put(e.getKey(), e.getValue().getOrderedListeners()); } return Collections.unmodifiableMap(lers); }
/** * */ public MockFloodlightProvider(boolean useAsyncUpdates) { listeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType, IOFMessageListener>>(); haListeners = new ListenerDispatcher<HAListenerTypeMarker, IHAListener>(); completionListeners = new ConcurrentLinkedQueue<IControllerCompletionListener>(); role = null; this.useAsyncUpdates = useAsyncUpdates; }
@Override public boolean isCallbackOrderingPrereq(OFType type, String name) { return (type.equals(OFType.PACKET_IN) && (name.equals("topology") || name.equals("devicemanager") || name.equals("virtualizer"))); }
public static FloodlightContext parseAndAnnotate(FloodlightContext bc, OFMessage m) { if (OFType.PACKET_IN.equals(m.getType())) { OFPacketIn pi = (OFPacketIn)m; Ethernet eth = new Ethernet(); eth.deserialize(pi.getData(), 0, pi.getData().length); IFloodlightProviderService.bcStore.put(bc, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } return bc; }
/** * Returns the average load value. * * @param type OpenFlow message type * @return load value */ private long getLoad(OFType type) { if (countMeterMap.get(type).getOneMinuteRate() == 0D) { return 0L; } return (long) (rateMeterMap.get(type).getOneMinuteRate() / countMeterMap.get(type).getOneMinuteRate()); }
@Test public void moveToWaitHello() throws Exception { resetChannel(); expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once(); replay(channel); handler.channelActive(ctx); List<OFMessage> msgs = getMessagesFromCapture(); assertEquals(1, msgs.size()); assertEquals(OFType.HELLO, msgs.get(0).getType()); assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitHelloState.class)); verifyUniqueXids(msgs); }
@Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { // TODO : packet listeners. floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); parseScripts(); }
/** * */ public MockFloodlightProvider(boolean useAsyncUpdates) { listeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType, IOFMessageListener>>(); haListeners = new ListenerDispatcher<HAListenerTypeMarker, IHAListener>(); role = null; this.useAsyncUpdates = useAsyncUpdates; }
@Override public void startUp(FloodlightModuleContext context) { floodlightProviderService.addOFMessageListener(OFType.FLOW_REMOVED, this); switchService.addOFSwitchListener(this); floodlightProviderService.addHAListener(this.haListener); // assumes no switches connected at startup() storageSourceService.createTable(TABLE_NAME, null); storageSourceService.setTablePrimaryKeyName(TABLE_NAME, COLUMN_NAME); storageSourceService.addListener(TABLE_NAME, this); entriesFromStorage = readEntriesFromStorage(); entry2dpid = computeEntry2DpidMap(entriesFromStorage); restApiService.addRestletRoutable(new StaticFlowEntryWebRoutable()); }
@Test public void testTwoMessageTypes() throws IOException, InterruptedException { int timeout = 50; int sleepTime = 60; damper = new OFMessageDamper(100, EnumSet.of(OFType.ECHO_REQUEST, OFType.HELLO), timeout); // echo requests should be dampened doWrite(true, sw1, echoRequst1); doWrite(false, sw1, echoRequst1); doWrite(false, sw1, echoRequst1Clone); doWrite(true, sw1, echoRequst2); doWrite(false, sw1, echoRequst2); // hello should be dampened as well doWrite(true, sw1, hello1); doWrite(false, sw1, hello1); doWrite(false, sw1, hello1); doWrite(true, sw1, hello2); doWrite(false, sw1, hello2); doWrite(false, sw1, hello2); // echo request should also be dampened on sw2 doWrite(true, sw2, echoRequst1); doWrite(false, sw2, echoRequst1); doWrite(true, sw2, echoRequst2); Thread.sleep(sleepTime); doWrite(true, sw1, echoRequst1); doWrite(true, sw2, echoRequst1); doWrite(true, sw1, hello1); doWrite(true, sw1, hello2); }
@Test public void testFloodBufferId() throws Exception { MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider(); this.packetIn = this.packetIn.createBuilder() .setBufferId(OFBufferId.of(10)) .setXid(1) .build(); OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build(); List<OFAction> al = new ArrayList<OFAction>(); al.add(ao); // build our expected flooded packetOut OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut() .setActions(al) .setXid(1) .setBufferId(OFBufferId.of(10)) .setInPort(OFPort.of(1)) .build(); // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); Capture<OFPacketOut> wc1 = new Capture<OFPacketOut>(CaptureType.ALL); mockSwitch.write(capture(wc1)); // Start recording the replay on the mocks replay(mockSwitch); // Get the listener and trigger the packet in IOFMessageListener listener = mockFloodlightProvider.getListeners().get( OFType.PACKET_IN).get(0); listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations verify(mockSwitch); assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); assertEquals(po, m); }
@Override public Map<OFType, List<IOFMessageListener>> getListeners() { Map<OFType, List<IOFMessageListener>> lers = new HashMap<OFType, List<IOFMessageListener>>(); for(Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e : messageListeners.entrySet()) { lers.put(e.getKey(), e.getValue().getOrderedListeners()); } return Collections.unmodifiableMap(lers); }