directory.
Change-Id: I279779c1d179b74dcc1a61c7e303095499764510
Signed-off-by: Ed Warnicke <eaw@cisco.com>
+++ /dev/null
-<?xml version="1.0"?>\r
-<!DOCTYPE module PUBLIC\r
- "-//Puppy Crawl//DTD Check Configuration 1.2//EN"\r
- "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">\r
-\r
-<module name="Checker">\r
- <module name="FileTabCharacter">\r
- <property name="eachLine" value="true" />\r
- </module>\r
-\r
- <module name="RegexpSingleline">\r
- <!-- \s matches whitespace character, $ matches end of line. -->\r
- <property name="format" value="\s+$" />\r
- <property name="message" value="Line has trailing spaces." />\r
- </module>\r
-\r
-</module>\r
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
- <relativePath>../../commons</relativePath>
+ <relativePath>../../</relativePath>
</parent>
<artifactId>distributions-openflowplugin-base</artifactId>
+++ /dev/null
-openflow-codec has been moved to the openflowjava project as
-of Aug 30, 2013:
-
-https://git.opendaylight.org/gerrit/#/c/1047/
-
-You can include it in your maven project with:
-
-<repositories>
- <!-- OpenDayLight Released artifact -->
- <repository>
- <id>opendaylight-release</id>
- <name>opendaylight-release</name>
- <url>${nexusproxy}/repositories/opendaylight.release/</url>
- </repository>
- <!-- OpenDayLight Snapshot artifact -->
- <repository>
- <id>opendaylight-snapshot</id>
- <name>opendaylight-snapshot</name>
- <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
- </repository>
-</repositories>
-
-<dependency>
- <groupId>org.opendaylight.openflowjava.thirdparty</groupId>
- <artifactId>org.openflow.codec</artifactId>
- <version>1.0.2-SNAPSHOT</version>
-</dependency>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <relativePath>../commons</relativePath>
- </parent>
-
- <artifactId>protocol_plugins.openflow_netty</artifactId>
- <version>0.1.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.6</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>
- org.opendaylight.controller.sal.packet,
- org.opendaylight.controller.sal.action,
- org.opendaylight.controller.sal.connection,
- org.opendaylight.controller.sal.discovery,
- org.opendaylight.controller.sal.topology,
- org.opendaylight.controller.sal.core,
- org.opendaylight.controller.sal.flowprogrammer,
- org.opendaylight.controller.sal.reader,
- org.opendaylight.controller.sal.inventory,
- org.opendaylight.controller.sal.match,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.openflowplugin.openflow.core,
- org.opendaylight.openflowplugin.openflow.core.internal,
- org.opendaylight.openflowplugin.openflow.internal,
- org.apache.commons.lang3.builder,
- org.apache.commons.lang3.tuple,
- org.apache.felix.dm,
- org.slf4j,
- org.eclipse.osgi.framework.console,
- org.osgi.framework,
- javax.net.ssl,
- org.jboss.netty.*
- </Import-Package>
- <Export-Package>
- org.opendaylight.controller.protocol_plugin.openflow.core.internal;-split-package:=merge-first,
- org.opendaylight.controller.protocol_plugin.openflow.core;-split-package:=merge-first,
- </Export-Package>
- <Embed-Dependency>
- org.openflow.openflowj_netty,org.jboss.netty;protocol_plugins.openflow;type=!pom;inline=false
- </Embed-Dependency>
- <Embed-Transitive>
- false
- </Embed-Transitive>
- <Bundle-Activator>
- org.opendaylight.controller.protocol_plugin.openflow.internal.EnhancedActivator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal.connection</artifactId>
- <version>0.1.0-SNAPSHOT</version>
- </dependency>
- <!-- Make sure this comes before protocol_plugins.openflow Maven
- honors the classpath order to reliable builds and here we
- want to make sure that the openflowJ embedded is picking the
- netty one over the non-netty enabled-->
- <dependency>
- <groupId>org.opendaylight.openflowjava.thirdparty</groupId>
- <artifactId>org.openflow.openflowj_netty</artifactId>
- <version>1.0.2-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.netty</groupId>
- <artifactId>netty</artifactId>
- <version>3.2.6.Final</version>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.protocol_plugin.openflow.core;
-
-import java.net.SocketAddress;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFStatisticsRequest;
-
-/**
- * This interface defines an abstraction of an Open Flow Switch.
- *
- */
-public interface IEnhancedSwitch extends ISwitch {
- public void startHandler();
-
- public void shutDownHandler();
-
- public void handleMessage(OFMessage ofMessage);
-
- public void flushBufferedMessages();
-
- public SocketAddress getRemoteAddress();
-
- public SocketAddress getLocalAddress();
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.RejectedExecutionException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SocketChannel;
-
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
-import org.jboss.netty.handler.timeout.IdleStateAwareChannelUpstreamHandler;
-import org.jboss.netty.handler.timeout.IdleStateEvent;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.ObjectSizeEstimator;
-import org.jboss.netty.handler.timeout.ReadTimeoutException;
-
-
-
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.protocol.factory.MessageParseException;
-import org.opendaylight.controller.protocol_plugin.openflow.core.IEnhancedSwitch;
-import org.opendaylight.controller.sal.connection.ConnectionConstants;
-import org.opendaylight.controller.sal.connection.IPluginInConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.opendaylight.openflowplugin.openflow.core.ISwitchStateListener;
-import org.opendaylight.openflowplugin.openflow.core.internal.SwitchEvent;
-//import org.opendaylight.controller.protocol_plugin.openflow.core.internal.OFChannelState.HandshakeState;
-//import org.openflow.protocol.OFType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-public class EnhancedController implements IController, IPluginInConnectionService {
-
-
- protected BasicFactory factory;
-
-
- private static final Logger logger = LoggerFactory
- .getLogger(EnhancedController.class);
-
-
- // Track connected switches via SwitchID
- private ConcurrentHashMap<Long, ISwitch> connectedSwitches;
-
- // Track connected switches via ChannelID. Whenever the message
- private ConcurrentHashMap<Integer, IEnhancedSwitch> channelIDToSwitchMap;
-
- // only 1 message listener per OFType
- private ConcurrentMap<OFType, IMessageListener> messageListeners;
-
- // only 1 switch state listener
- private ISwitchStateListener switchStateListener;
- private AtomicInteger switchInstanceNumber;
-
-
- private OFChannelHandler ofChannelHandler = null;
- private ControllerServerBootstrap bootstrap = null;
-
- private ThreadPoolExecutor execHandler = null;
-
- private static final int SEND_BUFFER_SIZE = 1 * 1024 * 1024;
- private static final int RECEIVE_BUFFER_SIZE = 1 * 1024 * 1024;
- private static final int WRITE_BUFFER_LOW_WATERMARK = 32 * 1024;
- private static final int WRITE_BUFFER_HIGH_WATERMARK = 64 * 1024;
- private static final String CONTROLLER_HOST = null;
- private static final int CONTROLLER_PORT = 6633;
-
- private static final int OMATPE_CORE_POOL_SIZE = 200;
- private static final int OMATPE_PER_CHANNEL_SIZE = 2 * 1048576;
- private static final int OMATPE_POOL_WIDE_SIZE = 0; //1073741824;
- private static final int OMATPE_THREAD_KEEP_ALIVE_IN_MILLISECONDS = 100;
- private static final int EXPERIMENTAL_OMATPE_OBJECT_SIZE = 1000; // bytes
-
- private HashedWheelTimer hashedWheelTimer = null;
-
- // This executor would be used by individual switches to handle
- // cases like Stats Request/Response or Sync* methods which sends request and
- // waits via Future for responses. Please note that threads in this
- // pool are shared across multiple threads. So, if all threads are busy,
- // Socket IO thread would get blocked creating sharp decline in performance
- // If possible TOTALLY avoid any thread usage which does network level
- // request / response by making a thread in this pool wait for response
- // Consider storing the Future reference against the "sent" request and
- // fire-event to wake-up the same when response is received rather than making the
- // sender thread getting into a "wait" mode. That would never scale
- private ExecutorService executorService = null;
-
- // IMPORTANT: DO NOT REDUCE THIS THREAD COUNT TO 0
- // THIS THREAD COUNT WOULD BE USED FOR SOCKET-IO + FOLLOWING EXECUTION CHAIN
- // Plugin + SAL + North-to-SAL + Egress (flow_provisioning)
- private static final int WORKER_THREAD_COUNT = 4;
-
- // This is a handy thread-pool if WORKER_THREAD_COUNT is not able to cope with
- // Socket IO + Execution of the following handling chain
- // Plugin + SAL + North-to-SAL + Egress (flow_provisioning)
- private static final int EXECUTION_HANDLER_THREAD_POOL_SIZE = 0;
-
- // This is the thread-pool which can be optionally used for
- // building synchronous semantics for flow_mod and stats handling cycle
- // Flow_Mod in synchronous model could involve FLOW_MOD + BARRIER_MSG
- // sending and receiving with wait timeout for reply
- // Stats handling in synchronous model could involve STATS_REQUEST + STATS_REPLY
- // sending and receiving with wait timeout for reply
- private static final int THREAD_POOL_SIZE_FOR_EGRESS_SYNC_MSGS = 30;
-
- private TrafficStatisticsHandler statsHandler = null;
-
- // Lock for locking messagelisteners list while escalating the switch
- // messages
- private ReentrantLock lock = new ReentrantLock();
-
- private static final int FLUSH_BATCH_SIZE = 100;
-
- //****************** IController Interafce Methods Begin ******************
-
- @Override
- public void addMessageListener(OFType type, IMessageListener listener) {
- IMessageListener currentListener = this.messageListeners.get(type);
- if (currentListener != null) {
- logger.warn("{} is already listened by {}", type.toString(),
- currentListener.toString());
- }
- this.messageListeners.put(type, listener);
- logger.debug("{} is now listened by {}", type.toString(),
- listener.toString());
-
- }
-
- @Override
- public void removeMessageListener(OFType type, IMessageListener listener) {
- IMessageListener currentListener = this.messageListeners.get(type);
- if ((currentListener != null) && (currentListener == listener)) {
- logger.debug("{} listener {} is Removed", type.toString(),
- listener.toString());
- this.messageListeners.remove(type);
- }
-
- }
-
- @Override
- public void addSwitchStateListener(ISwitchStateListener listener) {
- if (this.switchStateListener != null) {
- logger.warn("Switch events are already listened by {}",
- this.switchStateListener.toString());
- }
- this.switchStateListener = listener;
- logger.debug("Switch events are now listened by {}",
- listener.toString());
-
- }
-
- @Override
- public void removeSwitchStateListener(ISwitchStateListener listener) {
- if ((this.switchStateListener != null)
- && (this.switchStateListener == listener)) {
- logger.debug("SwitchStateListener {} is Removed",
- listener.toString());
- this.switchStateListener = null;
- }
-
- }
-
- @Override
- public Map<Long, ISwitch> getSwitches() {
- return this.connectedSwitches;
- }
-
- @Override
- public ISwitch getSwitch(Long switchId) {
- return this.connectedSwitches.get(switchId);
- }
-
- //****************** IController Interafce Methods End ******************
-
-
-
- //****************** Dependency-manager callbacks Begin ******************
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- public void init() {
- logger.debug("Initializing!");
- this.connectedSwitches = new ConcurrentHashMap<Long, ISwitch>();
- this.channelIDToSwitchMap = new ConcurrentHashMap<Integer, IEnhancedSwitch>();
- this.messageListeners = new ConcurrentHashMap<OFType, IMessageListener>();
- this.switchStateListener = null;
- this.hashedWheelTimer = new HashedWheelTimer();
- this.statsHandler = new TrafficStatisticsHandler(hashedWheelTimer);
- this.switchInstanceNumber = new AtomicInteger(0);
- this.factory = new BasicFactory();
- this.bootstrap = new ControllerServerBootstrap(this);
- this.executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE_FOR_EGRESS_SYNC_MSGS);
-
-
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- public void start() {
- this.statsHandler.init();
- logger.debug("Starting!");
- bootstrap.startServer(WORKER_THREAD_COUNT,
- CONTROLLER_HOST,
- CONTROLLER_PORT,
- ofChannelHandler);
-
-
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- public void stop() {
- for (Iterator<Entry<Integer, IEnhancedSwitch>> it = channelIDToSwitchMap.entrySet().iterator(); it
- .hasNext();) {
- Entry<Integer, IEnhancedSwitch> entry = it.next();
- ((EnhancedSwitchHandler) entry.getValue()).stop();
- }
-
- hashedWheelTimer.stop();
-
- executorService.shutdown();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- public void destroy() {
- }
- //****************** Dependency-manager callbacks End ******************
-
-
-
- public OFChannelHandler getChannelHandler(){
- return new OFChannelHandler(this);
- }
-
-
- protected class OFChannelHandler extends IdleStateAwareChannelUpstreamHandler{
-
-
- protected EnhancedController controller = null;
- protected Channel channel = null;
-
-
- public OFChannelHandler(EnhancedController controller){
- this.controller = controller;
- }
-
-
- @Override
- public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e)
- throws Exception {
- List<OFMessage> msglist = new ArrayList<OFMessage>(1);
- msglist.add(factory.getMessage(OFType.ECHO_REQUEST));
- e.getChannel().write(msglist);
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.ECHO_REQUEST_SENT);
- }
-
- @Override
- public void channelConnected(ChannelHandlerContext ctx,
- ChannelStateEvent e) throws Exception {
- channel = e.getChannel();
- logger.info("New switch connection from {}",
- channel.getRemoteAddress());
-
- Integer channelID = e.getChannel().getId();
-
- IEnhancedSwitch switchHandler = new EnhancedSwitchHandler(controller,
- channelID, channel, hashedWheelTimer, executorService, statsHandler);
- switchHandler.startHandler();
- channelIDToSwitchMap.put(channelID, switchHandler);
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.CONNECTED_SWITCHES);
-
- }
-
- @Override
- public void channelDisconnected(ChannelHandlerContext ctx,
- ChannelStateEvent e) throws Exception {
- // when SwitchHandler.shutDownHandler is called, Controller would
- // get the feedback via switchDeleted method. So that both SwitchHandler and
- // controller both release resources of the switch concerned
-
- Integer channelID = e.getChannel().getId();
- IEnhancedSwitch switchHandler = channelIDToSwitchMap.get(channelID);
- if (switchHandler != null){
- switchHandler.shutDownHandler();
- }
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.DISCONNECTED_SWITCHES);
-
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
- throws Exception {
-
- EnhancedSwitchHandler sw = null;
-
- if (e.getCause() instanceof ReadTimeoutException) {
- // switch timeout
- logger.error("Disconnecting switch {} due to read timeout",
- e.getChannel().getId(), e.getCause().getMessage());
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop();
- /*
- } else if (e.getCause() instanceof HandshakeTimeoutException) {
- logger.error("Disconnecting switch {}: failed to complete handshake",
- e.getChannel().getId());
- ctx.getChannel().close();
- channelIDToSwitchMap.remove(e.getChannel().getId());
- */
- } else if (e.getCause() instanceof ClosedChannelException) {
- logger.warn("Channel for sw {} already closed Error : {}",
- e.getChannel().getId(), e.getCause().getMessage());
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop();
- } else if (e.getCause() instanceof IOException) {
- logger.error("Disconnecting switch {} due to IO Error: {}",
- e.getChannel().getId(), e.getCause().getMessage());
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop();
- /*
- } else if (e.getCause() instanceof SwitchStateException) {
- logger.error("Disconnecting switch {} due to switch state error: {}",
- e.getChannel().getId(), e.getCause().getMessage());
- ctx.getChannel().close();
- channelIDToSwitchMap.remove(e.getChannel().getId());
-
- } else if (e.getCause() instanceof MessageParseException) {
- logger.error("Disconnecting switch {} due to message parse error Error : {}",
- e.getChannel().getId(), e.getCause().getMessage());
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop(); */
- } else if (e.getCause() instanceof RejectedExecutionException) {
- logger.warn("Could not process message: queue full");
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop();
- } else {
- logger.error("Error while processing message from switch {} Error : {}",
- e.getChannel().getId(), e.getCause().getMessage());
- e.getCause().printStackTrace();
- ctx.getChannel().close();
- sw = (EnhancedSwitchHandler)channelIDToSwitchMap.get(e.getChannel().getId());
- sw.stop();
- }
-
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.EXCEPTION_CAUGHT);
- }
-
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
- throws Exception {
- Integer messageChannelId = e.getChannel().getId();
- IEnhancedSwitch swHan = (EnhancedSwitchHandler)channelIDToSwitchMap.get(messageChannelId);
-
- if (e.getMessage() instanceof List) {
- //@SuppressWarnings("unchecked")
- List<OFMessage> msglist = (List<OFMessage>)e.getMessage();
- if (msglist != null){ // this check actually brought down rate to some extent - weird !!!
- for (OFMessage ofm : msglist) {
- try {
-
- // Do the actual packet processing
- processOFMessage(ofm, messageChannelId);
- }
- catch (Exception ex) {
- // We are the last handler in the stream, so run the
- // exception through the channel again by passing in
- // ctx.getChannel().
- Channels.fireExceptionCaught(ctx.getChannel(), ex);
- }
- }
- }
- }
-
- // Flush all flow-mods/packet-out/stats generated from this "train"
- swHan.flushBufferedMessages();
-
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.MESSAGE_RECEIVED);
-
-
- }
-
-
- public void processOFMessage(OFMessage ofm, Integer channelID){
- IEnhancedSwitch switchHandler = (IEnhancedSwitch) channelIDToSwitchMap.get(channelID);
- statsHandler.countForEntitySimpleMeasurement(channelID, TrafficStatisticsHandler.ENTITY_COUNTER_RCV_MSG);
- if (switchHandler != null){
- switchHandler.handleMessage(ofm);
- }
- }
-
-
- }
-
-
- protected class ControllerServerBootstrap{
-
- private int workerThreads = 0;
- private EnhancedController controller = null;
-
- public ControllerServerBootstrap(EnhancedController controller){
- this.controller = controller;
- }
-
-
- public void startServer(int numWorkerThreads, String openFlowHost, int openFlowPort, OFChannelHandler ofchan){
- this.workerThreads = numWorkerThreads;
- try {
- final ServerBootstrap bootstrap = createServerBootStrap();
-
- bootstrap.setOption("reuseAddr", true);
- bootstrap.setOption("child.keepAlive", true);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.receiveBufferSize", EnhancedController.RECEIVE_BUFFER_SIZE);
- bootstrap.setOption("child.sendBufferSize", EnhancedController.SEND_BUFFER_SIZE);
-
- // better to have an receive buffer predictor
- //bootstrap.setOption("receiveBufferSizePredictorFactory",
- // new AdaptiveReceiveBufferSizePredictorFactory());
- //if the server is sending 1000 messages per sec, optimum write buffer water marks will
- //prevent unnecessary throttling, Check NioSocketChannelConfig doc
- //bootstrap.setOption("writeBufferLowWaterMark", WRITE_BUFFER_LOW_WATERMARK);
- //bootstrap.setOption("writeBufferHighWaterMark", WRITE_BUFFER_HIGH_WATERMARK);
-
- // TODO: IMPORTANT: If the threadpool is supplied as null, ExecutionHandler would
- // not be present in pipeline. If the load increases and ordering is required ,
- // use OrderedMemoryAwareThreadPoolExecutor as argument instead of null
-
- /*
- execHandler = new OrderedMemoryAwareThreadPoolExecutor(
- OMATPE_CORE_POOL_SIZE,
- OMATPE_PER_CHANNEL_SIZE,
- OMATPE_POOL_WIDE_SIZE,
- OMATPE_THREAD_KEEP_ALIVE_IN_MILLISECONDS,
- TimeUnit.MILLISECONDS,
- new ObjectSizeEstimator() {
-
- @Override
- public int estimateSize(Object o) {
- return 30000;
- }
- },
- Executors.defaultThreadFactory()); */
-
- execHandler = new OrderedMemoryAwareThreadPoolExecutor(
- OMATPE_CORE_POOL_SIZE,
- OMATPE_PER_CHANNEL_SIZE,
- OMATPE_POOL_WIDE_SIZE,
- OMATPE_THREAD_KEEP_ALIVE_IN_MILLISECONDS,
- TimeUnit.MILLISECONDS);
-
-
-
- ChannelPipelineFactory pfact =
- new OpenflowPipelineFactory(controller, execHandler);
- bootstrap.setPipelineFactory(pfact);
- InetSocketAddress sa =
- (openFlowHost == null)
- ? new InetSocketAddress(openFlowPort)
- : new InetSocketAddress(openFlowHost, openFlowPort);
- final ChannelGroup cg = new DefaultChannelGroup();
- cg.add(bootstrap.bind(sa));
-
-
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- }
-
- private ServerBootstrap createServerBootStrap() {
- if (workerThreads == 0) {
- return new ServerBootstrap(
- new NioServerSocketChannelFactory(
- Executors.newCachedThreadPool(),
- Executors.newCachedThreadPool()));
- } else {
- return new ServerBootstrap(
- new NioServerSocketChannelFactory(
- Executors.newCachedThreadPool(),
- Executors.newCachedThreadPool(), workerThreads));
- }
- }
-
-
-
- }
-
-
- /**
- * Method called by SwitchHandler once the handshake state is completed
- *
- * @param sw
- */
- public void switchAdded(SwitchEvent switchEv, Integer switchChannelID){
-
- ISwitch sw = switchEv.getSwitch();
- Long switchId = sw.getId();
-
- connectedSwitches.put(switchId, sw);
- statsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.CONNECTED_SWITCHES);
-
- logger.info("Switch with DPID : {} connected ", switchId);
-
- notifySwitchAdded(sw);
- }
-
-
- /**
- * Method called by SwitchHandler switch is disconnected
- *
- * @param sw
- */
-
- public void switchDeleted(SwitchEvent switchEv, Integer switchChannelID){
- ISwitch sw = switchEv.getSwitch();
- disconnectSwitch(sw, switchChannelID);
- }
-
-
- /**
- * Method called by SwitchHandler when it encounters any errors
- *
- *
- * @param sw
- */
-
- public void switchError(SwitchEvent switchEv, Integer switchChannelID){
-
- }
-
-
- public void switchMessage(SwitchEvent switchEv, Integer switchChannelID){
- long startTime = 0L;
- long endTime = 0L;
-
-
- OFMessage msg = switchEv.getMsg();
- ISwitch sw = switchEv.getSwitch();
- if (msg != null) {
- //try{
- // lock.lock();
- IMessageListener listener = messageListeners
- .get(msg.getType());
- if (listener != null) {
- //logger.debug("delegating to msg-receiver");
- //startTime = System.nanoTime();
- listener.receive(sw, msg);
- //endTime = System.nanoTime();
- //this.statsHandler.reportPacketInProcessingTime(endTime - startTime);
- }
- //}
- //finally{
- // lock.unlock();
- //}
- }
- }
-
- public void disconnectSwitch(ISwitch sw, Integer switchChannelID){
- Long sid = null;
- if (((EnhancedSwitchHandler) sw).isOperational()) {
- sid = sw.getId();
-
- this.connectedSwitches.remove(sid);
- this.channelIDToSwitchMap.remove(switchChannelID);
- notifySwitchDeleted(sw);
- }
- //((EnhancedSwitchHandler) sw).stop();
- logger.info("Switch with DPID {} disconnected", sid);
- sw = null;
- }
-
-
- private void notifySwitchAdded(ISwitch sw) {
- if (switchStateListener != null) {
- switchStateListener.switchAdded(sw);
- }
- }
-
- private void notifySwitchDeleted(ISwitch sw) {
- if (switchStateListener != null) {
- switchStateListener.switchDeleted(sw);
- }
- }
-
- @Override
- public Status disconnect(Node node) {
- ISwitch sw = getSwitch((Long)node.getID());
- if (sw != null) {
- if (sw instanceof EnhancedSwitchHandler) {
- EnhancedSwitchHandler eSw = (EnhancedSwitchHandler)sw;
- disconnectSwitch(sw, eSw.getSwitchChannelID());
- }
- }
- return new Status(StatusCode.SUCCESS);
- }
-
- @Override
- public Node connect(String connectionIdentifier, Map<ConnectionConstants, String> params) {
- return null;
- }
-
- /**
- * View Change notification
- */
- public void notifyClusterViewChanged() {
- for (ISwitch sw : connectedSwitches.values()) {
- notifySwitchAdded(sw);
- }
- }
-
- /**
- * Node Disconnected from the node's master controller.
- */
- @Override
- public void notifyNodeDisconnectFromMaster(Node node) {
- ISwitch sw = connectedSwitches.get((Long)node.getID());
- if (sw != null) notifySwitchAdded(sw);
- }
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedSelectorException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.opendaylight.controller.protocol_plugin.openflow.core.IEnhancedSwitch;
-import org.opendaylight.openflowplugin.openflow.core.internal.StatisticsCollector;
-import org.opendaylight.openflowplugin.openflow.core.internal.SwitchEvent;
-import org.opendaylight.openflowplugin.openflow.core.internal.SwitchEvent.SwitchEventType;
-import org.opendaylight.openflowplugin.openflow.core.internal.SynchronousMessage;
-import org.openflow.protocol.OFBarrierReply;
-import org.openflow.protocol.OFBarrierRequest;
-import org.openflow.protocol.OFEchoReply;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFFeaturesReply;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFGetConfigReply;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFSetConfig;
-import org.openflow.protocol.OFStatisticsReply;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
-import org.openflow.protocol.OFPhysicalPort.OFPortFeatures;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.protocol.factory.MessageParseException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnhancedSwitchHandler implements IEnhancedSwitch {
-
-
- private static final Logger logger = LoggerFactory
- .getLogger(EnhancedSwitchHandler.class);
- private static final int switchLivenessTimeout = getSwitchLivenessTimeout();
- private int MESSAGE_RESPONSE_TIMER = 2000;
-
- private EnhancedController controller = null;
- private Integer switchChannelID = null;
- private Channel channel;
- private long lastMsgReceivedTimeStamp = 0;
- private SwitchState state = null;
- private BasicFactory factory = null;
- private HashedWheelTimer timer = null;
- private SwitchLivelinessTimerTask switchLivelinessTask = null;
- private Timeout switchLivelinessTaskHandle = null;
- private long sid;
- private AtomicInteger xid;
- private int buffers;
- private int capabilities;
- private byte tables;
- private int actions;
- private Map<Short, OFPhysicalPort> physicalPorts;
- private Map<Short, Integer> portBandwidth;
- private Date connectedDate;
- private ExecutorService executor = null;
- private ConcurrentHashMap<Integer, Callable<Object>> messageWaitingDone;
- private Integer responseTimerValue;
- private TrafficStatisticsHandler trafficStatsHandler = null;
- private static final boolean START_LIVELINESS_TIMER = false;
-
- private static final int BATCH_COUNT_FOR_FLUSHING = 3;
- private int flushBatchTrack = 0;
-
- /*
- private List<OFMessage> msgBuffer = new ArrayList<OFMessage>();
- private int bufferTrack = 0;
- private static final int BATCH_BUFFER_THRESHOLD = 100;
- */
-
-
- // PLEASE .. IF THERE IS SOMETHING CALLED GOD, HELP ME GET THE THROUGHPUT WITH THIS !!
- private List<OFMessage> flushableMsgBuffer = new ArrayList<OFMessage>();
-
-
- public enum SwitchState {
- NON_OPERATIONAL(0),
- WAIT_FEATURES_REPLY(1),
- WAIT_CONFIG_REPLY(2),
- OPERATIONAL(3);
-
- private int value;
-
- private SwitchState(int value) {
- this.value = value;
- }
-
- @SuppressWarnings("unused")
- public int value() {
- return this.value;
- }
- }
-
-
- public EnhancedSwitchHandler(EnhancedController controller,
- Integer switchConnectionChannelID,
- Channel channel,
- HashedWheelTimer timer,
- ExecutorService executor,
- TrafficStatisticsHandler tHandler){
-
- this.controller = controller;
- this.physicalPorts = new HashMap<Short, OFPhysicalPort>();
- this.portBandwidth = new HashMap<Short, Integer>();
- this.switchChannelID = switchConnectionChannelID;
- this.timer = timer;
- this.sid = (long) 0;
- this.tables = (byte) 0;
- this.actions = (int) 0;
- this.capabilities = (int) 0;
- this.buffers = (int) 0;
- this.connectedDate = new Date();
- this.state = SwitchState.NON_OPERATIONAL;
- this.executor = executor;
- this.messageWaitingDone = new ConcurrentHashMap<Integer, Callable<Object>>();
- this.responseTimerValue = MESSAGE_RESPONSE_TIMER;
- this.channel = channel;
- this.xid = new AtomicInteger(this.channel.hashCode());
- this.trafficStatsHandler = tHandler;
-
- }
-
- Integer getSwitchChannelID() {
- return this.switchChannelID;
- }
-
- public void startHandler(){
- this.factory = new BasicFactory();
- start();
-
- }
-
-
- public void shutDownHandler(){
- stop();
-
- }
-
-
- public void handleChannelIdle(){
- // TODO: this is already handled by OFChannelHandler
- // so DON'T care
-
-
- }
-
-
- public void start() {
- sendFirstHello();
- }
-
- public void stop() {
- cancelSwitchTimer();
- SwitchEvent ev = new SwitchEvent(SwitchEventType.SWITCH_DELETE, this, null);
- controller.switchDeleted(ev, switchChannelID);
- }
-
- private void cancelSwitchTimer() {
- if (switchLivelinessTaskHandle != null){
- this.switchLivelinessTaskHandle.cancel();
- }
- }
-
-
- public void handleCaughtException(){
-
-
-
- }
-
-
-
-
- @Override
- public int getNextXid() {
- return this.xid.incrementAndGet();
- }
-
- @Override
- public Long getId() {
- return this.sid;
- }
-
- @Override
- public Byte getTables() {
- return this.tables;
- }
-
- @Override
- public Integer getActions() {
- return this.actions;
- }
-
- @Override
- public Integer getCapabilities() {
- return this.capabilities;
- }
-
- @Override
- public Integer getBuffers() {
- return this.buffers;
- }
-
- @Override
- public Date getConnectedDate() {
- return this.connectedDate;
- }
-
- @Override
- public Integer asyncSend(OFMessage msg) {
- return asyncSend(msg, getNextXid());
- }
-
-
- @Override
- public Integer asyncSend(OFMessage msg, int xid) {
- // TODO:
- // BATCHING IMPLEMENTATION. Please think hard before enablng this !!
- // Some messages could be latency-sensitive and some could be batched
- // for better throughput. So, below decision may not bring better
- // throughput for latency-sensitive cases like FLOW-MODs or
- // PACKET-OUTs
-
- /*
- if (bufferTrack == BUFFER_THRESHOLD){
- this.channel.write(msgBuffer);
- msgBuffer.clear();
- bufferTrack = 0;
-
- }
- msg.setXid(xid);
- msgBuffer.add(msg);
- bufferTrack++;
- */
-
-
-
- //List<OFMessage> msglist = new ArrayList<OFMessage>(1);
- msg.setXid(xid);
- synchronized( flushableMsgBuffer ) {
- flushableMsgBuffer.add(msg);
- }
-
- trafficStatsHandler.countForEntitySimpleMeasurement(switchChannelID,
- TrafficStatisticsHandler.ENTITY_COUNTER_SND_MSG);
-
- //this.channel.write(msglist);
-
- /*
- if (msg.getType() == OFType.FLOW_MOD){
- this.trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.FLOW_MOD_SENT);
- this.trafficStatsHandler.countForRateMeasurement(TrafficStatisticsHandler.FLOW_MOD_SENT);
- }
- */
-
-
- return xid;
- }
-
-
- @Override
- public Integer asyncFastSend(OFMessage msg) {
- return asyncFastSend(msg, getNextXid());
- }
-
- @Override
- public Integer asyncFastSend(OFMessage msg, int xid) {
- msg.setXid(xid);
- List<OFMessage> msglist = new ArrayList<OFMessage>(1);
- msglist.add(msg);
- this.channel.write(msglist);
- trafficStatsHandler.countForEntitySimpleMeasurement(switchChannelID,
- TrafficStatisticsHandler.ENTITY_COUNTER_SND_MSG);
- return xid;
- }
-
- @Override
- public Object syncSend(OFMessage msg) {
- int xid = getNextXid();
- return syncSend(msg, xid);
- }
-
- private Object syncSend(OFMessage msg, int xid) {
- return syncMessageInternal(msg, xid, true);
- }
-
- @Override
- public Map<Short, OFPhysicalPort> getPhysicalPorts() {
- return this.physicalPorts;
- }
-
- @Override
- public Set<Short> getPorts() {
- return this.physicalPorts.keySet();
- }
-
- @Override
- public OFPhysicalPort getPhysicalPort(Short portNumber) {
- return this.physicalPorts.get(portNumber);
- }
-
- @Override
- public Integer getPortBandwidth(Short portNumber) {
- return this.portBandwidth.get(portNumber);
- }
-
- @Override
- public boolean isPortEnabled(short portNumber) {
- return isPortEnabled(physicalPorts.get(portNumber));
- }
-
- @Override
- public boolean isPortEnabled(OFPhysicalPort port) {
- if (port == null) {
- return false;
- }
- int portConfig = port.getConfig();
- int portState = port.getState();
- if ((portConfig & OFPortConfig.OFPPC_PORT_DOWN.getValue()) > 0) {
- return false;
- }
- if ((portState & OFPortState.OFPPS_LINK_DOWN.getValue()) > 0) {
- return false;
- }
- if ((portState & OFPortState.OFPPS_STP_MASK.getValue()) == OFPortState.OFPPS_STP_BLOCK
- .getValue()) {
- return false;
- }
- return true;
-
- }
-
- @Override
- public List<OFPhysicalPort> getEnabledPorts() {
- List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
- synchronized (this.physicalPorts) {
- for (OFPhysicalPort port : physicalPorts.values()) {
- if (isPortEnabled(port)) {
- result.add(port);
- }
- }
- }
- return result;
- }
-
-
- /**
- * WARNING: CALLER WOULD BE BLOCKED
- *
- */
- @Override
- public Object getStatistics(OFStatisticsRequest req) {
- int xid = getNextXid();
- StatisticsCollector worker = new StatisticsCollector(this, xid, req);
- messageWaitingDone.put(xid, worker);
- Future<Object> submit = executor.submit(worker);
- Object result = null;
- try {
- result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
- return result;
- } catch (Exception e) {
- logger.warn("Timeout while waiting for {} replies", req.getType());
- result = null; // to indicate timeout has occurred
- return result;
- }
- }
-
- @Override
- public boolean isOperational() {
- return ((this.state == SwitchState.WAIT_CONFIG_REPLY) || (this.state == SwitchState.OPERATIONAL));
- }
-
- @Override
- public Object syncSendBarrierMessage() {
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- return syncSend(barrierMsg);
- }
-
- @Override
- public Object asyncSendBarrierMessage() {
- List<OFMessage> msglist = new ArrayList<OFMessage>(1);
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- int xid = getNextXid();
-
- barrierMsg.setXid(xid);
- msglist.add(barrierMsg);
-
- this.channel.write(msglist);
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.BARRIER_REQUEST_SENT);
- return Boolean.TRUE;
- }
-
-
- @Override
- public void handleMessage(OFMessage ofMessage) {
-
-
- logger.debug("Message received: {}", ofMessage.toString());
- this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
- OFType type = ofMessage.getType();
- switch (type) {
- case HELLO:
- logger.debug("<<<< HELLO");
- // send feature request
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.HELLO_RECEIVED);
- OFMessage featureRequest = factory
- .getMessage(OFType.FEATURES_REQUEST);
- asyncFastSend(featureRequest);
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.FEATURES_REQUEST_SENT);
- // delete all pre-existing flows
- OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL);
- OFFlowMod flowMod = (OFFlowMod) factory
- .getMessage(OFType.FLOW_MOD);
- flowMod.setMatch(match).setCommand(OFFlowMod.OFPFC_DELETE)
- .setOutPort(OFPort.OFPP_NONE)
- .setLength((short) OFFlowMod.MINIMUM_LENGTH);
- asyncFastSend(flowMod);
- this.state = SwitchState.WAIT_FEATURES_REPLY;
- if (START_LIVELINESS_TIMER){
- startSwitchTimer();
- }
- break;
- case ECHO_REQUEST:
- logger.debug("<<<< ECHO REQUEST");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.ECHO_REQUEST_RECEIVED);
- OFEchoReply echoReply = (OFEchoReply) factory
- .getMessage(OFType.ECHO_REPLY);
- asyncFastSend(echoReply);
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.ECHO_REPLY_SENT);
-
- break;
- case ECHO_REPLY:
- logger.debug("<<<< ECHO REPLY");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.ECHO_REPLY_RECEIVED);
- //this.probeSent = false;
- break;
- case FEATURES_REPLY:
- logger.debug("<<<< FEATURES REPLY");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.FEATURES_REPLY_RECEIVED);
- processFeaturesReply((OFFeaturesReply) ofMessage);
- break;
- case GET_CONFIG_REPLY:
- logger.debug("<<<< CONFIG REPLY");
- // make sure that the switch can send the whole packet to the
- // controller
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.CONFIG_REPLY_RECEIVED);
- if (((OFGetConfigReply) ofMessage).getMissSendLength() == (short) 0xffff) {
- this.state = SwitchState.OPERATIONAL;
- }
- break;
- case BARRIER_REPLY:
- logger.debug("<<<< BARRIER REPLY");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.BARRIER_REPLY_RECEIVED);
- processBarrierReply((OFBarrierReply) ofMessage);
- break;
- case ERROR:
- logger.debug("<<<< ERROR");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.ERROR_MSG_RECEIVED);
- processErrorReply((OFError) ofMessage);
- break;
- case PORT_STATUS:
- logger.debug("<<<< PORT STATUS");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.PORT_STATUS_RECEIVED);
- processPortStatusMsg((OFPortStatus) ofMessage);
- break;
- case STATS_REPLY:
- logger.debug("<<<< STATS REPLY");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.STATS_RESPONSE_RECEIVED);
- processStatsReply((OFStatisticsReply) ofMessage);
- break;
- case PACKET_IN:
- logger.debug("<<<< PACKET_IN");
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.PACKET_IN_RECEIVED);
- trafficStatsHandler.countForRateMeasurement(TrafficStatisticsHandler.PACKET_IN_RECEIVED);
- break;
- default:
- break;
- } // end of switch
- if (isOperational()) {
- logger.debug("SWITCH IS OPERATIONAL ... forwarding");
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_MESSAGE, this, ofMessage);
- controller.switchMessage(ev, switchChannelID);
- }
- }
-
-
- private void startSwitchTimer(){
- if (this.timer != null){
- if (switchLivelinessTask == null){
- switchLivelinessTask = new SwitchLivelinessTimerTask();
- }
- switchLivelinessTaskHandle = timer.newTimeout(switchLivelinessTask,
- switchLivenessTimeout, TimeUnit.SECONDS);
- }
- }
-
-
-
- /**
- * This method returns the switch liveness timeout value. If controller did
- * not receive any message from the switch for such a long period,
- * controller will tear down the connection to the switch.
- *
- * @return The timeout value
- */
- private static int getSwitchLivenessTimeout() {
- String timeout = System.getProperty("of.switchLivenessTimeout");
- int rv = 60500;
- try {
- if (timeout != null) {
- rv = Integer.parseInt(timeout);
- }
- } catch (Exception e) {
- }
- return rv;
- }
-
-
- private void processFeaturesReply(OFFeaturesReply reply) {
- if (this.state == SwitchState.WAIT_FEATURES_REPLY) {
- this.sid = reply.getDatapathId();
- this.buffers = reply.getBuffers();
- this.capabilities = reply.getCapabilities();
- this.tables = reply.getTables();
- this.actions = reply.getActions();
- // notify core of this error event
- for (OFPhysicalPort port : reply.getPorts()) {
- updatePhysicalPort(port);
- }
- // config the switch to send full data packet
- OFSetConfig config = (OFSetConfig) factory
- .getMessage(OFType.SET_CONFIG);
- config.setMissSendLength((short) 0xffff).setLengthU(
- OFSetConfig.MINIMUM_LENGTH);
- asyncFastSend(config);
- // send config request to make sure the switch can handle the set
- // config
- OFMessage getConfig = factory.getMessage(OFType.GET_CONFIG_REQUEST);
- asyncFastSend(getConfig);
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.CONFIG_REQUEST_SENT);
- this.state = SwitchState.WAIT_CONFIG_REPLY;
- // inform core that a new switch is now operational
- reportSwitchStateChange(true);
- }
- }
-
-
- private void updatePhysicalPort(OFPhysicalPort port) {
- Short portNumber = port.getPortNumber();
- physicalPorts.put(portNumber, port);
- portBandwidth
- .put(portNumber,
- port.getCurrentFeatures()
- & (OFPortFeatures.OFPPF_10MB_FD.getValue()
- | OFPortFeatures.OFPPF_10MB_HD
- .getValue()
- | OFPortFeatures.OFPPF_100MB_FD
- .getValue()
- | OFPortFeatures.OFPPF_100MB_HD
- .getValue()
- | OFPortFeatures.OFPPF_1GB_FD
- .getValue()
- | OFPortFeatures.OFPPF_1GB_HD
- .getValue() | OFPortFeatures.OFPPF_10GB_FD
- .getValue()));
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.UPDATE_PHYSICAL_PORT);
- }
-
-
- private void reportSwitchStateChange(boolean added) {
- SwitchEvent ev = null;
- if (added) {
- ev = new SwitchEvent(SwitchEvent.SwitchEventType.SWITCH_ADD, this, null);
- controller.switchAdded(ev, switchChannelID);
- } else {
- ev = new SwitchEvent(SwitchEvent.SwitchEventType.SWITCH_DELETE, this, null);
- controller.switchDeleted(ev, switchChannelID);
- }
- }
-
-
- protected class SwitchLivelinessTimerTask implements TimerTask {
-
- @Override
- public void run(Timeout timeout) throws Exception {
-
- // set this reference in parent so that cancellation is
- // possible
- switchLivelinessTaskHandle = timeout;
- Long now = System.currentTimeMillis();
- if ((now - lastMsgReceivedTimeStamp) > switchLivenessTimeout) {
- if (state == SwitchState.WAIT_FEATURES_REPLY) {
- // send another features request
- OFMessage request = factory
- .getMessage(OFType.FEATURES_REQUEST);
- asyncFastSend(request);
- } else {
- if (state == SwitchState.WAIT_CONFIG_REPLY) {
- // send another config request
- OFSetConfig config = (OFSetConfig) factory
- .getMessage(OFType.SET_CONFIG);
- config.setMissSendLength((short) 0xffff)
- .setLengthU(OFSetConfig.MINIMUM_LENGTH);
- asyncFastSend(config);
- OFMessage getConfig = factory
- .getMessage(OFType.GET_CONFIG_REQUEST);
- asyncFastSend(getConfig);
- }
- }
- }
- timer.newTimeout(this, switchLivenessTimeout, TimeUnit.SECONDS);
-
- }
- }
-
-
- /*
- * Either a BarrierReply or a OFError is received. If this is a reply for an
- * outstanding sync message, wake up associated task so that it can continue
- */
- private void processBarrierReply(OFBarrierReply msg) {
- Integer xid = msg.getXid();
- SynchronousMessage worker = (SynchronousMessage) messageWaitingDone
- .remove(xid);
- if (worker == null) {
- return;
- }
- worker.wakeup();
- }
-
- private void processErrorReply(OFError errorMsg) {
- try{
- OFMessage offendingMsg = errorMsg.getOffendingMsg();
- Integer xi = 0;
- if (offendingMsg != null) {
- xi = offendingMsg.getXid();
- } else {
- xi = errorMsg.getXid();
- }
- }
- catch(MessageParseException mpe){
- reportError(mpe);
- }
- }
-
- private void processPortStatusMsg(OFPortStatus msg) {
- OFPhysicalPort port = msg.getDesc();
- if (msg.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
- updatePhysicalPort(port);
- } else if (msg.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
- updatePhysicalPort(port);
- } else if (msg.getReason() == (byte) OFPortReason.OFPPR_DELETE
- .ordinal()) {
- deletePhysicalPort(port);
- }
-
- }
-
- private void deletePhysicalPort(OFPhysicalPort port) {
- Short portNumber = port.getPortNumber();
- physicalPorts.remove(portNumber);
- portBandwidth.remove(portNumber);
- }
-
- private void processStatsReply(OFStatisticsReply reply) {
- Integer xid = reply.getXid();
- StatisticsCollector worker = (StatisticsCollector) messageWaitingDone
- .get(xid);
- if (worker == null) {
- return;
- }
- if (worker.collect(reply)) {
- // if all the stats records are received (collect() returns true)
- // then we are done.
- messageWaitingDone.remove(xid);
- worker.wakeup();
- }
- }
-
-
- /**
- * This method performs synchronous operations for a given message. If
- * syncRequest is set to true, the message will be sent out followed by a
- * Barrier request message. Then it's blocked until the Barrier rely arrives
- * or timeout. If syncRequest is false, it simply skips the message send and
- * just waits for the response back.
- *
- * @param msg
- * Message to be sent
- * @param xid
- * Message XID
- * @param request
- * If set to true, the message the message will be sent out
- * followed by a Barrier request message. If set to false, it
- * simply skips the sending and just waits for the Barrier reply.
- * @return the result
- */
- private Object syncMessageInternal(OFMessage msg, int xid, boolean syncRequest) {
- Object result = null;
-
- SynchronousMessage worker = new SynchronousMessage(this, xid, msg, syncRequest);
- messageWaitingDone.put(xid, worker);
-
- Boolean status = false;
- Future<Object> submit = executor.submit(worker);
- try {
- result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
- messageWaitingDone.remove(xid);
- if (result == null) {
- // if result is null, then it means the switch can handle this
- // message successfully
- // convert the result into a Boolean with value true
- status = true;
- // logger.debug("Successfully send " +
- // msg.getType().toString());
- result = status;
- } else {
- // if result is not null, this means the switch can't handle
- // this message
- // the result if OFError already
- logger.debug("Send {} failed --> {}", msg.getType().toString(),
- ((OFError) result).toString());
- }
- return result;
- } catch (Exception e) {
- logger.warn("Timeout while waiting for {} reply", msg.getType()
- .toString());
- // convert the result into a Boolean with value false
- status = false;
- result = status;
- return result;
- }
-
-
- }
-
-
- private void sendFirstHello() {
- try {
- OFMessage msg = factory.getMessage(OFType.HELLO);
- asyncFastSend(msg);
- trafficStatsHandler.countForSimpleMeasurement(TrafficStatisticsHandler.HELLO_SENT);
- trafficStatsHandler.addEntityForCounter(switchChannelID, TrafficStatisticsHandler.ENTITY_COUNTER_RCV_MSG);
- trafficStatsHandler.addEntityForCounter(switchChannelID, TrafficStatisticsHandler.ENTITY_COUNTER_SND_MSG);
- } catch (Exception e) {
- reportError(e);
- }
- }
-
-
- private void reportError(Exception e) {
- if (e instanceof AsynchronousCloseException
- || e instanceof InterruptedException
- || e instanceof SocketException || e instanceof IOException
- || e instanceof ClosedSelectorException) {
- logger.error("Caught exception {}", e.getMessage());
- } else {
- logger.error("Caught exception ", e);
- }
- // notify core of this error event and disconnect the switch
-
- // TODO: We do not need this because except-hanling is done by
- // Controller's OFChannelHandler
-
- /*
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_ERROR, this, null);
-
- controller.switchError(ev, switchChannelID);
- */
- }
-
-
- @Override
- public void flushBufferedMessages() {
- //flushBatchTrack++;
- //if (flushBatchTrack > BATCH_COUNT_FOR_FLUSHING){
- synchronized (flushableMsgBuffer) {
- if (flushableMsgBuffer.size() > 0){
- channel.write(flushableMsgBuffer);
- flushableMsgBuffer.clear();
- }
- }
- // flushBatchTrack = 0;
- //}
-
- }
-
- @Override
- public SocketAddress getRemoteAddress() {
- return (channel != null) ? channel.getRemoteAddress() : null;
- }
-
- @Override
- public SocketAddress getLocalAddress() {
- return (channel != null) ? channel.getLocalAddress() : null;
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.openflow.protocol.OFFeaturesReply;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.statistics.OFDescriptionStatistics;
-
-/**
- * Wrapper class to hold state for the OpenFlow switch connection
- * @author readams
- */
-class OFChannelState {
-
- /**
- * State for handling the switch handshake
- */
- protected enum HandshakeState {
- /**
- * Beginning state
- */
- START,
-
- /**
- * Received HELLO from switch
- */
- HELLO,
-
- /**
- * We've received the features reply
- * Waiting for Config and Description reply
- */
- FEATURES_REPLY,
-
- /**
- * Switch is ready for processing messages
- */
- READY
-
- }
-
- protected volatile HandshakeState hsState = HandshakeState.START;
- protected boolean hasGetConfigReply = false;
- protected boolean hasDescription = false;
- protected boolean switchBindingDone = false;
-
- protected OFFeaturesReply featuresReply = null;
- protected OFDescriptionStatistics description = null;
- protected List<OFMessage> queuedOFMessages = new ArrayList<OFMessage>();
-}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.util.List;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.protocol.factory.OFMessageFactory;
-
-/**
- * Decode an openflow message from a Channel, for use in a netty
- * pipeline
- * @author readams
- */
-public class OFMessageDecoder extends FrameDecoder {
-
- OFMessageFactory factory = new BasicFactory();
-
- @Override
- protected Object decode(ChannelHandlerContext ctx, Channel channel,
- ChannelBuffer buffer) throws Exception {
- if (!channel.isConnected()) {
- // In testing, I see decode being called AFTER decode last.
- // This check avoids that from reading curroupted frames
- return null;
- }
-
- List<OFMessage> message = factory.parseMessage(buffer);
- return message;
- }
-
- @Override
- protected Object decodeLast(ChannelHandlerContext ctx, Channel channel,
- ChannelBuffer buffer) throws Exception {
- // This is not strictly needed atthis time. It is used to detect
- // connection reset detection from netty (for debug)
- return null;
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.util.List;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
-import org.openflow.protocol.OFMessage;
-
-/**
- * Encode an openflow message for output into a ChannelBuffer, for use in a
- * netty pipeline
- * @author readams
- */
-public class OFMessageEncoder extends OneToOneEncoder {
-
- @Override
- protected Object encode(ChannelHandlerContext ctx, Channel channel,
- Object msg) throws Exception {
- if (!( msg instanceof List))
- return msg;
-
- @SuppressWarnings("unchecked")
- List<OFMessage> msglist = (List<OFMessage>)msg;
- int size = 0;
- for (OFMessage ofm : msglist) {
- size += ofm.getLengthU();
- }
-
- ChannelBuffer buf = ChannelBuffers.buffer(size);;
- for (OFMessage ofm : msglist) {
- ofm.writeTo(buf);
- }
- return buf;
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.util.concurrent.ThreadPoolExecutor;
-
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.timeout.IdleStateHandler;
-import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timer;
-
-/**
- * Creates a ChannelPipeline for a server-side openflow channel
- * @author readams
- */
-public class OpenflowPipelineFactory implements ChannelPipelineFactory {
-
- private static final int READ_TIMEOUT = 30;
- private static final int READER_IDLE_TIMEOUT = 20;
- private static final int WRITER_IDLE_TIMEOUT = 25;
- private static final int ALL_IDLE_TIMEOUT = 0;
-
- protected EnhancedController controller;
- protected ThreadPoolExecutor pipelineExecutor;
- protected Timer timer;
- protected IdleStateHandler idleHandler;
- protected ReadTimeoutHandler readTimeoutHandler;
-
- public OpenflowPipelineFactory(EnhancedController controller,
- ThreadPoolExecutor pipelineExecutor) {
- super();
- this.controller = controller;
- this.pipelineExecutor = pipelineExecutor;
- this.timer = new HashedWheelTimer();
- this.idleHandler = new IdleStateHandler(timer, READER_IDLE_TIMEOUT, WRITER_IDLE_TIMEOUT, ALL_IDLE_TIMEOUT);
- this.readTimeoutHandler = new ReadTimeoutHandler(timer, READ_TIMEOUT);
- }
-
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- //OFChannelState state = new OFChannelState();
-
-
- ChannelPipeline pipeline = Channels.pipeline();
-
- /*
- if (pipelineExecutor != null)
- pipeline.addLast("pipelineExecutor",
- new ExecutionHandler(pipelineExecutor));*/
- pipeline.addLast("ofmessagedecoder", new OFMessageDecoder());
- pipeline.addLast("ofmessageencoder", new OFMessageEncoder());
- pipeline.addLast("idle", idleHandler);
- //pipeline.addLast("timeout", readTimeoutHandler);
- //pipeline.addLast("handshaketimeout",
- // new HandshakeTimeoutHandler(state, timer, 15));
-
- /*
- if (pipelineExecutor != null)
- pipeline.addLast("pipelineExecutor",
- new ExecutionHandler(pipelineExecutor));*/
- pipeline.addLast("handler", controller.getChannelHandler());
- return pipeline;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-public class TrafficStatisticsHandler {
-
-
- private static final Logger logger = LoggerFactory
- .getLogger(EnhancedController.class);
-
- private Timeout statsTaskHandle = null;
-
- private Map<String, AtomicLong> currentCounterMap = new ConcurrentHashMap<String, AtomicLong>();
- private Map<String, AtomicLong> lastCounterMap = new ConcurrentHashMap<String, AtomicLong>();
- private Map<String, Long> lastMeasurementTStamp = new ConcurrentHashMap<String, Long>();
- private List<String> rawRateMeasurementData = new ArrayList<String>();
-
- private ConcurrentHashMap<Integer, AtomicLong> msgRcvEntityCounter =
- new ConcurrentHashMap<Integer, AtomicLong>();
- private ConcurrentHashMap<Integer, AtomicLong> msgSndEntityCounter =
- new ConcurrentHashMap<Integer, AtomicLong>();
-
-
-
- private static final long STATISTICS_RATE_INTERVAL = 25000;
- private static final int STATISTICS_PRINT_INTREVAL = 180;
- private static List<Long> packetInProcessingTimeList = new ArrayList<Long>();
- private static List<Integer> pendingTaskCountList = new ArrayList<Integer>();
-
-
- public static final String ENTITY_COUNTER_RCV_MSG = "SWITCHWISE_RCV_MSG_COUNT";
- public static final String ENTITY_COUNTER_SND_MSG = "SWITCHWISE_SND_MSG_COUNT";
-
- private HashedWheelTimer hashedWheelTimer = null;
-
- public static final String ADDED_SWITCHES = "ADDED_SWITCHES";
- public static final String CONNECTED_SWITCHES = "CONNECTED_SWITCHES";
- public static final String DELETED_SWITCHES = "DELETED_SWITCHES";
- public static final String DISCONNECTED_SWITCHES = "DISCONNECTED_SWITCHES";
- public static final String SWITCH_ERROR = "SWITCH_ERROR";
-
-
-
- public static final String EXCEPTION_CAUGHT = "EXCEPTION_CAUGHT";
- public static final String MESSAGE_RECEIVED = "MESSAGE_RECEIVED"; // DO RATE-MEASUREMENTS
-
- public static final String MSG_LISTENER_INVOCATION = "MSG_LISTENER_INVOCATION";
- public static final String HELLO_RECEIVED = "HELLO_RECEIVED";
- public static final String HELLO_SENT = "HELLO_SENT";
- public static final String ECHO_REQUEST_SENT = "ECHO_REQUEST_SENT";
- public static final String ECHO_REQUEST_RECEIVED = "ECHO_REQUEST_RECEIVED";
- public static final String ECHO_REPLY_SENT = "ECHO_REPLY_SENT";
- public static final String ECHO_REPLY_RECEIVED = "ECHO_REPLY_RECEIVED";
- public static final String FEATURES_REQUEST_SENT = "FEATURES_REQUEST_SENT";
- public static final String FEATURES_REQUEST_RECEIVED = "FEATURES_REQUEST_RECEIVED";
- public static final String FEATURES_REPLY_SENT = "FEATURES_REPLY_SENT";
- public static final String FEATURES_REPLY_RECEIVED = "FEATURES_REPLY_RECEIVED";
- public static final String CONFIG_REQUEST_SENT = "CONFIG_REQUEST_SENT";
- public static final String CONFIG_REQUEST_RECEIVED = "CONFIG_REQUEST_RECEIVED";
- public static final String CONFIG_REPLY_SENT = "CONFIG_REPLY_SENT";
- public static final String CONFIG_REPLY_RECEIVED = "CONFIG_REPLY_RECEIVED";
- public static final String BARRIER_REQUEST_SENT = "BARRIER_REQUEST_SENT";
- public static final String BARRIER_REPLY_RECEIVED = "BARRIER_REPLY_RECEIVED";
- public static final String ERROR_MSG_RECEIVED = "ERROR_MSG_RECEIVED";
- public static final String PORT_STATUS_RECEIVED = "PORT_STATUS";
- public static final String PACKET_IN_RECEIVED = "PACKET_IN"; // DO RATE-MEASUREMENTS
- public static final String FLOW_MOD_SENT = "FLOW_MOD_SENT"; // DO RATE-MEASUREMENTS ==> To be determined as to where to collect this data from
- public static final String STATS_REQUEST_SENT = "STATS_REQUEST_SENT"; // DO RATE-MEASUREMENTS ==> To be determined as to where to collect this data from
- public static final String STATS_RESPONSE_RECEIVED = "STATS_RESPONSE_RECEIVED";
-
- public static final String UPDATE_PHYSICAL_PORT = "UPDATE_PHYSICAL_PORT";
-
- private static final int TASK_SCHEDULE_INITIAL_DELAY_IN_SECONDS = 10;
-
- private int trackPktInProcessing = 0;
- private static final int PKT_IN_PROCESSING_DURATION_SAMPLING_COUNT = 100000;
-
-
- public TrafficStatisticsHandler(HashedWheelTimer timer){
- this.hashedWheelTimer = timer;
- }
-
-
- public void init(){
-
- currentCounterMap.put(MSG_LISTENER_INVOCATION, new AtomicLong(0));
- currentCounterMap.put(ADDED_SWITCHES, new AtomicLong(0));
- currentCounterMap.put(DELETED_SWITCHES, new AtomicLong(0));
- currentCounterMap.put(CONNECTED_SWITCHES, new AtomicLong(0));
- currentCounterMap.put(DISCONNECTED_SWITCHES, new AtomicLong(0));
- currentCounterMap.put(SWITCH_ERROR, new AtomicLong(0));
- currentCounterMap.put(HELLO_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(HELLO_SENT, new AtomicLong(0));
- currentCounterMap.put(ECHO_REQUEST_SENT, new AtomicLong(0));
- currentCounterMap.put(ECHO_REQUEST_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(ECHO_REPLY_SENT, new AtomicLong(0));
- currentCounterMap.put(ECHO_REPLY_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(EXCEPTION_CAUGHT, new AtomicLong(0));
- currentCounterMap.put(MESSAGE_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(FEATURES_REQUEST_SENT, new AtomicLong(0));
- currentCounterMap.put(FEATURES_REQUEST_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(FEATURES_REPLY_SENT, new AtomicLong(0));
- currentCounterMap.put(FEATURES_REPLY_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(CONFIG_REQUEST_SENT, new AtomicLong(0));
- currentCounterMap.put(CONFIG_REQUEST_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(CONFIG_REPLY_SENT, new AtomicLong(0));
- currentCounterMap.put(CONFIG_REPLY_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(BARRIER_REQUEST_SENT, new AtomicLong(0));
- currentCounterMap.put(BARRIER_REPLY_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(ERROR_MSG_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(PORT_STATUS_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(PACKET_IN_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(FLOW_MOD_SENT, new AtomicLong(0));
- currentCounterMap.put(STATS_REQUEST_SENT, new AtomicLong(0));
- currentCounterMap.put(STATS_RESPONSE_RECEIVED, new AtomicLong(0));
- currentCounterMap.put(UPDATE_PHYSICAL_PORT, new AtomicLong(0));
-
- lastCounterMap.put(MSG_LISTENER_INVOCATION, new AtomicLong(0));
- lastCounterMap.put(ADDED_SWITCHES, new AtomicLong(0));
- lastCounterMap.put(DELETED_SWITCHES, new AtomicLong(0));
- lastCounterMap.put(CONNECTED_SWITCHES, new AtomicLong(0));
- lastCounterMap.put(DISCONNECTED_SWITCHES, new AtomicLong(0));
- lastCounterMap.put(SWITCH_ERROR, new AtomicLong(0));
- lastCounterMap.put(HELLO_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(HELLO_SENT, new AtomicLong(0));
- lastCounterMap.put(FEATURES_REQUEST_SENT, new AtomicLong(0));
- lastCounterMap.put(FEATURES_REQUEST_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(ECHO_REQUEST_SENT, new AtomicLong(0));
- lastCounterMap.put(ECHO_REQUEST_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(ECHO_REPLY_SENT, new AtomicLong(0));
- lastCounterMap.put(ECHO_REPLY_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(EXCEPTION_CAUGHT, new AtomicLong(0));
- lastCounterMap.put(MESSAGE_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(FEATURES_REPLY_SENT, new AtomicLong(0));
- lastCounterMap.put(FEATURES_REPLY_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(CONFIG_REQUEST_SENT, new AtomicLong(0));
- lastCounterMap.put(CONFIG_REQUEST_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(CONFIG_REPLY_SENT, new AtomicLong(0));
- lastCounterMap.put(CONFIG_REPLY_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(BARRIER_REQUEST_SENT, new AtomicLong(0));
- lastCounterMap.put(BARRIER_REPLY_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(ERROR_MSG_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(PORT_STATUS_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(PACKET_IN_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(FLOW_MOD_SENT, new AtomicLong(0));
- lastCounterMap.put(STATS_REQUEST_SENT, new AtomicLong(0));
- lastCounterMap.put(STATS_RESPONSE_RECEIVED, new AtomicLong(0));
- lastCounterMap.put(UPDATE_PHYSICAL_PORT, new AtomicLong(0));
-
- lastMeasurementTStamp.put(MSG_LISTENER_INVOCATION, new Long(0));
- lastMeasurementTStamp.put(ADDED_SWITCHES, new Long(0));
- lastMeasurementTStamp.put(DELETED_SWITCHES, new Long(0));
- lastMeasurementTStamp.put(CONNECTED_SWITCHES, new Long(0));
- lastMeasurementTStamp.put(DISCONNECTED_SWITCHES, new Long(0));
- lastMeasurementTStamp.put(SWITCH_ERROR, new Long(0));
- lastMeasurementTStamp.put(HELLO_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(HELLO_SENT, new Long(0));
- lastMeasurementTStamp.put(ECHO_REQUEST_SENT, new Long(0));
- lastMeasurementTStamp.put(ECHO_REQUEST_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(ECHO_REPLY_SENT, new Long(0));
- lastMeasurementTStamp.put(ECHO_REPLY_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(EXCEPTION_CAUGHT, new Long(0));
- lastMeasurementTStamp.put(MESSAGE_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(FEATURES_REQUEST_SENT, new Long(0));
- lastMeasurementTStamp.put(FEATURES_REQUEST_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(FEATURES_REPLY_SENT, new Long(0));
- lastMeasurementTStamp.put(FEATURES_REPLY_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(CONFIG_REQUEST_SENT, new Long(0));
- lastMeasurementTStamp.put(CONFIG_REQUEST_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(CONFIG_REPLY_SENT, new Long(0));
- lastMeasurementTStamp.put(CONFIG_REPLY_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(BARRIER_REQUEST_SENT, new Long(0));
- lastMeasurementTStamp.put(BARRIER_REPLY_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(ERROR_MSG_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(PORT_STATUS_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(PACKET_IN_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(FLOW_MOD_SENT, new Long(0));
- lastMeasurementTStamp.put(STATS_REQUEST_SENT, new Long(0));
- lastMeasurementTStamp.put(STATS_RESPONSE_RECEIVED, new Long(0));
- lastMeasurementTStamp.put(UPDATE_PHYSICAL_PORT, new Long(0));
-
- /*
- rateMap.put(HELLO_SENT, new Double(0.00000000));
- rateMap.put(FEATURES_REQUEST, new Double(0.00000000));
- rateMap.put(FEATURES_REPLY, new Double(0.00000000));
- rateMap.put(CONFIG_REQUEST, new Double(0.00000000));
- rateMap.put(CONFIG_REPLY, new Double(0.00000000));
- rateMap.put(PORT_STATUS, new Double(0.00000000));
- rateMap.put(PACKET_IN, new Double(0.00000000));
- rateMap.put(FLOW_MOD_SENT, new Double(0.00000000));
-
-
- history.put(HELLO_SENT, new ArrayList());
- history.put(FEATURES_REQUEST, new ArrayList());
- history.put(FEATURES_REPLY, new ArrayList());
- history.put(CONFIG_REQUEST, new ArrayList());
- history.put(CONFIG_REPLY, new ArrayList());
- history.put(PORT_STATUS, new ArrayList());
- history.put(PACKET_IN, new ArrayList());
- history.put(FLOW_MOD_SENT, new ArrayList());
- */
-
- statsTaskHandle = this.hashedWheelTimer.newTimeout(new StatsOutTask(),
- TASK_SCHEDULE_INITIAL_DELAY_IN_SECONDS, TimeUnit.SECONDS);
-
- }
-
- public void stopStatsHandler(){
- if (statsTaskHandle != null){
- statsTaskHandle.cancel();
- }
- }
-
- public void reportPacketInProcessingTime(long duration){
- trackPktInProcessing++;
- if (trackPktInProcessing > PKT_IN_PROCESSING_DURATION_SAMPLING_COUNT){
- packetInProcessingTimeList.add(new Long(duration));
- trackPktInProcessing = 0;
- }
- }
-
- public void addEntityForCounter(Integer entityID, String counterType){
- if (counterType.equalsIgnoreCase(ENTITY_COUNTER_RCV_MSG)){
- msgRcvEntityCounter.put(entityID, new AtomicLong(0));
- }
- else{
- msgSndEntityCounter.put(entityID, new AtomicLong(0));
- }
- }
-
- public void countForEntitySimpleMeasurement(Integer entityID, String counterType){
- if (counterType.equalsIgnoreCase(ENTITY_COUNTER_RCV_MSG)){
- //msgRcvEntityCounter.get(entityID).incrementAndGet();
- }
- else{
- //msgSndEntityCounter.get(entityID).incrementAndGet();
- }
- }
-
-
- public void countForSimpleMeasurement(String counterName){
- currentCounterMap.get(counterName).incrementAndGet();
- }
-
- public void countForRateMeasurement(String counterName){
-
- long currCntr = currentCounterMap.get(counterName).incrementAndGet();
- if (lastMeasurementTStamp.get(counterName) == 0){
- lastMeasurementTStamp.put(counterName, System.currentTimeMillis());
- }
-
- Long currentCount = new Long(currCntr);
- Long lastCount = lastCounterMap.get(counterName).get();
-
- //Double rate = 0.00000000000;
- if ((currentCount - lastCount) == STATISTICS_RATE_INTERVAL){
- Long currentTime = System.currentTimeMillis();
- Long lastTime = lastMeasurementTStamp.get(counterName);
- //rate = new Double((STATISTICS_RATE_INTERVAL/(currentTime-lastTime))*1000); //convert to count/sec
- rawRateMeasurementData.add("CN:" + counterName +
- ",CC:" + currentCount +
- ",LC:" + lastCount +
- ",CT:" + currentTime +
- ",LT:" + lastTime +
- ",CV:" + ((STATISTICS_RATE_INTERVAL/(currentTime-lastTime))*1000));
- lastCounterMap.put(counterName, new AtomicLong(currentCount));
- lastMeasurementTStamp.put(counterName, currentTime);
- //history.get(counterName).add(String.valueOf(rate.doubleValue()));
- //rateMap.put(counterName, rate);
- }
-
- }
-
-
- private class StatsOutTask implements TimerTask {
-
- @Override
- public void run(Timeout timeout) throws Exception {
-
- statsTaskHandle = timeout;
- logger.warn(">>>>>>Raw Counter values at controller BEGIN<<<<<<<<");
-
- for (Entry<String, AtomicLong> entry : currentCounterMap.entrySet()){
- logger.warn("{} {}", entry.getKey(), entry.getValue());
- }
- logger.warn(">>>>>>Counter values at controller END <<<<<<<<");
-
- logger.warn(">>>>>>Entity Counter values at controller BEGIN<<<<<<<<");
-
- for (Entry<Integer, AtomicLong> entry : msgRcvEntityCounter.entrySet()){
- logger.warn("SwitchID {} : Rcv Msg Count {}", entry.getKey(), entry.getValue());
- }
- logger.warn(">>>>>>Entity Counter values at controller END <<<<<<<<");
-
- logger.warn(">>>>>>Raw data rate values at controller BEGIN<<<<<<<<");
-
- for (String str : rawRateMeasurementData ){
- logger.warn("{}", str);
- }
- logger.warn(">>>>>>Raw data rate values at controller END <<<<<<<<");
-
-
- if (packetInProcessingTimeList.size() > 0){
- logger.warn("================ MAX PACKET_IN PROC TIME in microseconds : {}",
- Collections.max(packetInProcessingTimeList)/1000);
- logger.warn("================ MIN PACKET_IN PROC TIME in microseconds : {}",
- Collections.min(packetInProcessingTimeList)/1000);
- long v = 0L;
- int track = 0;
- for (Long val : packetInProcessingTimeList){
- v = v + val.longValue();
- track++;
- }
- logger.warn("================ AVG PACKET_IN PROC TIME in microseconds : {}",
- ((double)(v/track))/1000);
- }
- hashedWheelTimer.newTimeout(this, STATISTICS_PRINT_INTREVAL, TimeUnit.SECONDS);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.protocol_plugin.openflow.internal;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.protocol_plugin.openflow.core.internal.EnhancedController;
-import org.opendaylight.openflowplugin.openflow.core.internal.Controller;
-import org.opendaylight.openflowplugin.openflow.internal.Activator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Openflow protocol plugin Activator
- *
- *
- */
-public class EnhancedActivator extends Activator {
- protected static final Logger logger = LoggerFactory
- .getLogger(EnhancedActivator.class);
-
- // Default Constructor for the activator
- public EnhancedActivator() {
- super();
- logger.debug("Enhanced activator called!");
- }
-
- /**
- * Function that is used to communicate to dependency manager the list of
- * known implementations for services that are container independent.
- *
- *
- * @return An array containing all the CLASS objects that will be
- * instantiated in order to get an fully working implementation
- * Object
- */
- @Override
- public Object[] getGlobalImplementations() {
- Object[] res = super.getGlobalImplementations();
- // Now remove the Controller.class and return the
- // EnhancedController
- List resList = new ArrayList(Arrays.asList(res));
- resList.remove(Controller.class);
- resList.add(EnhancedController.class);
- return resList.toArray();
- }
-
- /**
- * Function that is called when configuration of the dependencies is
- * required.
- *
- * @param c
- * dependency manager Component object, used for configuring the
- * dependencies exported and imported
- * @param imp
- * Implementation class that is being configured, needed as long
- * as the same routine can configure multiple implementations
- */
- @Override
- public void configureGlobalInstance(Component c, Object imp) {
- if (imp.equals(EnhancedController.class)) {
- // Configure it like if was the Controller.class
- super.configureGlobalInstance(c, Controller.class);
- } else {
- super.configureGlobalInstance(c, imp);
- }
- }
-}
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
- <relativePath>../commons</relativePath>
+ <relativePath>../</relativePath>
</parent>
<artifactId>openflowplugin-it</artifactId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-netconf-connector</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
switchSim.setSecuredClient(false);
Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenarioVBM(
ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13);
-
+
ScenarioHandler scenario = new ScenarioHandler(handshakeScenario);
switchSim.setScenarioHandler(scenario);
switchSim.start();
}
//TODO: dump errors of plugin
}
-
+
/**
* test basic integration with OFLib running the handshake (with version bitmap)
* @throws Exception
switchSim.setSecuredClient(false);
Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenario(
(short) 0, ScenarioFactory.VERSION_BITMAP_10_13);
-
+
ScenarioHandler scenario = new ScenarioHandler(handshakeScenario);
switchSim.setScenarioHandler(scenario);
switchSim.start();
}
//TODO: dump errors of plugin
}
-
+
/**
* test basic integration with OFLib running the handshake
* @throws Exception
switchSim = new SimpleClient("localhost", 6653);
switchSim.setSecuredClient(false);
- Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenario((short) 1,
+ Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenario((short) 1,
ScenarioFactory.VERSION_BITMAP_10_13);
-
+
ScenarioHandler scenario = new ScenarioHandler(handshakeScenario);
switchSim.setScenarioHandler(scenario);
switchSim.start();
}
//TODO: dump errors of plugin
}
-
+
/**
* test basic integration with OFLib running the handshake
* @throws Exception
switchSim = new SimpleClient("localhost", 6653);
switchSim.setSecuredClient(false);
- Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenario((short) 1,
+ Stack<ClientEvent> handshakeScenario = ScenarioFactory.createHandshakeScenario((short) 1,
ScenarioFactory.VERSION_BITMAP_10_13);
handshakeScenario.setElementAt(new SleepEvent(5000), 0);
-
+
ScenarioHandler scenario = new ScenarioHandler(handshakeScenario);
switchSim.setScenarioHandler(scenario);
switchSim.start();
mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager").versionAsInProject(),
TestHelper.mdSalCoreBundles(), TestHelper.bindingAwareSalBundles(),
TestHelper.flowCapableModelBundles(), TestHelper.baseModelBundles(),
-
-
+
+
mavenBundle(ODL, "sal").versionAsInProject(),
mavenBundle(ODL, "sal.connection").versionAsInProject(),
mavenBundle(ODL, "sal-common").versionAsInProject(),
- mavenBundle("org.opendaylight.controller.thirdparty", "org.openflow.openflowj").versionAsInProject(),
mavenBundle(ODL_MODEL, "model-flow-statistics").versionAsInProject(),
mavenBundle(OFLIBRARY, "openflow-protocol-impl").versionAsInProject(),
mavenBundle(NETTY, "netty-codec").versionAsInProject(),
mavenBundle(OFLIBRARY, "simple-client").versionAsInProject().start(),
- mavenBundle(OFPLUGIN, "openflowplugin").versionAsInProject(), junitBundles(),
- mavenBundle("org.opendaylight.controller.thirdparty", "org.openflow.openflowj").versionAsInProject()
+ mavenBundle(OFPLUGIN, "openflowplugin").versionAsInProject(), junitBundles()
);
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
-
- <modules>
- <module>../commons</module>
- <module>../openflow_netty</module>
- <module>../openflowplugin</module>
- <module>../distribution/base</module>
- <module>../openflowplugin-it</module>
- <module>../test-provider</module>
- </modules>
-</project>
-
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
- <relativePath>../commons</relativePath>
+ <relativePath>../</relativePath>
</parent>
<artifactId>openflowplugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
- <Export-Package>
- org.opendaylight.openflowplugin.openflow.internal
- </Export-Package>
- <Embed-Transitive>
- false
- </Embed-Transitive>
<Bundle-Activator>
- org.opendaylight.openflowplugin.openflow.internal.Activator
+ org.opendaylight.openflowplugin.openflow.md.Activator
</Bundle-Activator>
+ <Private-Package>
+ org.opendaylight.openflowplugin.md.*
+ </Private-Package>
</instructions>
<manifestLocation>${project.build.directory}/META-INF</manifestLocation>
</configuration>
<artifactId>sal.connection</artifactId>
<version>0.1.1-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller.thirdparty</groupId>
- <artifactId>org.openflow.openflowj</artifactId>
- <version>1.0.2-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-base</artifactId>
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/**
- * @file IDataPacketListen.java
- *
- * @brief Interface to dispatch locally in the protocol plugin the
- * data packets, intended especially for Discovery, main difference
- * here with the analogous of SAL is that this is Global
- * inherently
- *
- */
-package org.opendaylight.openflowplugin.openflow;
-
-import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.packet.PacketResult;
-
-/**
- * Interface to dispatch locally in the protocol plugin the
- * data packets, intended especially for Discovery, main difference
- * here with the analogous of SAL is that this is Global
- * inherently.
- */
-public interface IDataPacketListen {
- /**
- * Dispatch received data packet
- *
- * @param inPkt
- * The incoming raw packet
- * @return Possible results for Data packet processing handler
- */
- public PacketResult receiveDataPacket(RawPacket inPkt);
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-/**
- * @file IDataPacketMux.java
- *
- * @brief Simple wrapped interface for the IPluginInDataPacketService
- * which will be only exported by DataPacketServices mux/demux
- * component and will be only accessible by the openflow protocol
- * plugin
- */
-
-import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
-
-/**
- * Simple wrapped interface for the IPluginInDataPacketService
- * which will be only exported by DataPacketServices mux/demux
- * component and will be only accessible by the openflow protocol
- * plugin
- */
-public interface IDataPacketMux extends IPluginInDataPacketService {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import org.opendaylight.controller.sal.discovery.IDiscoveryService;
-
-/**
- * The interface provides method to notify the local plugin listener when an
- * edge is discovered or removed.
- */
-public interface IDiscoveryListener extends IDiscoveryService {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService;
-
-/**
- * Interface which defines the methods exposed by the Flow Programmer Notifier.
- * Their implementation relays the asynchronous messages received from the
- * network nodes to the the SAL Flow Programmer Notifier Service on the proper
- * container.
- */
-public interface IFlowProgrammerNotifier extends
- IPluginOutFlowProgrammerService {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
-
-/**
- * The Interface provides inventory service to the local plugin modules
- */
-public interface IInventoryProvider extends IPluginInInventoryService {
-
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-/**
- * Wrapper of Interface that provides inventory updates locally in the protocol
- * plugin.
- */
-public interface IInventoryShimExternalListener extends
- IInventoryShimInternalListener {
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.Set;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-
-/**
- * The Interface provides inventory updates to inventory listeners within the
- * protocol plugin
- */
-public interface IInventoryShimInternalListener {
- /**
- * Updates node and its properties
- *
- * @param node {@link org.opendaylight.controller.sal.core.Node} being updated
- * @param type {@link org.opendaylight.controller.sal.core.UpdateType}
- * @param props set of {@link org.opendaylight.controller.sal.core.Property} such as
- * {@link org.opendaylight.controller.sal.core.Description} and/or
- * {@link org.opendaylight.controller.sal.core.Tier} etc.
- */
- public void updateNode(Node node, UpdateType type, Set<Property> props);
-
- /**
- * Updates node connector and its properties
- *
- * @param nodeConnector {@link org.opendaylight.controller.sal.core.NodeConnector} being updated
- * @param type {@link org.opendaylight.controller.sal.core.UpdateType}
- * @param props set of {@link org.opendaylight.controller.sal.core.Property} such as
- * {@link org.opendaylight.controller.sal.core.Description} and/or
- * {@link org.opendaylight.controller.sal.core.State} etc.
- */
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props);
-
-}
+++ /dev/null
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.List;
-
-import org.openflow.protocol.statistics.OFStatistics;
-
-/**
- * Interface defines the api which gets called when the information
- * contained in the OF statistics reply message from a network is updated with
- * new one.
- */
-public interface IOFStatisticsListener {
- public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> description);
-
- public void flowStatisticsRefreshed(Long switchId, List<OFStatistics> flows);
-
- public void portStatisticsRefreshed(Long switchId, List<OFStatistics> ports);
-
- public void tableStatisticsRefreshed(Long switchId, List<OFStatistics> tables);
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.List;
-
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.openflow.protocol.statistics.OFStatisticsType;
-
-/**
- * Interface to expose the openflow statistics collected on the switches
- */
-public interface IOFStatisticsManager {
- /**
- * Return all the statistics for all the flows present on the specified switch
- *
- * @param switchId the openflow datapath id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFFlowStatistics(Long switchId);
-
- /**
- * Return all the statistics for all the flows present on the specified switch
- *
- * @param switchId the openflow datapath id
- * @param ofMatch the openflow match to query. If null, the query is intended for all the flows
- * @param priority Priority of the wanted flow
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFFlowStatistics(Long switchId, OFMatch ofMatch, short priority);
-
- /**
- * Return the description statistics for the specified switch.
- *
- * @param switchId the openflow datapath id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFDescStatistics(Long switchId);
-
- /**
- * Returns the statistics for all the ports on the specified switch
- *
- * @param switchId the openflow datapath id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFPortStatistics(Long switchId);
-
- /**
- * Returns the statistics for the specified switch port
- *
- * @param switchId the openflow datapath id
- * @param portId the openflow switch port id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFPortStatistics(Long switchId, short portId);
-
- /**
- * Returns the number of flows installed on the switch
- *
- * @param switchId the openflow datapath id
- * @return the number of flows installed on the switch
- */
- int getFlowsNumber(long switchId);
-
- /**
- * Send a statistics request message to the specified switch and returns
- * the switch response. It blocks the caller until the response has arrived
- * from the switch or the request has timed out
- *
- * @param switchId the openflow datapath id of the target switch
- * @param statType the openflow statistics type
- * @param target the target object. For flow statistics it is the OFMatch.
- * For port statistics, it is the port id. If null the query
- * will be performed for all the targets for the specified
- * statistics type.
- *
- * @param timeout the timeout in milliseconds the system will wait for a response
- * from the switch, before declaring failure
- * @return the list of openflow statistics
- */
- List<OFStatistics> queryStatistics(Long switchId,
- OFStatisticsType statType, Object target);
-
- /**
- * Returns the averaged transmit rate for the passed switch port
- *
- * @param switchId the openflow datapath id of the target switch
- * @param portId the openflow switch port id
- * @return the median transmit rate in bits per second
- */
- long getTransmitRate(Long switchId, Short port);
-
- /**
- * Returns the statistics for the specified switch table
- *
- * @param switchId the openflow datapath id
- * @param tableId the openflow switch table id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFTableStatistics(Long switchId, Byte tableId);
-
- /**
- * Returns all the table statistics for the node specified
- *
- * @param switchId the openflow datapath id
- * @return the list of openflow statistics
- */
- List<OFStatistics> getOFTableStatistics(Long switchId);
-
-}
+++ /dev/null
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.reader.FlowOnNode;
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
-import org.opendaylight.controller.sal.reader.NodeDescription;
-import org.opendaylight.controller.sal.reader.NodeTableStatistics;
-
-/**
- * The Interface provides statistics updates to ReaderFilter listeners within
- * the protocol plugin
- */
-public interface IReadFilterInternalListener {
-
- /**
- * Notifies the hardware view of all the flow installed on the specified network node
- * @param node
- * @return
- */
- public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList);
-
- /**
- * Notifies the hardware view of the specified network node connector
- * @param node
- * @return
- */
- public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList);
-
- /**
- * Notifies all the table statistics for a node
- * @param node
- * @return
- */
- public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList);
-
- /**
- * Notifies the hardware view of all the flow installed on the specified network node
- * @param node
- * @return
- */
- public void nodeDescriptionStatisticsUpdated(Node node, NodeDescription nodeDescription);
-
-
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.NodeTable;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.reader.FlowOnNode;
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
-import org.opendaylight.controller.sal.reader.NodeDescription;
-import org.opendaylight.controller.sal.reader.NodeTableStatistics;
-
-/**
- * Interface to serve the hardware information requests coming from SAL
- * It is implemented by the respective OF1.0 plugin component
- *
- */
-public interface IReadServiceFilter {
- /**
- * Returns the hardware image for the specified flow
- * on the specified network node for the passed container
- *
- * @param container
- * @param node
- * @param flow
- * @param cached
- * @return
- */
- public FlowOnNode readFlow(String container, Node node, Flow flow,
- boolean cached);
-
- /**
- * Returns the hardware view of all the flow installed
- * on the specified network node for the passed container
- *
- * @param container
- * @param node
- * @param cached
- * @return
- */
- public List<FlowOnNode> readAllFlow(String container, Node node,
- boolean cached);
-
- /**
- * Returns the description of the network node as provided by the node itself
- *
- * @param node
- * @param cached
- * @return
- */
- public NodeDescription readDescription(Node node, boolean cached);
-
- /**
- * Returns the hardware view of the specified network node connector
- * for the given container
- * @param node
- * @return
- */
- public NodeConnectorStatistics readNodeConnector(String container,
- NodeConnector nodeConnector, boolean cached);
-
- /**
- * Returns the hardware info for all the node connectors on the
- * specified network node for the given container
- *
- * @param node
- * @return
- */
- public List<NodeConnectorStatistics> readAllNodeConnector(String container,
- Node node, boolean cached);
-
- /**
- * Returns the table statistics of the node as specified by the given container
- * @param node
- * @param cached
- * @return
- */
- public NodeTableStatistics readNodeTable(String container,
- NodeTable nodeTable, boolean cached);
-
- /**
- * Returns the table statistics of all the tables for the specified node
- *
- * @param node
- * @return
- */
- public List<NodeTableStatistics> readAllNodeTable(String containerName,
- Node node, boolean cached);
-
- /**
- * Returns the average transmit rate for the specified node conenctor on
- * the given container. If the node connector does not belong to the passed
- * container a zero value is returned
- *
- * @param container
- * @param nodeConnector
- * @return tx rate [bps]
- */
- public long getTransmitRate(String container, NodeConnector nodeConnector);
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-/**
- * @file IRefreshInternalProvider.java
- *
- * @brief Topology refresh notifications requested by application
- * to be fetched from the plugin
- *
- * For example, an application that has been started late, will want to
- * be up to date with the latest topology. Hence, it requests for a
- * topology refresh from the plugin.
- */
-
-/**
- * Topology refresh requested by the application from the plugin
- *
- */
-
-public interface IRefreshInternalProvider {
-
- /**
- * @param containerName
- */
- public void requestRefresh(String containerName);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow;
-
-import java.util.List;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
-
-/**
- * The Interface provides Edge updates to the topology listeners
- */
-public interface ITopologyServiceShimListener {
- /**
- * Called to update on Edge in the topology graph
- *
- * @param topoedgeupdateList
- * List of topoedgeupdates Each topoedgeupdate includes edge, its
- * Properties ( BandWidth and/or Latency etc) and update type.
- */
- public void edgeUpdate(List<TopoEdgeUpdate> topoedgeupdateList);
-
- /**
- * Called when an Edge utilization is above the safe threshold configured on
- * the controller
- *
- * @param {@link org.opendaylight.controller.sal.core.Edge}
- */
- public void edgeOverUtilized(Edge edge);
-
- /**
- * Called when the Edge utilization is back to normal, below the safety
- * threshold level configured on the controller
- *
- * @param {@link org.opendaylight.controller.sal.core.Edge}
- */
- public void edgeUtilBackToNormal(Edge edge);
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core;
-
-import java.util.Map;
-
-import org.openflow.protocol.OFType;
-
-/**
- * This interface defines an abstraction of the Open Flow Controller that allows applications to control and manage the Open Flow switches.
- *
- */
-public interface IController {
-
- /**
- * Allows application to start receiving OF messages received from switches.
- * @param type the type of OF message that applications want to receive
- * @param listener: Object that implements the IMessageListener
- */
- public void addMessageListener(OFType type, IMessageListener listener);
-
- /**
- * Allows application to stop receiving OF message received from switches.
- * @param type The type of OF message that applications want to stop receiving
- * @param listener The object that implements the IMessageListener
- */
- public void removeMessageListener(OFType type, IMessageListener listener);
-
- /**
- * Allows application to start receiving switch state change events.
- * @param listener The object that implements the ISwitchStateListener
- */
- public void addSwitchStateListener(ISwitchStateListener listener);
-
- /**
- * Allows application to stop receiving switch state change events.
- * @param listener The object that implements the ISwitchStateListener
- */
- public void removeSwitchStateListener(ISwitchStateListener listener);
-
- /**
- * Returns a map containing all the OF switches that are currently connected to the Controller.
- * @return Map of ISwitch
- */
- public Map<Long, ISwitch> getSwitches();
-
- /**
- * Returns the ISwitch of the given switchId.
- *
- * @param switchId The switch ID
- * @return ISwitch if present, null otherwise
- */
- public ISwitch getSwitch(Long switchId);
-
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core;
-
-import org.openflow.protocol.OFMessage;
-
-/**
- * Interface to be implemented by applications that want to receive OF messages.
- *
- */
-public interface IMessageListener {
- /**
- * This method is called by the Controller when a message is received from a switch.
- * Application who is interested in receiving OF Messages needs to implement this method.
- * @param sw The ISwitch which sent the OF message
- * @param msg The OF message
- */
- public void receive(ISwitch sw, OFMessage msg);
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core;
-
-import java.util.List;
-
-import org.openflow.protocol.OFMessage;
-
-/**
- * This interface defines low level routines to read/write messages on an open
- * socket channel. If secure communication is desired, these methods also perform
- * encryption and decryption of the network data.
- */
-public interface IMessageReadWrite {
- /**
- * Sends the OF message out over the socket channel. For secure
- * communication, the data will be encrypted.
- *
- * @param msg OF message to be sent
- * @throws Exception
- */
- public void asyncSend(OFMessage msg) throws Exception;
-
- /**
- * Resumes sending the remaining messages in the outgoing buffer
- * @throws Exception
- */
- public void resumeSend() throws Exception;
-
- /**
- * Reads the incoming network data from the socket and retrieves the OF
- * messages. For secure communication, the data will be decrypted first.
- *
- * @return list of OF messages
- * @throws Exception
- */
- public List<OFMessage> readMessages() throws Exception;
-
- /**
- * Proper clean up when the switch connection is closed
- *
- * @return
- * @throws Exception
- */
- public void stop() throws Exception;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFStatisticsRequest;
-
-/**
- * This interface defines an abstraction of an Open Flow Switch.
- *
- */
-public interface ISwitch {
- /**
- * Gets a unique XID.
- *
- * @return XID
- */
- public int getNextXid();
-
- /**
- * Returns the Switch's ID.
- *
- * @return the Switch's ID
- */
- public Long getId();
-
- /**
- * Returns the Switch's table numbers supported by datapath
- *
- * @return the tables
- */
- public Byte getTables();
-
- /**
- * Returns the Switch's bitmap of supported ofp_action_type
- *
- * @return the actions
- */
- public Integer getActions();
-
- /**
- * Returns the Switch's bitmap of supported ofp_capabilities
- *
- * @return the capabilities
- */
- public Integer getCapabilities();
-
- /**
- * Returns the Switch's buffering capacity in Number of Pkts
- *
- * @return the buffers
- */
- public Integer getBuffers();
-
- /**
- * Returns the Date when the switch was connected.
- *
- * @return Date The date when the switch was connected
- */
- public Date getConnectedDate();
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. An unique XID is generated automatically and
- * inserted into the message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- public Integer asyncSend(OFMessage msg);
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. The specified XID is inserted into the message.
- *
- * @param msg
- * The OF message to be Sent
- * @param xid
- * The XID to be used in the message
- * @return The XID used
- */
- public Integer asyncSend(OFMessage msg, int xid);
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. An unique XID is generated automatically and inserted into the
- * message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- public Integer asyncFastSend(OFMessage msg);
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. The specified XID is inserted into the message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- public Integer asyncFastSend(OFMessage msg, int xid);
-
- /**
- * Sends the OF message followed by a Barrier Request with a unique XID
- * which is automatically generated, and waits for a result from the switch.
- *
- * @param msg
- * The message to be sent
- * @return An Object which has one of the followings instances/values:
- * Boolean with value true to indicate the message has been
- * successfully processed and acknowledged by the switch; Boolean
- * with value false to indicate the message has failed to be
- * processed by the switch within a period of time or OFError to
- * indicate that the message has been denied by the switch which
- * responded with OFError.
- */
- public Object syncSend(OFMessage msg);
-
- /**
- * Returns a map containing all OFPhysicalPorts of this switch.
- *
- * @return The Map of OFPhysicalPort
- */
- public Map<Short, OFPhysicalPort> getPhysicalPorts();
-
- /**
- * Returns a Set containing all port IDs of this switch.
- *
- * @return The Set of port ID
- */
- public Set<Short> getPorts();
-
- /**
- * Returns OFPhysicalPort of the specified portNumber of this switch.
- *
- * @param portNumber
- * The port ID
- * @return OFPhysicalPort for the specified PortNumber
- */
- public OFPhysicalPort getPhysicalPort(Short portNumber);
-
- /**
- * Returns the bandwidth of the specified portNumber of this switch.
- *
- * @param portNumber
- * the port ID
- * @return bandwidth
- */
- public Integer getPortBandwidth(Short portNumber);
-
- /**
- * Returns True if the port is enabled,
- *
- * @param portNumber
- * @return True if the port is enabled
- */
- public boolean isPortEnabled(short portNumber);
-
- /**
- * Returns True if the port is enabled.
- *
- * @param port
- * @return True if the port is enabled
- */
- public boolean isPortEnabled(OFPhysicalPort port);
-
- /**
- * Returns a list containing all enabled ports of this switch.
- *
- * @return: List containing all enabled ports of this switch
- */
- public List<OFPhysicalPort> getEnabledPorts();
-
- /**
- * Sends OFStatisticsRequest with a unique XID generated automatically and
- * waits for a result from the switch.
- *
- * @param req
- * the OF Statistic Request to be sent
- * @return Object has one of the following instances/values::
- * List<OFStatistics>, a list of statistics records received from
- * the switch as response from the request; OFError if the switch
- * failed handle the request or NULL if timeout has occurred while
- * waiting for the response.
- */
- public Object getStatistics(OFStatisticsRequest req);
-
- /**
- * Returns true if the switch has reached the operational state (has sent
- * FEATURE_REPLY to the controller).
- *
- * @return true if the switch is operational
- */
- public boolean isOperational();
-
- /**
- * Send Barrier message synchronously. The caller will be blocked until the
- * Barrier reply arrives.
- */
- Object syncSendBarrierMessage();
-
- /**
- * Send Barrier message asynchronously. The caller is not blocked. The
- * Barrier message will be sent in a transmit thread which will be blocked
- * until the Barrier reply arrives.
- */
- Object asyncSendBarrierMessage();
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core;
-
-/**
- * Interface to be implemented by applications that want to receive switch state event changes.
- *
- */
-public interface ISwitchStateListener {
- /**
- * This method is invoked by Controller when a switch has been connected to the Controller.
- * Application who wants to receive this event needs to implement this method.
- * @param sw The switch that has just connected.
- */
- public void switchAdded(ISwitch sw);
-
- /**
- * This method is invoked by Controller when a switch has been disconnected from the Controller.
- * Application who wants to receive this event needs to implement this method.
- * @param sw The switch that has just disconnected.
- */
- public void switchDeleted(ISwitch sw);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.opendaylight.controller.sal.connection.ConnectionConstants;
-import org.opendaylight.controller.sal.connection.IPluginInConnectionService;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.opendaylight.openflowplugin.openflow.core.ISwitchStateListener;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Controller implements IController, CommandProvider, IPluginInConnectionService {
- private static final Logger logger = LoggerFactory
- .getLogger(Controller.class);
- private ControllerIO controllerIO;
- private Thread switchEventThread;
- private ConcurrentHashMap<Long, ISwitch> switches;
- private BlockingQueue<SwitchEvent> switchEvents;
- // only 1 message listener per OFType
- private ConcurrentMap<OFType, IMessageListener> messageListeners;
- // only 1 switch state listener
- private ISwitchStateListener switchStateListener;
- private AtomicInteger switchInstanceNumber;
- private int MAXQUEUESIZE = 50000;
-
- /*
- * this thread monitors the switchEvents queue for new incoming events from
- * switch
- */
- private class EventHandler implements Runnable {
- @Override
- public void run() {
-
- while (true) {
- try {
- SwitchEvent ev = switchEvents.take();
- SwitchEvent.SwitchEventType eType = ev.getEventType();
- ISwitch sw = ev.getSwitch();
- switch (eType) {
- case SWITCH_ADD:
- Long sid = sw.getId();
- ISwitch existingSwitch = switches.get(sid);
- if (existingSwitch != null) {
- logger.info("Replacing existing {} with New {}",
- existingSwitch, sw);
- disconnectSwitch(existingSwitch);
- }
- switches.put(sid, sw);
- notifySwitchAdded(sw);
- break;
- case SWITCH_DELETE:
- disconnectSwitch(sw);
- break;
- case SWITCH_ERROR:
- disconnectSwitch(sw);
- break;
- case SWITCH_MESSAGE:
- OFMessage msg = ev.getMsg();
- if (msg != null) {
- IMessageListener listener = messageListeners
- .get(msg.getType());
- if (listener != null) {
- listener.receive(sw, msg);
- }
- }
- break;
- default:
- logger.error("Unknown switch event {}", eType.ordinal());
- }
- } catch (InterruptedException e) {
- switchEvents.clear();
- return;
- }
- }
- }
-
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- public void init() {
- logger.debug("Initializing!");
- this.switches = new ConcurrentHashMap<Long, ISwitch>();
- this.switchEvents = new LinkedBlockingQueue<SwitchEvent>(MAXQUEUESIZE);
- this.messageListeners = new ConcurrentHashMap<OFType, IMessageListener>();
- this.switchStateListener = null;
- this.switchInstanceNumber = new AtomicInteger(0);
- registerWithOSGIConsole();
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- public void start() {
- logger.debug("Starting! - omitting whole startup");
- /*
- * start a thread to handle event coming from the switch
- */
-// switchEventThread = new Thread(new EventHandler(), "SwitchEvent Thread");
-// switchEventThread.start();
-//
-// // spawn a thread to start to listen on the open flow port
-// controllerIO = new ControllerIO(this);
-// try {
-// controllerIO.start();
-// } catch (IOException ex) {
-// logger.error("Caught exception while starting:", ex);
-// }
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- public void stop() {
- for (Iterator<Entry<Long, ISwitch>> it = switches.entrySet().iterator(); it
- .hasNext();) {
- Entry<Long, ISwitch> entry = it.next();
- ((SwitchHandler) entry.getValue()).stop();
- it.remove();
- }
- switchEventThread.interrupt();
- try {
- controllerIO.shutDown();
- } catch (IOException ex) {
- logger.error("Caught exception while stopping:", ex);
- }
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- public void destroy() {
- }
-
- @Override
- public void addMessageListener(OFType type, IMessageListener listener) {
- IMessageListener currentListener = this.messageListeners.get(type);
- if (currentListener != null) {
- logger.warn("{} is already listened by {}", type,
- currentListener);
- }
- this.messageListeners.put(type, listener);
- logger.debug("{} is now listened by {}", type, listener);
- }
-
- @Override
- public void removeMessageListener(OFType type, IMessageListener listener) {
- IMessageListener currentListener = this.messageListeners.get(type);
- if ((currentListener != null) && (currentListener == listener)) {
- logger.debug("{} listener {} is Removed", type, listener);
- this.messageListeners.remove(type);
- }
- }
-
- @Override
- public void addSwitchStateListener(ISwitchStateListener listener) {
- if (this.switchStateListener != null) {
- logger.warn("Switch events are already listened by {}",
- this.switchStateListener);
- }
- this.switchStateListener = listener;
- logger.debug("Switch events are now listened by {}", listener);
- }
-
- @Override
- public void removeSwitchStateListener(ISwitchStateListener listener) {
- if ((this.switchStateListener != null)
- && (this.switchStateListener == listener)) {
- logger.debug("SwitchStateListener {} is Removed", listener);
- this.switchStateListener = null;
- }
- }
-
- public void handleNewConnection(Selector selector,
- SelectionKey serverSelectionKey) {
- ServerSocketChannel ssc = (ServerSocketChannel) serverSelectionKey
- .channel();
- SocketChannel sc = null;
- try {
- sc = ssc.accept();
- // create new switch
- int i = this.switchInstanceNumber.addAndGet(1);
- String instanceName = "SwitchHandler-" + i;
- SwitchHandler switchHandler = new SwitchHandler(this, sc, instanceName);
- switchHandler.start();
- if (sc.isConnected()) {
- logger.info("Switch:{} is connected to the Controller",
- sc.socket().getRemoteSocketAddress()
- .toString().split("/")[1]);
- }
-
- } catch (IOException e) {
- return;
- }
- }
-
- private void disconnectSwitch(ISwitch sw) {
- if (((SwitchHandler) sw).isOperational()) {
- Long sid = sw.getId();
- if (this.switches.remove(sid, sw)) {
- logger.warn("{} is Disconnected", sw);
- notifySwitchDeleted(sw);
- }
- }
- ((SwitchHandler) sw).stop();
- sw = null;
- }
-
- private void notifySwitchAdded(ISwitch sw) {
- if (switchStateListener != null) {
- switchStateListener.switchAdded(sw);
- }
- }
-
- private void notifySwitchDeleted(ISwitch sw) {
- if (switchStateListener != null) {
- switchStateListener.switchDeleted(sw);
- }
- }
-
- private synchronized void addSwitchEvent(SwitchEvent event) {
- try {
- this.switchEvents.put(event);
- } catch (InterruptedException e) {
- logger.debug("SwitchEvent caught Interrupt Exception");
- }
- }
-
- public void takeSwitchEventAdd(ISwitch sw) {
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_ADD, sw, null);
- addSwitchEvent(ev);
- }
-
- public void takeSwitchEventDelete(ISwitch sw) {
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_DELETE, sw, null);
- addSwitchEvent(ev);
- }
-
- public void takeSwitchEventError(ISwitch sw) {
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_ERROR, sw, null);
- addSwitchEvent(ev);
- }
-
- public void takeSwitchEventMsg(ISwitch sw, OFMessage msg) {
- if (messageListeners.get(msg.getType()) != null) {
- SwitchEvent ev = new SwitchEvent(
- SwitchEvent.SwitchEventType.SWITCH_MESSAGE, sw, msg);
- addSwitchEvent(ev);
- }
- }
-
- @Override
- public Map<Long, ISwitch> getSwitches() {
- return this.switches;
- }
-
- @Override
- public ISwitch getSwitch(Long switchId) {
- return this.switches.get(switchId);
- }
-
- public void _controllerShowSwitches(CommandInterpreter ci) {
- Set<Long> sids = switches.keySet();
- StringBuffer s = new StringBuffer();
- int size = sids.size();
- if (size == 0) {
- ci.print("switches: empty");
- return;
- }
- Iterator<Long> iter = sids.iterator();
- s.append("Total: " + size + " switches\n");
- while (iter.hasNext()) {
- Long sid = iter.next();
- Date date = switches.get(sid).getConnectedDate();
- String switchInstanceName = ((SwitchHandler) switches.get(sid))
- .getInstanceName();
- s.append(switchInstanceName + "/" + HexString.toHexString(sid)
- + " connected since " + date.toString() + "\n");
- }
- ci.print(s.toString());
- return;
- }
-
- public void _controllerReset(CommandInterpreter ci) {
- ci.print("...Disconnecting the communication to all switches...\n");
- stop();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ie) {
- } finally {
- ci.print("...start to accept connections from switches...\n");
- start();
- }
- }
-
- public void _controllerShowConnConfig(CommandInterpreter ci) {
- String str = System.getProperty("secureChannelEnabled");
- if ((str != null) && (str.trim().equalsIgnoreCase("true"))) {
- ci.print("The Controller and Switch should communicate through TLS connetion.\n");
-
- String keyStoreFile = System.getProperty("controllerKeyStore");
- String trustStoreFile = System.getProperty("controllerTrustStore");
- if ((keyStoreFile == null) || keyStoreFile.trim().isEmpty()) {
- ci.print("controllerKeyStore not specified in ./configuration/config.ini\n");
- } else {
- ci.print("controllerKeyStore=" + keyStoreFile + "\n");
- }
- if ((trustStoreFile == null) || trustStoreFile.trim().isEmpty()) {
- ci.print("controllerTrustStore not specified in ./configuration/config.ini\n");
- } else {
- ci.print("controllerTrustStore=" + trustStoreFile + "\n");
- }
- } else {
- ci.print("The Controller and Switch should communicate through TCP connetion.\n");
- }
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
- .getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this,
- null);
- }
-
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("---Open Flow Controller---\n");
- help.append("\t controllerShowSwitches\n");
- help.append("\t controllerReset\n");
- help.append("\t controllerShowConnConfig\n");
- return help.toString();
- }
-
- @Override
- public Status disconnect(Node node) {
- ISwitch sw = getSwitch((Long) node.getID());
- if (sw != null) disconnectSwitch(sw);
- return new Status(StatusCode.SUCCESS);
- }
-
- @Override
- public Node connect(String connectionIdentifier, Map<ConnectionConstants, String> params) {
- return null;
- }
-
- /**
- * View Change notification
- */
- public void notifyClusterViewChanged() {
- for (ISwitch sw : switches.values()) {
- notifySwitchAdded(sw);
- }
- }
-
- /**
- * Node Disconnected from the node's master controller.
- */
- @Override
- public void notifyNodeDisconnectFromMaster(Node node) {
- ISwitch sw = switches.get((Long)node.getID());
- if (sw != null) notifySwitchAdded(sw);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.Iterator;
-
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ControllerIO {
- private static final Logger logger = LoggerFactory
- .getLogger(ControllerIO.class);
- private static Short defaultOpenFlowPort = 6633;
- private Short openFlowPort;
- private SelectionKey serverSelectionKey;
- private IController listener;
- private ServerSocketChannel serverSocket;
- private Selector selector;
- private boolean running;
- private Thread controllerIOThread;
-
- public ControllerIO(IController l) {
- this.listener = l;
- this.openFlowPort = defaultOpenFlowPort;
- String portString = System.getProperty("of.listenPort");
- if (portString != null) {
- try {
- openFlowPort = Short.decode(portString).shortValue();
- } catch (NumberFormatException e) {
- logger.warn("Invalid port:{}, use default({})", portString,
- openFlowPort);
- }
- }
- }
-
- public void start() throws IOException {
- this.running = true;
- // obtain a selector
- this.selector = SelectorProvider.provider().openSelector();
- // create the listening socket
- this.serverSocket = ServerSocketChannel.open();
- this.serverSocket.configureBlocking(false);
- this.serverSocket.socket().bind(
- new java.net.InetSocketAddress(openFlowPort));
- this.serverSocket.socket().setReuseAddress(true);
- // register this socket for accepting incoming connections
- this.serverSelectionKey = this.serverSocket.register(selector,
- SelectionKey.OP_ACCEPT);
- controllerIOThread = new Thread(new Runnable() {
- @Override
- public void run() {
- while (running) {
- try {
- // wait for an incoming connection
- selector.select(0);
- Iterator<SelectionKey> selectedKeys = selector
- .selectedKeys().iterator();
- while (selectedKeys.hasNext()) {
- SelectionKey skey = selectedKeys.next();
- selectedKeys.remove();
- if (skey.isValid() && skey.isAcceptable()) {
- ((Controller) listener).handleNewConnection(
- selector, serverSelectionKey);
- }
- }
- } catch (Exception e) {
- continue;
- }
- }
- }
- }, "ControllerI/O Thread");
- controllerIOThread.start();
- logger.info("Controller is now listening on port {}", openFlowPort);
- }
-
- public void shutDown() throws IOException {
- this.running = false;
- this.selector.wakeup();
- this.serverSocket.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.util.List;
-
-import org.opendaylight.openflowplugin.openflow.core.IMessageReadWrite;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.factory.BasicFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class implements methods to read/write messages over an established
- * socket channel. The data exchange is in clear text format.
- */
-public class MessageReadWriteService implements IMessageReadWrite {
- private static final Logger logger = LoggerFactory
- .getLogger(MessageReadWriteService.class);
- private static final int bufferSize = 1024 * 1024;
-
- private Selector selector;
- private SelectionKey clientSelectionKey;
- private SocketChannel socket;
- private ByteBuffer inBuffer;
- private ByteBuffer outBuffer;
- private BasicFactory factory;
-
- public MessageReadWriteService(SocketChannel socket, Selector selector)
- throws ClosedChannelException {
- this.socket = socket;
- this.selector = selector;
- this.factory = new BasicFactory();
- this.inBuffer = ByteBuffer.allocateDirect(bufferSize);
- this.outBuffer = ByteBuffer.allocateDirect(bufferSize);
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ);
- }
-
- /**
- * Sends the OF message out over the socket channel.
- *
- * @param msg
- * OF message to be sent
- * @throws Exception
- */
- @Override
- public void asyncSend(OFMessage msg) throws IOException {
- synchronized (outBuffer) {
- int msgLen = msg.getLengthU();
- if (outBuffer.remaining() < msgLen) {
- // increase the buffer size so that it can contain this message
- ByteBuffer newBuffer = ByteBuffer.allocateDirect(outBuffer
- .capacity() + msgLen);
- outBuffer.flip();
- newBuffer.put(outBuffer);
- outBuffer = newBuffer;
- }
- }
- synchronized (outBuffer) {
- msg.writeTo(outBuffer);
-
- if (!socket.isOpen()) {
- return;
- }
-
- outBuffer.flip();
- socket.write(outBuffer);
- outBuffer.compact();
- if (outBuffer.position() > 0) {
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
- }
- logger.trace("Message sent: {}", msg);
- }
- }
-
- /**
- * Resumes sending the remaining messages in the outgoing buffer
- *
- * @throws Exception
- */
- @Override
- public void resumeSend() throws IOException {
- synchronized (outBuffer) {
- if (!socket.isOpen()) {
- return;
- }
-
- outBuffer.flip();
- socket.write(outBuffer);
- outBuffer.compact();
- if (outBuffer.position() > 0) {
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
- } else {
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
- }
- }
- }
-
- /**
- * Reads the incoming network data from the socket and retrieves the OF
- * messages.
- *
- * @return list of OF messages
- * @throws Exception
- */
- @Override
- public List<OFMessage> readMessages() throws IOException {
- if (!socket.isOpen()) {
- return null;
- }
-
- List<OFMessage> msgs = null;
- int bytesRead = -1;
- bytesRead = socket.read(inBuffer);
- if (bytesRead < 0) {
- throw new AsynchronousCloseException();
- }
-
- inBuffer.flip();
- msgs = factory.parseMessages(inBuffer);
- if (inBuffer.hasRemaining()) {
- inBuffer.compact();
- } else {
- inBuffer.clear();
- }
- return msgs;
- }
-
- @Override
- public void stop() {
- inBuffer = null;
- outBuffer = null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.openflow.protocol.OFMessage;
-
-/**
- * This class describes an OpenFlow message with priority
- */
-class PriorityMessage {
- OFMessage msg;
- int priority;
- final static AtomicLong seq = new AtomicLong();
- final long seqNum;
- boolean syncReply; // set to true if we want to be blocked until the response arrives
-
- public PriorityMessage(OFMessage msg, int priority) {
- this.msg = msg;
- this.priority = priority;
- this.seqNum = seq.getAndIncrement();
- this.syncReply = false;
- }
-
- public PriorityMessage(OFMessage msg, int priority, boolean syncReply) {
- this(msg, priority);
- this.syncReply = syncReply;
- }
-
- public OFMessage getMsg() {
- return msg;
- }
-
- public void setMsg(OFMessage msg) {
- this.msg = msg;
- }
-
- public int getPriority() {
- return priority;
- }
-
- public void setPriority(int priority) {
- this.priority = priority;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((msg == null) ? 0 : msg.hashCode());
- result = prime * result + priority;
- result = prime * result + (int) (seqNum ^ (seqNum >>> 32));
- result = prime * result + (syncReply ? 1231 : 1237);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- PriorityMessage other = (PriorityMessage) obj;
- if (msg == null) {
- if (other.msg != null)
- return false;
- } else if (!msg.equals(other.msg))
- return false;
- if (priority != other.priority)
- return false;
- if (seqNum != other.seqNum)
- return false;
- if (syncReply != other.syncReply)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "PriorityMessage [msg=" + msg + ", priority=" + priority
- + ", seqNum=" + seqNum + ", syncReply=" + syncReply + "]";
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.util.List;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-
-import org.opendaylight.openflowplugin.openflow.core.IMessageReadWrite;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.factory.BasicFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class implements methods to read/write messages over an established
- * socket channel. The data exchange is encrypted/decrypted by SSLEngine.
- */
-public class SecureMessageReadWriteService implements IMessageReadWrite {
- private static final Logger logger = LoggerFactory
- .getLogger(SecureMessageReadWriteService.class);
-
- private Selector selector;
- private SelectionKey clientSelectionKey;
- private SocketChannel socket;
- private BasicFactory factory;
-
- private SSLEngine sslEngine;
- private SSLEngineResult sslEngineResult; // results from sslEngine last operation
- private ByteBuffer myAppData; // clear text message to be sent
- private ByteBuffer myNetData; // encrypted message to be sent
- private ByteBuffer peerAppData; // clear text message received from the
- // switch
- private ByteBuffer peerNetData; // encrypted message from the switch
- private FileInputStream kfd = null, tfd = null;
-
- public SecureMessageReadWriteService(SocketChannel socket, Selector selector)
- throws Exception {
- this.socket = socket;
- this.selector = selector;
- this.factory = new BasicFactory();
-
- try {
- createSecureChannel(socket);
- createBuffers(sslEngine);
- } catch (Exception e) {
- stop();
- throw e;
- }
- }
-
- /**
- * Bring up secure channel using SSL Engine
- *
- * @param socket
- * TCP socket channel
- * @throws Exception
- */
- private void createSecureChannel(SocketChannel socket) throws Exception {
- String keyStoreFile = System.getProperty("controllerKeyStore");
- String keyStorePassword = System
- .getProperty("controllerKeyStorePassword");
- String trustStoreFile = System.getProperty("controllerTrustStore");
- String trustStorePassword = System
- .getProperty("controllerTrustStorePassword");
-
- if (keyStoreFile != null) {
- keyStoreFile = keyStoreFile.trim();
- }
- if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
- throw new FileNotFoundException(
- "controllerKeyStore not specified in ./configuration/config.ini");
- }
- if (keyStorePassword != null) {
- keyStorePassword = keyStorePassword.trim();
- }
- if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
- throw new FileNotFoundException(
- "controllerKeyStorePassword not specified in ./configuration/config.ini");
- }
- if (trustStoreFile != null) {
- trustStoreFile = trustStoreFile.trim();
- }
- if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
- throw new FileNotFoundException(
- "controllerTrustStore not specified in ./configuration/config.ini");
- }
- if (trustStorePassword != null) {
- trustStorePassword = trustStorePassword.trim();
- }
- if ((trustStorePassword == null) || trustStorePassword.isEmpty()) {
- throw new FileNotFoundException(
- "controllerTrustStorePassword not specified in ./configuration/config.ini");
- }
-
- KeyStore ks = KeyStore.getInstance("JKS");
- KeyStore ts = KeyStore.getInstance("JKS");
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
- kfd = new FileInputStream(keyStoreFile);
- tfd = new FileInputStream(trustStoreFile);
- ks.load(kfd, keyStorePassword.toCharArray());
- ts.load(tfd, trustStorePassword.toCharArray());
- kmf.init(ks, keyStorePassword.toCharArray());
- tmf.init(ts);
-
- SecureRandom random = new SecureRandom();
- random.nextInt();
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), random);
- sslEngine = sslContext.createSSLEngine();
- sslEngine.setUseClientMode(false);
- sslEngine.setNeedClientAuth(true);
-
- // Do initial handshake
- doHandshake(socket, sslEngine);
-
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ);
- }
-
- /**
- * Sends the OF message out over the socket channel. The message is
- * encrypted by SSL Engine.
- *
- * @param msg
- * OF message to be sent
- * @throws Exception
- */
- @Override
- public void asyncSend(OFMessage msg) throws Exception {
- synchronized (myAppData) {
- int msgLen = msg.getLengthU();
- if (myAppData.remaining() < msgLen) {
- // increase the buffer size so that it can contain this message
- ByteBuffer newBuffer = ByteBuffer.allocateDirect(myAppData
- .capacity() + msgLen);
- myAppData.flip();
- newBuffer.put(myAppData);
- myAppData = newBuffer;
- }
- }
- synchronized (myAppData) {
- msg.writeTo(myAppData);
- myAppData.flip();
- sslEngineResult = sslEngine.wrap(myAppData, myNetData);
- logger.trace("asyncSend sslEngine wrap: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
-
- if (!socket.isOpen()) {
- return;
- }
-
- myNetData.flip();
- socket.write(myNetData);
- if (myNetData.hasRemaining()) {
- myNetData.compact();
- } else {
- myNetData.clear();
- }
-
- if (myAppData.hasRemaining()) {
- myAppData.compact();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
- } else {
- myAppData.clear();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
- }
-
- logger.trace("Message sent: {}", msg);
- }
- }
-
- /**
- * Resumes sending the remaining messages in the outgoing buffer
- *
- * @throws Exception
- */
- @Override
- public void resumeSend() throws Exception {
- synchronized (myAppData) {
- myAppData.flip();
- sslEngineResult = sslEngine.wrap(myAppData, myNetData);
- logger.trace("resumeSend sslEngine wrap: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
-
- if (!socket.isOpen()) {
- return;
- }
-
- myNetData.flip();
- socket.write(myNetData);
- if (myNetData.hasRemaining()) {
- myNetData.compact();
- } else {
- myNetData.clear();
- }
-
- if (myAppData.hasRemaining()) {
- myAppData.compact();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
- } else {
- myAppData.clear();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
- }
- }
- }
-
- /**
- * Reads the incoming network data from the socket, decryptes them and then
- * retrieves the OF messages.
- *
- * @return list of OF messages
- * @throws Exception
- */
- @Override
- public List<OFMessage> readMessages() throws Exception {
- if (!socket.isOpen()) {
- return null;
- }
-
- List<OFMessage> msgs = null;
- int bytesRead = -1;
- int countDown = 50;
-
- bytesRead = socket.read(peerNetData);
- if (bytesRead < 0) {
- logger.debug("Message read operation failed");
- throw new AsynchronousCloseException();
- }
-
- do {
- peerNetData.flip();
- sslEngineResult = sslEngine.unwrap(peerNetData, peerAppData);
- if (peerNetData.hasRemaining()) {
- peerNetData.compact();
- } else {
- peerNetData.clear();
- }
- logger.trace("sslEngine unwrap result: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
- } while ((sslEngineResult.getStatus() == SSLEngineResult.Status.OK)
- && peerNetData.hasRemaining() && (--countDown > 0));
-
- if (countDown == 0) {
- logger.trace("countDown reaches 0. peerNetData pos {} lim {}",
- peerNetData.position(), peerNetData.limit());
- }
-
- peerAppData.flip();
- msgs = factory.parseMessages(peerAppData);
- if (peerAppData.hasRemaining()) {
- peerAppData.compact();
- } else {
- peerAppData.clear();
- }
-
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
-
- return msgs;
- }
-
- /**
- * If the result indicates that we have outstanding tasks to do, go ahead
- * and run them in this thread.
- */
- private void runDelegatedTasks(SSLEngineResult result, SSLEngine engine)
- throws Exception {
-
- if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
- Runnable runnable;
- while ((runnable = engine.getDelegatedTask()) != null) {
- logger.debug("\trunning delegated task...");
- runnable.run();
- }
- HandshakeStatus hsStatus = engine.getHandshakeStatus();
- if (hsStatus == HandshakeStatus.NEED_TASK) {
- throw new Exception("handshake shouldn't need additional tasks");
- }
- logger.debug("\tnew HandshakeStatus: {}", hsStatus);
- }
- }
-
- private void doHandshake(SocketChannel socket, SSLEngine engine)
- throws Exception {
- SSLSession session = engine.getSession();
- ByteBuffer myAppData = ByteBuffer.allocate(session
- .getApplicationBufferSize());
- ByteBuffer peerAppData = ByteBuffer.allocate(session
- .getApplicationBufferSize());
- ByteBuffer myNetData = ByteBuffer.allocate(session
- .getPacketBufferSize());
- ByteBuffer peerNetData = ByteBuffer.allocate(session
- .getPacketBufferSize());
-
- // Begin handshake
- engine.beginHandshake();
- SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
-
- // Process handshaking message
- while (hs != SSLEngineResult.HandshakeStatus.FINISHED
- && hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
- switch (hs) {
- case NEED_UNWRAP:
- // Receive handshaking data from peer
- if (socket.read(peerNetData) < 0) {
- throw new AsynchronousCloseException();
- }
-
- // Process incoming handshaking data
- peerNetData.flip();
- SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
- peerNetData.compact();
- hs = res.getHandshakeStatus();
-
- // Check status
- switch (res.getStatus()) {
- case OK:
- // Handle OK status
- break;
- }
- break;
-
- case NEED_WRAP:
- // Empty the local network packet buffer.
- myNetData.clear();
-
- // Generate handshaking data
- res = engine.wrap(myAppData, myNetData);
- hs = res.getHandshakeStatus();
-
- // Check status
- switch (res.getStatus()) {
- case OK:
- myNetData.flip();
-
- // Send the handshaking data to peer
- while (myNetData.hasRemaining()) {
- if (socket.write(myNetData) < 0) {
- throw new AsynchronousCloseException();
- }
- }
- break;
- }
- break;
-
- case NEED_TASK:
- // Handle blocking tasks
- Runnable runnable;
- while ((runnable = engine.getDelegatedTask()) != null) {
- logger.debug("\trunning delegated task...");
- runnable.run();
- }
- hs = engine.getHandshakeStatus();
- if (hs == HandshakeStatus.NEED_TASK) {
- throw new Exception(
- "handshake shouldn't need additional tasks");
- }
- logger.debug("\tnew HandshakeStatus: {}", hs);
- break;
- }
- }
- }
-
- private void createBuffers(SSLEngine engine) {
- SSLSession session = engine.getSession();
- this.myAppData = ByteBuffer
- .allocate(session.getApplicationBufferSize());
- this.peerAppData = ByteBuffer.allocate(session
- .getApplicationBufferSize());
- this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- }
-
- @Override
- public void stop() throws IOException {
- this.sslEngine = null;
- this.sslEngineResult = null;
- this.myAppData = null;
- this.myNetData = null;
- this.peerAppData = null;
- this.peerNetData = null;
-
- if (this.kfd != null) {
- this.kfd.close();
- this.kfd = null;
- }
- if (this.tfd != null) {
- this.tfd.close();
- this.tfd = null;
- }
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CountDownLatch;
-
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFStatisticsReply;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.statistics.OFStatistics;
-
-public class StatisticsCollector implements Callable<Object> {
-
- private ISwitch sw;
- private Integer xid;
- private OFStatisticsRequest request;
- private CountDownLatch latch;
- private Object result;
- private List<OFStatistics> stats;
-
- public StatisticsCollector(ISwitch sw, int xid, OFStatisticsRequest request) {
- this.sw = sw;
- this.xid = xid;
- this.request = request;
- latch = new CountDownLatch(1);
- result = new Object();
- stats = new CopyOnWriteArrayList<OFStatistics>();
- }
-
- /*
- * accumulate the stats records in result
- * Returns: true: if this is the last record
- * false: more to come
- */
- public boolean collect(OFStatisticsReply reply) {
- synchronized (result) {
- stats.addAll(reply.getStatistics());
- if ((reply.getFlags() & 0x01) == 0) {
- // all stats are collected, done
- result = stats;
- return true;
- } else {
- // still waiting for more to come
- return false;
- }
- }
- }
-
- @Override
- public Object call() throws Exception {
- sw.asyncSend(request, xid);
- // free up the request as it is no longer needed
- request = null;
- // wait until all stats replies are received or timeout
- latch.await();
- return result;
- }
-
- public Integer getXid() {
- return this.xid;
- }
-
- public void wakeup() {
- this.latch.countDown();
- }
-
- public void wakeup(OFError errorMsg) {
-
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFMessage;
-
-public class SwitchEvent {
-
- public static enum SwitchEventType {
- SWITCH_ADD, SWITCH_DELETE, SWITCH_ERROR, SWITCH_MESSAGE,
- }
-
- private SwitchEventType eventType;
- private ISwitch sw;
- private OFMessage msg;
-
- public SwitchEvent(SwitchEventType type, ISwitch sw, OFMessage msg) {
- this.eventType = type;
- this.sw = sw;
- this.msg = msg;
- }
-
- public SwitchEventType getEventType() {
- return this.eventType;
- }
-
- public ISwitch getSwitch() {
- return this.sw;
- }
-
- public OFMessage getMsg() {
- return this.msg;
- }
-
- @Override
- public String toString() {
- String s;
- switch (this.eventType) {
- case SWITCH_ADD:
- s = "SWITCH_ADD";
- break;
- case SWITCH_DELETE:
- s = "SWITCH_DELETE";
- break;
- case SWITCH_ERROR:
- s = "SWITCH_ERROR";
- break;
- case SWITCH_MESSAGE:
- s = "SWITCH_MESSAGE";
- break;
- default:
- s = "?" + this.eventType.ordinal() + "?";
- }
- return "Switch Event: " + s;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.io.IOException;
-import java.net.SocketException;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageReadWrite;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFBarrierReply;
-import org.openflow.protocol.OFBarrierRequest;
-import org.openflow.protocol.OFEchoReply;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFFeaturesReply;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFGetConfigReply;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
-import org.openflow.protocol.OFPhysicalPort.OFPortFeatures;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.openflow.protocol.OFSetConfig;
-import org.openflow.protocol.OFStatisticsReply;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SwitchHandler implements ISwitch {
- private static final Logger logger = LoggerFactory
- .getLogger(SwitchHandler.class);
- private static final int SWITCH_LIVENESS_TIMER = 5000;
- private static final int switchLivenessTimeout = getSwitchLivenessTimeout();
- private final int MESSAGE_RESPONSE_TIMER = 2000;
-
- private final String instanceName;
- private final ISwitch thisISwitch;
- private final IController core;
- private Long sid;
- private Integer buffers;
- private Integer capabilities;
- private Byte tables;
- private Integer actions;
- private Selector selector;
- private final SocketChannel socket;
- private final BasicFactory factory;
- private final AtomicInteger xid;
- private SwitchState state;
- private Timer periodicTimer;
- private final Map<Short, OFPhysicalPort> physicalPorts;
- private final Map<Short, Integer> portBandwidth;
- private final Date connectedDate;
- private Long lastMsgReceivedTimeStamp;
- private Boolean probeSent;
- private final ExecutorService executor;
- private final ConcurrentHashMap<Integer, Callable<Object>> messageWaitingDone;
- private boolean running;
- private IMessageReadWrite msgReadWriteService;
- private Thread switchHandlerThread;
- private Integer responseTimerValue;
- private PriorityBlockingQueue<PriorityMessage> transmitQ;
- private Thread transmitThread;
-
- private enum SwitchState {
- NON_OPERATIONAL(0), WAIT_FEATURES_REPLY(1), WAIT_CONFIG_REPLY(2), OPERATIONAL(
- 3);
-
- private int value;
-
- private SwitchState(int value) {
- this.value = value;
- }
-
- @SuppressWarnings("unused")
- public int value() {
- return this.value;
- }
- }
-
- public SwitchHandler(Controller core, SocketChannel sc, String name) {
- this.instanceName = name;
- this.thisISwitch = this;
- this.sid = (long) 0;
- this.buffers = (int) 0;
- this.capabilities = (int) 0;
- this.tables = (byte) 0;
- this.actions = (int) 0;
- this.core = core;
- this.socket = sc;
- this.factory = new BasicFactory();
- this.connectedDate = new Date();
- this.lastMsgReceivedTimeStamp = connectedDate.getTime();
- this.physicalPorts = new HashMap<Short, OFPhysicalPort>();
- this.portBandwidth = new HashMap<Short, Integer>();
- this.state = SwitchState.NON_OPERATIONAL;
- this.probeSent = false;
- this.xid = new AtomicInteger(this.socket.hashCode());
- this.periodicTimer = null;
- this.executor = Executors.newFixedThreadPool(4);
- this.messageWaitingDone = new ConcurrentHashMap<Integer, Callable<Object>>();
- this.responseTimerValue = MESSAGE_RESPONSE_TIMER;
- String rTimer = System.getProperty("of.messageResponseTimer");
- if (rTimer != null) {
- try {
- responseTimerValue = Integer.decode(rTimer);
- } catch (NumberFormatException e) {
- logger.warn(
- "Invalid of.messageResponseTimer: {} use default({})",
- rTimer, MESSAGE_RESPONSE_TIMER);
- }
- }
- }
-
- public void start() {
- try {
- startTransmitThread();
- setupCommChannel();
- sendFirstHello();
- startHandlerThread();
- } catch (Exception e) {
- reportError(e);
- }
- }
-
- private void startHandlerThread() {
- switchHandlerThread = new Thread(new Runnable() {
- @Override
- public void run() {
- running = true;
- while (running) {
- try {
- // wait for an incoming connection
- selector.select(0);
- Iterator<SelectionKey> selectedKeys = selector
- .selectedKeys().iterator();
- while (selectedKeys.hasNext()) {
- SelectionKey skey = selectedKeys.next();
- selectedKeys.remove();
- if (skey.isValid() && skey.isWritable()) {
- resumeSend();
- }
- if (skey.isValid() && skey.isReadable()) {
- handleMessages();
- }
- }
- } catch (Exception e) {
- reportError(e);
- }
- }
- }
- }, instanceName);
- switchHandlerThread.start();
- }
-
- public void stop() {
- running = false;
- cancelSwitchTimer();
- try {
- selector.wakeup();
- selector.close();
- } catch (Exception e) {
- }
- try {
- socket.close();
- } catch (Exception e) {
- }
- try {
- msgReadWriteService.stop();
- } catch (Exception e) {
- }
- executor.shutdown();
-
- msgReadWriteService = null;
-
- if (switchHandlerThread != null) {
- switchHandlerThread.interrupt();
- }
- if (transmitThread != null) {
- transmitThread.interrupt();
- }
- }
-
- @Override
- public int getNextXid() {
- return this.xid.incrementAndGet();
- }
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. An unique XID is generated automatically and
- * inserted into the message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- @Override
- public Integer asyncSend(OFMessage msg) {
- return asyncSend(msg, getNextXid());
- }
-
- private Object syncSend(OFMessage msg, int xid) {
- return syncMessageInternal(msg, xid, true);
- }
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. The specified XID is inserted into the message.
- *
- * @param msg
- * The OF message to be Sent
- * @param xid
- * The XID to be used in the message
- * @return The XID used
- */
- @Override
- public Integer asyncSend(OFMessage msg, int xid) {
- msg.setXid(xid);
- if (transmitQ != null) {
- transmitQ.add(new PriorityMessage(msg, 0));
- }
- return xid;
- }
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. An unique XID is generated automatically and inserted into the
- * message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- @Override
- public Integer asyncFastSend(OFMessage msg) {
- return asyncFastSend(msg, getNextXid());
- }
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. The specified XID is inserted into the message.
- *
- * @param msg
- * The OF message to be sent
- * @return The XID used
- */
- @Override
- public Integer asyncFastSend(OFMessage msg, int xid) {
- msg.setXid(xid);
- if (transmitQ != null) {
- transmitQ.add(new PriorityMessage(msg, 1));
- }
- return xid;
- }
-
- public void resumeSend() {
- try {
- if (msgReadWriteService != null) {
- msgReadWriteService.resumeSend();
- }
- } catch (Exception e) {
- reportError(e);
- }
- }
-
- /**
- * This method bypasses the transmit queue and sends the message over the
- * socket directly. If the input xid is not null, the specified xid is
- * inserted into the message. Otherwise, an unique xid is generated
- * automatically and inserted into the message.
- *
- * @param msg
- * Message to be sent
- * @param xid
- * Message xid
- */
- private void asyncSendNow(OFMessage msg, Integer xid) {
- if (xid == null) {
- xid = getNextXid();
- }
- msg.setXid(xid);
-
- asyncSendNow(msg);
- }
-
- /**
- * This method bypasses the transmit queue and sends the message over the
- * socket directly.
- *
- * @param msg
- * Message to be sent
- */
- private void asyncSendNow(OFMessage msg) {
- if (msgReadWriteService == null) {
- logger.warn(
- "asyncSendNow: {} is not sent because Message ReadWrite Service is not available.",
- msg);
- return;
- }
-
- try {
- msgReadWriteService.asyncSend(msg);
- } catch (Exception e) {
- reportError(e);
- }
- }
-
- public void handleMessages() {
- List<OFMessage> msgs = null;
-
- try {
- if (msgReadWriteService != null) {
- msgs = msgReadWriteService.readMessages();
- }
- } catch (Exception e) {
- reportError(e);
- }
-
- if (msgs == null) {
- logger.debug("{} is down", this);
- // the connection is down, inform core
- reportSwitchStateChange(false);
- return;
- }
- for (OFMessage msg : msgs) {
- logger.trace("Message received: {}", msg);
- this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
- OFType type = msg.getType();
- switch (type) {
- case HELLO:
- // send feature request
- OFMessage featureRequest = factory
- .getMessage(OFType.FEATURES_REQUEST);
- asyncFastSend(featureRequest);
- // delete all pre-existing flows
- OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL);
- OFFlowMod flowMod = (OFFlowMod) factory
- .getMessage(OFType.FLOW_MOD);
- flowMod.setMatch(match).setCommand(OFFlowMod.OFPFC_DELETE)
- .setOutPort(OFPort.OFPP_NONE)
- .setLength((short) OFFlowMod.MINIMUM_LENGTH);
- asyncFastSend(flowMod);
- this.state = SwitchState.WAIT_FEATURES_REPLY;
- startSwitchTimer();
- break;
- case ECHO_REQUEST:
- OFEchoReply echoReply = (OFEchoReply) factory
- .getMessage(OFType.ECHO_REPLY);
- // respond immediately
- asyncSendNow(echoReply, msg.getXid());
- break;
- case ECHO_REPLY:
- this.probeSent = false;
- break;
- case FEATURES_REPLY:
- processFeaturesReply((OFFeaturesReply) msg);
- break;
- case GET_CONFIG_REPLY:
- // make sure that the switch can send the whole packet to the
- // controller
- if (((OFGetConfigReply) msg).getMissSendLength() == (short) 0xffff) {
- this.state = SwitchState.OPERATIONAL;
- }
- break;
- case BARRIER_REPLY:
- processBarrierReply((OFBarrierReply) msg);
- break;
- case ERROR:
- processErrorReply((OFError) msg);
- break;
- case PORT_STATUS:
- processPortStatusMsg((OFPortStatus) msg);
- break;
- case STATS_REPLY:
- processStatsReply((OFStatisticsReply) msg);
- break;
- case PACKET_IN:
- break;
- default:
- break;
- } // end of switch
- if (isOperational()) {
- ((Controller) core).takeSwitchEventMsg(thisISwitch, msg);
- }
- } // end of for
- }
-
- private void processPortStatusMsg(OFPortStatus msg) {
- OFPhysicalPort port = msg.getDesc();
- if (msg.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
- updatePhysicalPort(port);
- } else if (msg.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
- updatePhysicalPort(port);
- } else if (msg.getReason() == (byte) OFPortReason.OFPPR_DELETE
- .ordinal()) {
- deletePhysicalPort(port);
- }
-
- }
-
- private void startSwitchTimer() {
- this.periodicTimer = new Timer();
- this.periodicTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- try {
- Long now = System.currentTimeMillis();
- if ((now - lastMsgReceivedTimeStamp) > switchLivenessTimeout) {
- if (probeSent) {
- // switch failed to respond to our probe, consider
- // it down
- logger.warn("{} is idle for too long, disconnect",
- toString());
- reportSwitchStateChange(false);
- } else {
- // send a probe to see if the switch is still alive
- logger.debug(
- "Send idle probe (Echo Request) to {}",
- this);
- probeSent = true;
- OFMessage echo = factory
- .getMessage(OFType.ECHO_REQUEST);
- asyncFastSend(echo);
- }
- } else {
- if (state == SwitchState.WAIT_FEATURES_REPLY) {
- // send another features request
- OFMessage request = factory
- .getMessage(OFType.FEATURES_REQUEST);
- asyncFastSend(request);
- } else {
- if (state == SwitchState.WAIT_CONFIG_REPLY) {
- // send another config request
- OFSetConfig config = (OFSetConfig) factory
- .getMessage(OFType.SET_CONFIG);
- config.setMissSendLength((short) 0xffff)
- .setLengthU(OFSetConfig.MINIMUM_LENGTH);
- asyncFastSend(config);
- OFMessage getConfig = factory
- .getMessage(OFType.GET_CONFIG_REQUEST);
- asyncFastSend(getConfig);
- }
- }
- }
- } catch (Exception e) {
- reportError(e);
- }
- }
- }, SWITCH_LIVENESS_TIMER, SWITCH_LIVENESS_TIMER);
- }
-
- private void cancelSwitchTimer() {
- if (this.periodicTimer != null) {
- this.periodicTimer.cancel();
- }
- }
-
- private void reportError(Exception e) {
- if (e instanceof AsynchronousCloseException
- || e instanceof InterruptedException
- || e instanceof SocketException || e instanceof IOException
- || e instanceof ClosedSelectorException) {
- if (logger.isDebugEnabled()) {
- logger.debug("Caught exception {}", e.getMessage());
- }
- } else {
- logger.warn("Caught exception ", e);
- }
- // notify core of this error event and disconnect the switch
- ((Controller) core).takeSwitchEventError(this);
- }
-
- private void reportSwitchStateChange(boolean added) {
- if (added) {
- ((Controller) core).takeSwitchEventAdd(this);
- } else {
- ((Controller) core).takeSwitchEventDelete(this);
- }
- }
-
- @Override
- public Long getId() {
- return this.sid;
- }
-
- private void processFeaturesReply(OFFeaturesReply reply) {
- if (this.state == SwitchState.WAIT_FEATURES_REPLY) {
- this.sid = reply.getDatapathId();
- this.buffers = reply.getBuffers();
- this.capabilities = reply.getCapabilities();
- this.tables = reply.getTables();
- this.actions = reply.getActions();
- // notify core of this error event
- for (OFPhysicalPort port : reply.getPorts()) {
- updatePhysicalPort(port);
- }
- // config the switch to send full data packet
- OFSetConfig config = (OFSetConfig) factory
- .getMessage(OFType.SET_CONFIG);
- config.setMissSendLength((short) 0xffff).setLengthU(
- OFSetConfig.MINIMUM_LENGTH);
- asyncFastSend(config);
- // send config request to make sure the switch can handle the set
- // config
- OFMessage getConfig = factory.getMessage(OFType.GET_CONFIG_REQUEST);
- asyncFastSend(getConfig);
- this.state = SwitchState.WAIT_CONFIG_REPLY;
- // inform core that a new switch is now operational
- reportSwitchStateChange(true);
- }
- }
-
- private void updatePhysicalPort(OFPhysicalPort port) {
- Short portNumber = port.getPortNumber();
- physicalPorts.put(portNumber, port);
- portBandwidth
- .put(portNumber,
- port.getCurrentFeatures()
- & (OFPortFeatures.OFPPF_10MB_FD.getValue()
- | OFPortFeatures.OFPPF_10MB_HD
- .getValue()
- | OFPortFeatures.OFPPF_100MB_FD
- .getValue()
- | OFPortFeatures.OFPPF_100MB_HD
- .getValue()
- | OFPortFeatures.OFPPF_1GB_FD
- .getValue()
- | OFPortFeatures.OFPPF_1GB_HD
- .getValue() | OFPortFeatures.OFPPF_10GB_FD
- .getValue()));
- }
-
- private void deletePhysicalPort(OFPhysicalPort port) {
- Short portNumber = port.getPortNumber();
- physicalPorts.remove(portNumber);
- portBandwidth.remove(portNumber);
- }
-
- @Override
- public boolean isOperational() {
- return ((this.state == SwitchState.WAIT_CONFIG_REPLY) || (this.state == SwitchState.OPERATIONAL));
- }
-
- @Override
- public String toString() {
- try {
- return ("Switch:"
- + socket.socket().getRemoteSocketAddress().toString().split("/")[1]
- + " SWID:" + (isOperational() ? HexString
- .toHexString(this.sid) : "unknown"));
- } catch (Exception e) {
- return (isOperational() ? HexString.toHexString(this.sid)
- : "unknown");
- }
-
- }
-
- @Override
- public Date getConnectedDate() {
- return this.connectedDate;
- }
-
- public String getInstanceName() {
- return instanceName;
- }
-
- @Override
- public Object getStatistics(OFStatisticsRequest req) {
- int xid = getNextXid();
- StatisticsCollector worker = new StatisticsCollector(this, xid, req);
- messageWaitingDone.put(xid, worker);
- Future<Object> submit = executor.submit(worker);
- Object result = null;
- try {
- result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
- return result;
- } catch (Exception e) {
- logger.warn("Timeout while waiting for {} replies", req.getType());
- result = null; // to indicate timeout has occurred
- return result;
- }
- }
-
- @Override
- public Object syncSend(OFMessage msg) {
- int xid = getNextXid();
- return syncSend(msg, xid);
- }
-
- /*
- * Either a BarrierReply or a OFError is received. If this is a reply for an
- * outstanding sync message, wake up associated task so that it can continue
- */
- private void processBarrierReply(OFBarrierReply msg) {
- Integer xid = msg.getXid();
- SynchronousMessage worker = (SynchronousMessage) messageWaitingDone
- .remove(xid);
- if (worker == null) {
- return;
- }
- worker.wakeup();
- }
-
- private void processErrorReply(OFError errorMsg) {
- OFMessage offendingMsg = errorMsg.getOffendingMsg();
- Integer xid;
- if (offendingMsg != null) {
- xid = offendingMsg.getXid();
- } else {
- xid = errorMsg.getXid();
- }
- /*
- * the error can be a reply to a synchronous message or to a statistic
- * request message
- */
- Callable<?> worker = messageWaitingDone.remove(xid);
- if (worker == null) {
- return;
- }
- if (worker instanceof SynchronousMessage) {
- ((SynchronousMessage) worker).wakeup(errorMsg);
- } else {
- ((StatisticsCollector) worker).wakeup(errorMsg);
- }
- }
-
- private void processStatsReply(OFStatisticsReply reply) {
- Integer xid = reply.getXid();
- StatisticsCollector worker = (StatisticsCollector) messageWaitingDone
- .get(xid);
- if (worker == null) {
- return;
- }
- if (worker.collect(reply)) {
- // if all the stats records are received (collect() returns true)
- // then we are done.
- messageWaitingDone.remove(xid);
- worker.wakeup();
- }
- }
-
- @Override
- public Map<Short, OFPhysicalPort> getPhysicalPorts() {
- return this.physicalPorts;
- }
-
- @Override
- public OFPhysicalPort getPhysicalPort(Short portNumber) {
- return this.physicalPorts.get(portNumber);
- }
-
- @Override
- public Integer getPortBandwidth(Short portNumber) {
- return this.portBandwidth.get(portNumber);
- }
-
- @Override
- public Set<Short> getPorts() {
- return this.physicalPorts.keySet();
- }
-
- @Override
- public Byte getTables() {
- return this.tables;
- }
-
- @Override
- public Integer getActions() {
- return this.actions;
- }
-
- @Override
- public Integer getCapabilities() {
- return this.capabilities;
- }
-
- @Override
- public Integer getBuffers() {
- return this.buffers;
- }
-
- @Override
- public boolean isPortEnabled(short portNumber) {
- return isPortEnabled(physicalPorts.get(portNumber));
- }
-
- @Override
- public boolean isPortEnabled(OFPhysicalPort port) {
- if (port == null) {
- return false;
- }
- int portConfig = port.getConfig();
- int portState = port.getState();
- if ((portConfig & OFPortConfig.OFPPC_PORT_DOWN.getValue()) > 0) {
- return false;
- }
- if ((portState & OFPortState.OFPPS_LINK_DOWN.getValue()) > 0) {
- return false;
- }
- if ((portState & OFPortState.OFPPS_STP_MASK.getValue()) == OFPortState.OFPPS_STP_BLOCK
- .getValue()) {
- return false;
- }
- return true;
- }
-
- @Override
- public List<OFPhysicalPort> getEnabledPorts() {
- List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
- synchronized (this.physicalPorts) {
- for (OFPhysicalPort port : physicalPorts.values()) {
- if (isPortEnabled(port)) {
- result.add(port);
- }
- }
- }
- return result;
- }
-
- /*
- * Transmit thread polls the message out of the priority queue and invokes
- * messaging service to transmit it over the socket channel
- */
- class PriorityMessageTransmit implements Runnable {
- @Override
- public void run() {
- running = true;
- while (running) {
- try {
- PriorityMessage pmsg = transmitQ.take();
- msgReadWriteService.asyncSend(pmsg.msg);
- /*
- * If syncReply is set to true, wait for the response back.
- */
- if (pmsg.syncReply) {
- syncMessageInternal(pmsg.msg, pmsg.msg.getXid(), false);
- }
- } catch (InterruptedException ie) {
- reportError(new InterruptedException(
- "PriorityMessageTransmit thread interrupted"));
- } catch (Exception e) {
- reportError(e);
- }
- }
- transmitQ = null;
- }
- }
-
- /*
- * Setup and start the transmit thread
- */
- private void startTransmitThread() {
- this.transmitQ = new PriorityBlockingQueue<PriorityMessage>(11,
- new Comparator<PriorityMessage>() {
- @Override
- public int compare(PriorityMessage p1, PriorityMessage p2) {
- if (p2.priority != p1.priority) {
- return p2.priority - p1.priority;
- } else {
- return (p2.seqNum < p1.seqNum) ? 1 : -1;
- }
- }
- });
- this.transmitThread = new Thread(new PriorityMessageTransmit());
- this.transmitThread.start();
- }
-
- /*
- * Setup communication services
- */
- private void setupCommChannel() throws Exception {
- this.selector = SelectorProvider.provider().openSelector();
- this.socket.configureBlocking(false);
- this.socket.socket().setTcpNoDelay(true);
- this.msgReadWriteService = getMessageReadWriteService();
- }
-
- private void sendFirstHello() {
- try {
- OFMessage msg = factory.getMessage(OFType.HELLO);
- asyncFastSend(msg);
- } catch (Exception e) {
- reportError(e);
- }
- }
-
- private IMessageReadWrite getMessageReadWriteService() throws Exception {
- String str = System.getProperty("secureChannelEnabled");
- return ((str != null) && (str.trim().equalsIgnoreCase("true"))) ? new SecureMessageReadWriteService(
- socket, selector) : new MessageReadWriteService(socket,
- selector);
- }
-
- /**
- * Send Barrier message synchronously. The caller will be blocked until the
- * Barrier reply is received.
- */
- @Override
- public Object syncSendBarrierMessage() {
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- return syncSend(barrierMsg);
- }
-
- /**
- * Send Barrier message asynchronously. The caller is not blocked. The
- * Barrier message will be sent in a transmit thread which will be blocked
- * until the Barrier reply is received.
- */
- @Override
- public Object asyncSendBarrierMessage() {
- if (transmitQ == null) {
- return Boolean.FALSE;
- }
-
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- int xid = getNextXid();
-
- barrierMsg.setXid(xid);
- transmitQ.add(new PriorityMessage(barrierMsg, 0, true));
-
- return Boolean.TRUE;
- }
-
- /**
- * This method returns the switch liveness timeout value. If controller did
- * not receive any message from the switch for such a long period,
- * controller will tear down the connection to the switch.
- *
- * @return The timeout value
- */
- private static int getSwitchLivenessTimeout() {
- String timeout = System.getProperty("of.switchLivenessTimeout");
- int rv = 60500;
-
- try {
- if (timeout != null) {
- rv = Integer.parseInt(timeout);
- }
- } catch (Exception e) {
- }
-
- return rv;
- }
-
- /**
- * This method performs synchronous operations for a given message. If
- * syncRequest is set to true, the message will be sent out followed by a
- * Barrier request message. Then it's blocked until the Barrier rely arrives
- * or timeout. If syncRequest is false, it simply skips the message send and
- * just waits for the response back.
- *
- * @param msg
- * Message to be sent
- * @param xid
- * Message XID
- * @param request
- * If set to true, the message the message will be sent out
- * followed by a Barrier request message. If set to false, it
- * simply skips the sending and just waits for the Barrier reply.
- * @return the result
- */
- private Object syncMessageInternal(OFMessage msg, int xid, boolean syncRequest) {
- SynchronousMessage worker = new SynchronousMessage(this, xid, msg, syncRequest);
- messageWaitingDone.put(xid, worker);
- Object result = null;
- Boolean status = false;
- Future<Object> submit = executor.submit(worker);
- try {
- result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
- messageWaitingDone.remove(xid);
- if (result == null) {
- // if result is null, then it means the switch can handle this
- // message successfully
- // convert the result into a Boolean with value true
- status = true;
- // logger.debug("Successfully send " +
- // msg.getType().toString());
- result = status;
- } else {
- // if result is not null, this means the switch can't handle
- // this message
- // the result if OFError already
- if (logger.isDebugEnabled()) {
- logger.debug("Send {} failed --> {}", msg.getType(),
- (result));
- }
- }
- return result;
- } catch (Exception e) {
- logger.warn("Timeout while waiting for {} reply", msg.getType()
- .toString());
- // convert the result into a Boolean with value false
- status = false;
- result = status;
- return result;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.core.internal;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFBarrierRequest;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFMessage;
-
-/**
- * This class implements synchronous operations on message send to a switch. If
- * syncRequest is set to true, it sends the requested message to the switch
- * followed by a Barrier request message. It returns the result once it gets the
- * reply from the switch or after a timeout. If the protocol does not dictate
- * the switch to reply the processing status for a particular message, the
- * Barrier request forces the switch to reply saying whether or not the message
- * processing was successful for messages sent to the switch up to this point.
- * If syncRequest is false, it simply skips the message send and just waits for
- * the response back.
- */
-public class SynchronousMessage implements Callable<Object> {
- private ISwitch sw;
- private Integer xid;
- private OFMessage syncMsg;
- protected CountDownLatch latch;
- private Object result;
- private boolean syncRequest;
-
- public SynchronousMessage(ISwitch sw, Integer xid, OFMessage msg,
- boolean syncRequest) {
- this.sw = sw;
- this.xid = xid;
- syncMsg = msg;
- latch = new CountDownLatch(1);
- result = null;
- this.syncRequest = syncRequest;
- }
-
- @Override
- public Object call() throws Exception {
- /*
- * Send out message only if syncRequest is set to true. Otherwise, just
- * wait for the Barrier response back.
- */
- if (syncRequest) {
- sw.asyncSend(syncMsg, xid);
- if (!(syncMsg instanceof OFBarrierRequest)) {
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- sw.asyncSend(barrierMsg, xid);
- }
- }
- latch.await();
- return result;
- }
-
- public Integer getXid() {
- return this.xid;
- }
-
- public void wakeup() {
- this.latch.countDown();
- }
-
- public void wakeup(OFError e) {
- result = e;
- wakeup();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
-import org.opendaylight.controller.sal.connection.IPluginInConnectionService;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService;
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
-import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
-import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService;
-import org.opendaylight.controller.sal.reader.IPluginInReadService;
-import org.opendaylight.controller.sal.reader.IPluginOutReadService;
-import org.opendaylight.controller.sal.topology.IPluginInTopologyService;
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
-import org.opendaylight.openflowplugin.openflow.IDataPacketListen;
-import org.opendaylight.openflowplugin.openflow.IDataPacketMux;
-import org.opendaylight.openflowplugin.openflow.IDiscoveryListener;
-import org.opendaylight.openflowplugin.openflow.IFlowProgrammerNotifier;
-import org.opendaylight.openflowplugin.openflow.IInventoryProvider;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimInternalListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsManager;
-import org.opendaylight.openflowplugin.openflow.IReadFilterInternalListener;
-import org.opendaylight.openflowplugin.openflow.IReadServiceFilter;
-import org.opendaylight.openflowplugin.openflow.IRefreshInternalProvider;
-import org.opendaylight.openflowplugin.openflow.ITopologyServiceShimListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.internal.Controller;
-import org.opendaylight.openflowplugin.openflow.md.core.MDController;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.SalRegistrationManager;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Openflow protocol plugin Activator
- */
-public class Activator extends ComponentActivatorAbstractBase {
- protected static final Logger logger = LoggerFactory.getLogger(Activator.class);
-
- private OpenflowPluginProvider pluginProvider = new OpenflowPluginProvider();
-
- /**
- * Function called when the activator starts just after some initializations
- * are done by the ComponentActivatorAbstractBase.
- *
- */
- public void init() {
- }
-
- /**
- * Function called when the activator stops just before the cleanup done by
- * ComponentActivatorAbstractBase
- *
- */
- public void destroy() {
- }
-
- @Override
- public void start(BundleContext arg0) {
- super.start(arg0);
- pluginProvider.setContext(arg0);
- }
-
- /**
- * Function that is used to communicate to dependency manager the list of
- * known implementations for services inside a container
- *
- *
- * @return An array containing all the CLASS objects that will be
- * instantiated in order to get an fully working implementation
- * Object
- */
- public Object[] getImplementations() {
- Object[] res = { TopologyServices.class, DataPacketServices.class, InventoryService.class, ReadService.class,
- FlowProgrammerNotifier.class };
- return res;
- }
-
- /**
- * Function that is called when configuration of the dependencies is
- * required.
- *
- * @param c
- * dependency manager Component object, used for configuring the
- * dependencies exported and imported
- * @param imp
- * Implementation class that is being configured, needed as long
- * as the same routine can configure multiple implementations
- * @param containerName
- * The containerName being configured, this allow also optional
- * per-container different behavior if needed, usually should not
- * be the case though.
- */
- public void configureInstance(Component c, Object imp, String containerName) {
- if (imp.equals(TopologyServices.class)) {
- // export the service to be used by SAL
- c.setInterface(
- new String[] { IPluginInTopologyService.class.getName(),
- ITopologyServiceShimListener.class.getName() }, null);
- // Hook the services coming in from SAL, as optional in
- // case SAL is not yet there, could happen
- c.add(createContainerServiceDependency(containerName).setService(IPluginOutTopologyService.class)
- .setCallbacks("setPluginOutTopologyService", "unsetPluginOutTopologyService").setRequired(false));
- c.add(createServiceDependency().setService(IRefreshInternalProvider.class)
- .setCallbacks("setRefreshInternalProvider", "unsetRefreshInternalProvider").setRequired(false));
- }
-
- if (imp.equals(InventoryService.class)) {
- // export the service
- c.setInterface(new String[] { IPluginInInventoryService.class.getName(),
- IInventoryShimInternalListener.class.getName(), IInventoryProvider.class.getName() }, null);
-
- // Now lets add a service dependency to make sure the
- // provider of service exists
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createContainerServiceDependency(containerName).setService(IPluginOutInventoryService.class)
- .setCallbacks("setPluginOutInventoryServices", "unsetPluginOutInventoryServices")
- .setRequired(false));
- }
-
- if (imp.equals(DataPacketServices.class)) {
- // export the service to be used by SAL
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- // Set the protocolPluginType property which will be used
- // by SAL
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
- c.setInterface(IPluginInDataPacketService.class.getName(), props);
- // Hook the services coming in from SAL, as optional in
- // case SAL is not yet there, could happen
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- // This is required for the transmission to happen properly
- c.add(createServiceDependency().setService(IDataPacketMux.class)
- .setCallbacks("setIDataPacketMux", "unsetIDataPacketMux").setRequired(true));
- c.add(createContainerServiceDependency(containerName).setService(IPluginOutDataPacketService.class)
- .setCallbacks("setPluginOutDataPacketService", "unsetPluginOutDataPacketService")
- .setRequired(false));
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- }
-
- if (imp.equals(ReadService.class)) {
- // export the service to be used by SAL
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- // Set the protocolPluginType property which will be used
- // by SAL
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
- c.setInterface(
- new String[] { IReadFilterInternalListener.class.getName(), IPluginInReadService.class.getName() },
- props);
-
- c.add(createServiceDependency().setService(IReadServiceFilter.class)
- .setCallbacks("setService", "unsetService").setRequired(true));
-
- c.add(createContainerServiceDependency(containerName).setService(IPluginOutReadService.class)
- .setCallbacks("setPluginOutReadServices", "unsetPluginOutReadServices").setRequired(false));
-
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- }
-
- if (imp.equals(FlowProgrammerNotifier.class)) {
- // export the service to be used by SAL
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- // Set the protocolPluginType property which will be used
- // by SAL
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
- c.setInterface(IFlowProgrammerNotifier.class.getName(), props);
-
- c.add(createContainerServiceDependency(containerName).setService(IPluginOutFlowProgrammerService.class)
- .setCallbacks("setPluginOutFlowProgrammerService", "unsetPluginOutFlowProgrammerService")
- .setRequired(true));
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- }
- }
-
- /**
- * Function that is used to communicate to dependency manager the list of
- * known implementations for services that are container independent.
- *
- *
- * @return An array containing all the CLASS objects that will be
- * instantiated in order to get an fully working implementation
- * Object
- */
- public Object[] getGlobalImplementations() {
- Object[] res = { Controller.class, OFStatisticsManager.class, FlowProgrammerService.class,
- ReadServiceFilter.class, DiscoveryService.class, DataPacketMuxDemux.class, InventoryService.class,
- InventoryServiceShim.class, TopologyServiceShim.class, MDController.class, pluginProvider };
- return res;
- }
-
- /**
- * Function that is called when configuration of the dependencies is
- * required.
- *
- * @param c
- * dependency manager Component object, used for configuring the
- * dependencies exported and imported
- * @param imp
- * Implementation class that is being configured, needed as long
- * as the same routine can configure multiple implementations
- */
- public void configureGlobalInstance(Component c, Object imp) {
-
- if (imp.equals(Controller.class)) {
- logger.debug("Activator configureGlobalInstance( ) is called");
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put("name", "Controller");
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
- c.setInterface(new String[] { IController.class.getName(), IPluginInConnectionService.class.getName() },
- props);
- } else
-
- if (imp.equals(FlowProgrammerService.class)) {
- // export the service to be used by SAL
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- // Set the protocolPluginType property which will be used
- // by SAL
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW);
- c.setInterface(
- new String[] { IPluginInFlowProgrammerService.class.getName(), IMessageListener.class.getName(),
- IContainerListener.class.getName(), IInventoryShimExternalListener.class.getName() }, props);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
-
- c.add(createServiceDependency().setService(IFlowProgrammerNotifier.class)
- .setCallbacks("setFlowProgrammerNotifier", "unsetsetFlowProgrammerNotifier").setRequired(false));
-
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- } else
-
- if (imp.equals(ReadServiceFilter.class)) {
-
- c.setInterface(new String[] { IReadServiceFilter.class.getName(), IContainerListener.class.getName(),
- IOFStatisticsListener.class.getName() }, null);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createServiceDependency().setService(IOFStatisticsManager.class)
- .setCallbacks("setService", "unsetService").setRequired(true));
- c.add(createServiceDependency().setService(IReadFilterInternalListener.class)
- .setCallbacks("setReadFilterInternalListener", "unsetReadFilterInternalListener")
- .setRequired(false));
- } else
-
- if (imp.equals(OFStatisticsManager.class)) {
-
- c.setInterface(
- new String[] { IOFStatisticsManager.class.getName(), IInventoryShimExternalListener.class.getName() },
- null);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createServiceDependency().setService(IOFStatisticsListener.class)
- .setCallbacks("setStatisticsListener", "unsetStatisticsListener").setRequired(false));
- } else
-
- if (imp.equals(DiscoveryService.class)) {
- // export the service
- c.setInterface(
- new String[] { IInventoryShimExternalListener.class.getName(), IDataPacketListen.class.getName(),
- IContainerListener.class.getName() }, null);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createContainerServiceDependency(GlobalConstants.DEFAULT.toString())
- .setService(IInventoryProvider.class)
- .setCallbacks("setInventoryProvider", "unsetInventoryProvider").setRequired(true));
- c.add(createServiceDependency().setService(IDataPacketMux.class)
- .setCallbacks("setIDataPacketMux", "unsetIDataPacketMux").setRequired(true));
- c.add(createServiceDependency().setService(IDiscoveryListener.class)
- .setCallbacks("setDiscoveryListener", "unsetDiscoveryListener").setRequired(true));
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- } else
-
- // DataPacket mux/demux services, which is teh actual engine
- // doing the packet switching
- if (imp.equals(DataPacketMuxDemux.class)) {
- c.setInterface(new String[] { IDataPacketMux.class.getName(), IContainerListener.class.getName(),
- IInventoryShimExternalListener.class.getName() }, null);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createServiceDependency().setService(IPluginOutDataPacketService.class)
- .setCallbacks("setPluginOutDataPacketService", "unsetPluginOutDataPacketService")
- .setRequired(false));
- // See if there is any local packet dispatcher
- c.add(createServiceDependency().setService(IDataPacketListen.class)
- .setCallbacks("setIDataPacketListen", "unsetIDataPacketListen").setRequired(false));
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- } else
-
- if (imp.equals(InventoryService.class)) {
- // export the service
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put("scope", "Global");
-
- c.setInterface(new String[] { IPluginInInventoryService.class.getName(),
- IInventoryShimInternalListener.class.getName(), IInventoryProvider.class.getName() }, props);
-
- // Now lets add a service dependency to make sure the
- // provider of service exists
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createServiceDependency().setService(IPluginOutInventoryService.class, "(scope=Global)")
- .setCallbacks("setPluginOutInventoryServices", "unsetPluginOutInventoryServices")
- .setRequired(false));
- } else
-
- if (imp.equals(InventoryServiceShim.class)) {
- c.setInterface(new String[] { IContainerListener.class.getName(), IOFStatisticsListener.class.getName() },
- null);
-
- c.add(createServiceDependency().setService(IController.class, "(name=Controller)")
- .setCallbacks("setController", "unsetController").setRequired(true));
- c.add(createServiceDependency().setService(IInventoryShimInternalListener.class, "(!(scope=Global))")
- .setCallbacks("setInventoryShimInternalListener", "unsetInventoryShimInternalListener")
- .setRequired(true));
- c.add(createServiceDependency().setService(IInventoryShimInternalListener.class, "(scope=Global)")
- .setCallbacks("setInventoryShimGlobalInternalListener", "unsetInventoryShimGlobalInternalListener")
- .setRequired(true));
- c.add(createServiceDependency().setService(IInventoryShimExternalListener.class)
- .setCallbacks("setInventoryShimExternalListener", "unsetInventoryShimExternalListener")
- .setRequired(false));
- c.add(createServiceDependency().setService(IPluginOutConnectionService.class)
- .setCallbacks("setIPluginOutConnectionService", "unsetIPluginOutConnectionService")
- .setRequired(false));
- } else
-
- if (imp.equals(TopologyServiceShim.class)) {
- c.setInterface(new String[] { IDiscoveryListener.class.getName(), IContainerListener.class.getName(),
- IRefreshInternalProvider.class.getName(), IInventoryShimExternalListener.class.getName() }, null);
- c.add(createServiceDependency().setService(ITopologyServiceShimListener.class)
- .setCallbacks("setTopologyServiceShimListener", "unsetTopologyServiceShimListener")
- .setRequired(true));
- c.add(createServiceDependency().setService(IOFStatisticsManager.class)
- .setCallbacks("setStatisticsManager", "unsetStatisticsManager").setRequired(false));
- } else
-
- if (imp == pluginProvider) {
- // c.setInterface(new String[] { IDiscoveryListener.class.getName(),
- // IContainerListener.class.getName(),
- // IRefreshInternalProvider.class.getName(),
- // IInventoryShimExternalListener.class.getName() }, null);
- c.add(createServiceDependency().setService(BindingAwareBroker.class)
- .setCallbacks("setBroker", "unsetBroker").setRequired(true));
- c.add(createServiceDependency().setService(SwitchConnectionProvider.class)
- .setCallbacks("setSwitchConnectionProvider", "unsetSwitchConnectionProvider").setRequired(true));
- logger.debug("configuring Binding Aware Provider");
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService;
-import org.opendaylight.controller.sal.packet.PacketResult;
-import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.openflowplugin.openflow.IDataPacketListen;
-import org.opendaylight.openflowplugin.openflow.IDataPacketMux;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-
-public class DataPacketMuxDemux implements IContainerListener,
- IMessageListener, IDataPacketMux, IInventoryShimExternalListener {
- protected static final Logger logger = LoggerFactory
- .getLogger(DataPacketMuxDemux.class);
- private IController controller = null;
- private ConcurrentMap<Long, ISwitch> swID2ISwitch = new ConcurrentHashMap<Long, ISwitch>();
- // Gives a map between a Container and all the DataPacket listeners on SAL
- private ConcurrentMap<String, IPluginOutDataPacketService> pluginOutDataPacketServices = new ConcurrentHashMap<String, IPluginOutDataPacketService>();
- // Gives a map between a NodeConnector and the containers to which it
- // belongs
- private ConcurrentMap<NodeConnector, List<String>> nc2Container = new ConcurrentHashMap<NodeConnector, List<String>>();
- // Gives a map between a Container and the FlowSpecs on it
- private ConcurrentMap<String, List<ContainerFlow>> container2FlowSpecs = new ConcurrentHashMap<String, List<ContainerFlow>>();
- // Track local data packet listener
- private List<IDataPacketListen> iDataPacketListen = new CopyOnWriteArrayList<IDataPacketListen>();
- private IPluginOutConnectionService connectionOutService;
-
- void setIDataPacketListen(IDataPacketListen s) {
- if (this.iDataPacketListen != null) {
- if (!this.iDataPacketListen.contains(s)) {
- logger.debug("Added new IDataPacketListen");
- this.iDataPacketListen.add(s);
- }
- }
- }
-
- void unsetIDataPacketListen(IDataPacketListen s) {
- if (this.iDataPacketListen != null) {
- if (this.iDataPacketListen.contains(s)) {
- logger.debug("Removed IDataPacketListen");
- this.iDataPacketListen.remove(s);
- }
- }
- }
-
- void setPluginOutDataPacketService(Map<String, Object> props,
- IPluginOutDataPacketService s) {
- if (props == null) {
- logger.error("Didn't receive the service properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("containerName not supplied");
- return;
- }
- if (this.pluginOutDataPacketServices != null) {
- // It's expected only one SAL per container as long as the
- // replication is done in the SAL implementation toward
- // the different APPS
- this.pluginOutDataPacketServices.put(containerName, s);
- logger.debug("New outService for container: {}", containerName);
- }
- }
-
- void unsetPluginOutDataPacketService(Map<String, Object> props,
- IPluginOutDataPacketService s) {
- if (props == null) {
- logger.error("Didn't receive the service properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("containerName not supplied");
- return;
- }
- if (this.pluginOutDataPacketServices != null) {
- this.pluginOutDataPacketServices.remove(containerName);
- logger.debug("Removed outService for container: {}", containerName);
- }
- }
-
- void setController(IController s) {
- logger.debug("Controller provider set in DATAPACKET SERVICES");
- this.controller = s;
- }
-
- void unsetController(IController s) {
- if (this.controller == s) {
- logger.debug("Controller provider UNset in DATAPACKET SERVICES");
- this.controller = null;
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- this.controller.addMessageListener(OFType.PACKET_IN, this);
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- this.controller.removeMessageListener(OFType.PACKET_IN, this);
-
- // Clear state that may need to be reused on component restart
- this.pluginOutDataPacketServices.clear();
- this.nc2Container.clear();
- this.container2FlowSpecs.clear();
- this.controller = null;
- this.swID2ISwitch.clear();
- }
-
- @Override
- public void receive(ISwitch sw, OFMessage msg) {
- if (sw == null || msg == null
- || this.pluginOutDataPacketServices == null) {
- // Something fishy, we cannot do anything
- logger.debug(
- "sw: {} and/or msg: {} and/or pluginOutDataPacketServices: {} is null!",
- new Object[] { sw, msg, this.pluginOutDataPacketServices });
- return;
- }
-
- Long ofSwitchID = Long.valueOf(sw.getId());
- try {
- Node n = new Node(Node.NodeIDType.OPENFLOW, ofSwitchID);
- if (!connectionOutService.isLocal(n)) {
- logger.debug("Connection service refused DataPacketMuxDemux receive {} {}", sw, msg);
- return;
- }
- }
- catch (Exception e) {
- return;
- }
-
- if (msg instanceof OFPacketIn) {
- OFPacketIn ofPacket = (OFPacketIn) msg;
- Short ofPortID = Short.valueOf(ofPacket.getInPort());
-
- try {
- Node n = new Node(Node.NodeIDType.OPENFLOW, ofSwitchID);
- NodeConnector p = PortConverter.toNodeConnector(ofPortID, n);
- RawPacket dataPacket = new RawPacket(ofPacket.getPacketData());
- dataPacket.setIncomingNodeConnector(p);
-
- // Try to dispatch the packet locally, in here we will
- // pass the parsed packet simply because once the
- // packet infra is settled all the packets will passed
- // around as parsed and read-only
- for (int i = 0; i < this.iDataPacketListen.size(); i++) {
- IDataPacketListen s = this.iDataPacketListen.get(i);
- if (s.receiveDataPacket(dataPacket).equals(
- PacketResult.CONSUME)) {
- logger.trace("Consumed locally data packet");
- return;
- }
- }
-
- // Now dispatch the packet toward SAL at least for
- // default container, we need to revisit this in a general
- // slicing architecture refresh
- IPluginOutDataPacketService defaultOutService = this.pluginOutDataPacketServices
- .get(GlobalConstants.DEFAULT.toString());
- if (defaultOutService != null) {
- defaultOutService.receiveDataPacket(dataPacket);
- if (logger.isTraceEnabled()) {
- logger.trace(
- "Dispatched to apps a frame of size: {} on " +
- "container: {}: {}", new Object[] {
- ofPacket.getPacketData().length,
- GlobalConstants.DEFAULT.toString(),
- HexEncode.bytesToHexString(dataPacket
- .getPacketData()) });
- }
- }
- // Now check the mapping between nodeConnector and
- // Container and later on optimally filter based on
- // flowSpec
- List<String> containersRX = this.nc2Container.get(p);
- if (containersRX != null) {
- for (int i = 0; i < containersRX.size(); i++) {
- String container = containersRX.get(i);
- IPluginOutDataPacketService s = this.pluginOutDataPacketServices
- .get(container);
- if (s != null) {
- // TODO add filtering on a per-flowSpec base
- s.receiveDataPacket(dataPacket);
- if (logger.isTraceEnabled()) {
- logger.trace(
- "Dispatched to apps a frame of size: {}" +
- " on container: {}: {}", new Object[] {
- ofPacket.getPacketData().length,
- container,
- HexEncode.bytesToHexString(dataPacket
- .getPacketData()) });
- }
- }
- }
- }
-
- // This is supposed to be the catch all for all the
- // DataPacket hence we will assume it has been handled
- return;
- } catch (ConstructionException cex) {
- }
-
- // If we reach this point something went wrong.
- return;
- } else {
- // We don't care about non-data packets
- return;
- }
- }
-
- @Override
- public void transmitDataPacket(RawPacket outPkt) {
- // Sanity check area
- if (outPkt == null) {
- logger.debug("outPkt is null!");
- return;
- }
-
- NodeConnector outPort = outPkt.getOutgoingNodeConnector();
- if (outPort == null) {
- logger.debug("outPort is null! outPkt: {}", outPkt);
- return;
- }
-
- if (!connectionOutService.isLocal(outPort.getNode())) {
- logger.debug("data packets will not be sent to {} in a non-master controller", outPort.toString());
- return;
- }
-
-
- if (!outPort.getType().equals(
- NodeConnector.NodeConnectorIDType.OPENFLOW)) {
- // The output Port is not of type OpenFlow
- logger.debug("outPort is not OF Type! outPort: {}", outPort);
- return;
- }
-
- Short port = (Short) outPort.getID();
- Long swID = (Long) outPort.getNode().getID();
- ISwitch sw = this.swID2ISwitch.get(swID);
-
- if (sw == null) {
- // If we cannot get the controller descriptor we cannot even
- // send out the frame
- logger.debug("swID: {} - sw is null!", swID);
- return;
- }
-
- byte[] data = outPkt.getPacketData();
- // build action
- OFActionOutput action = new OFActionOutput().setPort(port);
- // build packet out
- OFPacketOut po = new OFPacketOut()
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setInPort(OFPort.OFPP_NONE)
- .setActions(Collections.singletonList((OFAction) action))
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
- po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength()
- + data.length);
- po.setPacketData(data);
-
- // send PACKET_OUT at high priority
- sw.asyncFastSend(po);
- logger.trace("Transmitted a frame of size: {}", data.length);
- }
-
- public void addNode(Node node, Set<Property> props) {
- if (node == null) {
- logger.debug("node is null!");
- return;
- }
-
- long sid = (Long) node.getID();
- ISwitch sw = controller.getSwitches().get(sid);
- if (sw == null) {
- logger.debug("sid: {} - sw is null!", sid);
- return;
- }
- this.swID2ISwitch.put(sw.getId(), sw);
- }
-
- public void removeNode(Node node) {
- if (node == null) {
- logger.debug("node is null!");
- return;
- }
-
- long sid = (Long) node.getID();
- ISwitch sw = controller.getSwitches().get(sid);
- if (sw == null) {
- logger.debug("sid: {} - sw is null!", sid);
- return;
- }
- this.swID2ISwitch.remove(sw.getId());
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag,
- short newTag, UpdateType t) {
- // Do nothing
- }
-
- @Override
- public void containerFlowUpdated(String containerName,
- ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t) {
- if (this.container2FlowSpecs == null) {
- logger.error("container2FlowSpecs is NULL");
- return;
- }
- List<ContainerFlow> fSpecs = this.container2FlowSpecs
- .get(containerName);
- if (fSpecs == null) {
- fSpecs = new CopyOnWriteArrayList<ContainerFlow>();
- }
- switch (t) {
- case ADDED:
- if (!fSpecs.contains(previousFlow)) {
- fSpecs.add(previousFlow);
- }
- break;
- case REMOVED:
- if (fSpecs.contains(previousFlow)) {
- fSpecs.remove(previousFlow);
- }
- break;
- case CHANGED:
- break;
- }
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p,
- UpdateType t) {
- if (this.nc2Container == null) {
- logger.error("nc2Container is NULL");
- return;
- }
- List<String> containers = this.nc2Container.get(p);
- if (containers == null) {
- containers = new CopyOnWriteArrayList<String>();
- }
- boolean updateMap = false;
- switch (t) {
- case ADDED:
- if (!containers.contains(containerName)) {
- containers.add(containerName);
- updateMap = true;
- }
- break;
- case REMOVED:
- if (containers.contains(containerName)) {
- containers.remove(containerName);
- updateMap = true;
- }
- break;
- case CHANGED:
- break;
- }
- if (updateMap) {
- if (containers.isEmpty()) {
- // Do cleanup to reduce memory footprint if no
- // elements to be tracked
- this.nc2Container.remove(p);
- } else {
- this.nc2Container.put(p, containers);
- }
- }
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // do nothing
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- switch (type) {
- case ADDED:
- addNode(node, props);
- break;
- case REMOVED:
- removeNode(node);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- // do nothing
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
-import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.openflowplugin.openflow.IDataPacketMux;
-
-public class DataPacketServices implements IPluginInDataPacketService {
- protected static final Logger logger = LoggerFactory
- .getLogger(DataPacketServices.class);
- private IDataPacketMux iDataPacketMux = null;
- private IPluginOutConnectionService connectionOutService;
-
- void setIDataPacketMux(IDataPacketMux s) {
- this.iDataPacketMux = s;
- }
-
- void unsetIDataPacketMux(IDataPacketMux s) {
- if (this.iDataPacketMux == s) {
- this.iDataPacketMux = null;
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- @Override
- public void transmitDataPacket(RawPacket outPkt) {
- NodeConnector nc = outPkt.getOutgoingNodeConnector();
- if (connectionOutService != null && connectionOutService.isLocal(nc.getNode())) {
- this.iDataPacketMux.transmitDataPacket(outPkt);
- } else {
- logger.debug("{} is dropped in the controller "+outPkt);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.List;
-
-import org.opendaylight.controller.sal.reader.NodeDescription;
-import org.openflow.protocol.statistics.OFDescriptionStatistics;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class for converting openflow description statistics into SAL
- * NodeDescription object
- */
-public class DescStatisticsConverter {
- private static final Logger log = LoggerFactory
- .getLogger(DescStatisticsConverter.class);
- NodeDescription hwDesc;
- OFDescriptionStatistics ofDesc;
-
- public DescStatisticsConverter(List<OFStatistics> statsList) {
- this.hwDesc = null;
- this.ofDesc = (statsList == null || statsList.isEmpty())?
- null : (OFDescriptionStatistics) statsList.get(0);
- }
- public DescStatisticsConverter(OFDescriptionStatistics desc) {
- this.hwDesc = null;
- this.ofDesc = desc;
- }
-
- public NodeDescription getHwDescription() {
- if (hwDesc == null && ofDesc != null) {
- hwDesc = new NodeDescription();
- hwDesc.setManufacturer(ofDesc.getManufacturerDescription());
- hwDesc.setHardware(ofDesc.getHardwareDescription());
- hwDesc.setSoftware(ofDesc.getSoftwareDescription());
- hwDesc.setDescription(ofDesc.getDatapathDescription());
- hwDesc.setSerialNumber(ofDesc.getSerialNumber());
- }
- log.trace("OFDescriptionStatistics: {}", ofDesc);
- log.trace("NodeDescription: {}", hwDesc);
- return hwDesc;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.openflow.protocol.OFPhysicalPort;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Config;
-import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.State;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.packet.Ethernet;
-import org.opendaylight.controller.sal.packet.LLDP;
-import org.opendaylight.controller.sal.packet.LLDPTLV;
-import org.opendaylight.controller.sal.packet.LinkEncap;
-import org.opendaylight.controller.sal.packet.PacketResult;
-import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.utils.EtherTypes;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.openflowplugin.openflow.IDataPacketListen;
-import org.opendaylight.openflowplugin.openflow.IDataPacketMux;
-import org.opendaylight.openflowplugin.openflow.IDiscoveryListener;
-import org.opendaylight.openflowplugin.openflow.IInventoryProvider;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-
-/**
- * The class describes neighbor discovery service for an OpenFlow network.
- */
-public class DiscoveryService implements IInventoryShimExternalListener, IDataPacketListen, IContainerListener,
- CommandProvider {
- private static Logger logger = LoggerFactory.getLogger(DiscoveryService.class);
- private IController controller = null;
- private IDiscoveryListener discoveryListener = null;
- private IInventoryProvider inventoryProvider = null;
- private IDataPacketMux iDataPacketMux = null;
- // High priority list containing newly added ports which will be served first
- private List<NodeConnector> readyListHi = null;
- // List containing all the ports which will be served periodically
- private List<NodeConnector> readyListLo = null;
- // Staging area during quiet period
- private List<NodeConnector> stagingList = null;
- // Wait for next discovery packet. The map contains the time elapsed since
- // the last received LLDP frame on each node connector
- private ConcurrentMap<NodeConnector, Integer> holdTime = null;
- // Allow one more retry for newly added ports. This map contains the time
- // period elapsed since last discovery pkt transmission on the port.
- private ConcurrentMap<NodeConnector, Integer> elapsedTime = null;
- // OpenFlow edges keyed by head connector
- private ConcurrentMap<NodeConnector, Edge> edgeMap = null;
- // The map contains aging entry keyed by head connector of Production edge
- private ConcurrentMap<NodeConnector, Integer> agingMap = null;
- // Production edges keyed by head connector
- private ConcurrentMap<NodeConnector, Edge> prodMap = null;
-
- private Timer discoveryTimer;
- private DiscoveryTimerTask discoveryTimerTask;
- private final static long discoveryTimerTick = 2L * 1000; // per tick in msec
- private int discoveryTimerTickCount = 0; // main tick counter
- // Max # of ports handled in one batch
- private int discoveryBatchMaxPorts;
- // Periodically restart batching process
- private int discoveryBatchRestartTicks;
- private int discoveryBatchPausePeriod = 2;
- // Pause after this point
- private int discoveryBatchPauseTicks;
- private int discoveryTimeoutTicks;
- private int discoveryThresholdTicks;
- private int discoveryAgeoutTicks;
- // multiple of discoveryBatchRestartTicks
- private int discoveryConsistencyCheckMultiple = 2;
- // CC tick counter
- private int discoveryConsistencyCheckTickCount;
- // # of times CC gets called
- private int discoveryConsistencyCheckCallingTimes = 0;
- // # of cases CC corrected
- private int discoveryConsistencyCheckCorrected = 0;
- // Enable or disable CC
- private boolean discoveryConsistencyCheckEnabled = true;
- // Enable or disable aging
- private boolean discoveryAgingEnabled = true;
- // Global flag to enable or disable LLDP snooping
- private boolean discoverySnoopingEnabled = true;
- // The list of ports that will not do LLDP snooping
- private List<NodeConnector> discoverySnoopingDisableList;
- private BlockingQueue<NodeConnector> transmitQ;
- private Thread transmitThread;
- private Boolean throttling = false; // if true, no more batching.
- private volatile Boolean shuttingDown = false;
-
- private LLDPTLV chassisIdTlv, portIdTlv, ttlTlv, customTlv;
- private IPluginOutConnectionService connectionOutService;
-
- class DiscoveryTransmit implements Runnable {
- private final BlockingQueue<NodeConnector> transmitQ;
-
- DiscoveryTransmit(BlockingQueue<NodeConnector> transmitQ) {
- this.transmitQ = transmitQ;
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- NodeConnector nodeConnector = transmitQ.take();
- RawPacket outPkt = createDiscoveryPacket(nodeConnector);
- sendDiscoveryPacket(nodeConnector, outPkt);
- nodeConnector = null;
- } catch (InterruptedException e1) {
- logger.warn("DiscoveryTransmit interupted", e1.getMessage());
- if (shuttingDown) {
- return;
- }
- } catch (Exception e2) {
- logger.error("", e2);
- }
- }
- }
- }
-
- class DiscoveryTimerTask extends TimerTask {
- @Override
- public void run() {
- checkTimeout();
- checkAging();
- doConsistencyCheck();
- doDiscovery();
- }
- }
-
- public enum DiscoveryPeriod {
- INTERVAL (300),
- AGEOUT (120),
- THRESHOLD (30);
-
- private int time; // sec
- private int tick; // tick
-
- DiscoveryPeriod(int time) {
- this.time = time;
- this.tick = time2Tick(time);
- }
-
- public int getTime() {
- return time;
- }
-
- public void setTime(int time) {
- this.time = time;
- this.tick = time2Tick(time);
- }
-
- public int getTick() {
- return tick;
- }
-
- public void setTick(int tick) {
- this.time = tick2Time(tick);
- this.tick = tick;
- }
-
- private int time2Tick(int time) {
- return (int) (time / (discoveryTimerTick / 1000));
- }
-
- private int tick2Time(int tick) {
- return (int) (tick * (discoveryTimerTick / 1000));
- }
- }
-
- private RawPacket createDiscoveryPacket(NodeConnector nodeConnector) {
- String nodeId = HexEncode.longToHexString((Long) nodeConnector.getNode().getID());
-
- // Create LLDP ChassisID TLV
- byte[] cidValue = LLDPTLV.createChassisIDTLVValue(nodeId);
- chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue()).setLength((short) cidValue.length)
- .setValue(cidValue);
-
- // Create LLDP PortID TLV
- String portId = nodeConnector.getNodeConnectorIDString();
- byte[] pidValue = LLDPTLV.createPortIDTLVValue(portId);
- portIdTlv.setType(LLDPTLV.TLVType.PortID.getValue()).setLength((short) pidValue.length).setValue(pidValue);
-
- // Create LLDP Custom TLV
- byte[] customValue = LLDPTLV.createCustomTLVValue(nodeConnector.toString());
- customTlv.setType(LLDPTLV.TLVType.Custom.getValue()).setLength((short) customValue.length)
- .setValue(customValue);
-
- // Create LLDP Custom Option list
- List<LLDPTLV> customList = new ArrayList<LLDPTLV>();
- customList.add(customTlv);
-
- // Create discovery pkt
- LLDP discoveryPkt = new LLDP();
- discoveryPkt.setChassisId(chassisIdTlv).setPortId(portIdTlv).setTtl(ttlTlv).setOptionalTLVList(customList);
-
- RawPacket rawPkt = null;
- try {
- // Create ethernet pkt
- byte[] sourceMac = getSourceMACFromNodeID(nodeId);
- Ethernet ethPkt = new Ethernet();
- ethPkt.setSourceMACAddress(sourceMac).setDestinationMACAddress(LLDP.LLDPMulticastMac)
- .setEtherType(EtherTypes.LLDP.shortValue()).setPayload(discoveryPkt);
-
- byte[] data = ethPkt.serialize();
- rawPkt = new RawPacket(data);
- rawPkt.setOutgoingNodeConnector(nodeConnector);
- } catch (ConstructionException cex) {
- logger.warn("RawPacket creation caught exception {}", cex.getMessage());
- } catch (Exception e) {
- logger.error("Failed to serialize the LLDP packet: " + e);
- }
-
- return rawPkt;
- }
-
- private void sendDiscoveryPacket(NodeConnector nodeConnector, RawPacket outPkt) {
- if (nodeConnector == null) {
- logger.debug("Can not send discovery packet out since nodeConnector is null");
- return;
- }
-
- if (!connectionOutService.isLocal(nodeConnector.getNode())) {
- logger.debug("Discoery packets will not be sent to {} in a non-master controller", nodeConnector.toString());
- return;
- }
-
- if (outPkt == null) {
- logger.debug("Can not send discovery packet out since outPkt is null");
- return;
- }
-
- long sid = (Long) nodeConnector.getNode().getID();
- ISwitch sw = controller.getSwitches().get(sid);
-
- if (sw == null) {
- logger.debug("Can not send discovery packet out since switch {} is null", sid);
- return;
- }
-
- if (!sw.isOperational()) {
- logger.debug("Can not send discovery packet out since switch {} is not operational", sw);
- return;
- }
-
- if (this.iDataPacketMux == null) {
- logger.debug("Can not send discovery packet out since DataPacket service is not available");
- return;
- }
-
- logger.trace("Sending topology discovery pkt thru {}", nodeConnector);
- this.iDataPacketMux.transmitDataPacket(outPkt);
- }
-
- @Override
- public PacketResult receiveDataPacket(RawPacket inPkt) {
- if (inPkt == null) {
- logger.debug("Ignoring null packet");
- return PacketResult.IGNORED;
- }
-
- byte[] data = inPkt.getPacketData();
- if (data.length <= 0) {
- logger.trace("Ignoring zero length packet");
- return PacketResult.IGNORED;
- }
-
- if (!inPkt.getEncap().equals(LinkEncap.ETHERNET)) {
- logger.trace("Ignoring non ethernet packet");
- return PacketResult.IGNORED;
- }
-
- NodeConnector nodeConnector = inPkt.getIncomingNodeConnector();
- if (((Short) nodeConnector.getID()).equals(NodeConnector.SPECIALNODECONNECTORID)) {
- logger.trace("Ignoring ethernet packet received on special port: "
- + inPkt.getIncomingNodeConnector().toString());
- return PacketResult.IGNORED;
- }
-
- if (!connectionOutService.isLocal(nodeConnector.getNode())) {
- logger.debug("Discoery packets will not be processed from {} in a non-master controller", nodeConnector.toString());
- return PacketResult.IGNORED;
- }
-
- Ethernet ethPkt = new Ethernet();
- try {
- ethPkt.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
- } catch (Exception e) {
- logger.warn("Failed to decode LLDP packet from {}: {}", inPkt.getIncomingNodeConnector(), e);
- return PacketResult.IGNORED;
- }
-
- if (ethPkt.getPayload() instanceof LLDP) {
- NodeConnector dst = inPkt.getIncomingNodeConnector();
- if (isEnabled(dst)) {
- if (!processDiscoveryPacket(dst, ethPkt)) {
- // Snoop the discovery pkt if not generated from us
- snoopDiscoveryPacket(dst, ethPkt);
- }
- return PacketResult.CONSUME;
- }
- }
- return PacketResult.IGNORED;
- }
-
- /*
- * Snoop incoming discovery frames generated by the production network
- * neighbor switch
- */
- private void snoopDiscoveryPacket(NodeConnector dstNodeConnector, Ethernet ethPkt) {
- if (!this.discoverySnoopingEnabled || discoverySnoopingDisableList.contains(dstNodeConnector)) {
- logger.trace("Discarded received discovery packet on {} since snooping is turned off", dstNodeConnector);
- return;
- }
-
- if ((dstNodeConnector == null) || (ethPkt == null)) {
- logger.trace("Quit snooping discovery packet: Null node connector or packet");
- return;
- }
-
- LLDP lldp = (LLDP) ethPkt.getPayload();
-
- try {
- String nodeId = LLDPTLV.getHexStringValue(lldp.getChassisId().getValue(), lldp.getChassisId().getLength());
- String portId = LLDPTLV.getStringValue(lldp.getPortId().getValue(), lldp.getPortId().getLength());
- byte[] systemNameBytes = null;
- // get system name if present in the LLDP pkt
- for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
- if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
- systemNameBytes = lldptlv.getValue();
- break;
- }
- }
- String nodeName = (systemNameBytes == null) ? nodeId
- : new String(systemNameBytes, Charset.defaultCharset());
- Node srcNode = new Node(Node.NodeIDType.PRODUCTION, nodeName);
- NodeConnector srcNodeConnector = NodeConnectorCreator.createNodeConnector(
- NodeConnector.NodeConnectorIDType.PRODUCTION, portId, srcNode);
-
- Edge edge = null;
- Set<Property> props = null;
- edge = new Edge(srcNodeConnector, dstNodeConnector);
- props = getProps(dstNodeConnector);
-
- updateProdEdge(edge, props);
- } catch (Exception e) {
- logger.warn("Caught exception ", e);
- }
- }
-
- /*
- * Handle discovery frames generated by our controller
- *
- * @return true if it's a success
- */
- private boolean processDiscoveryPacket(NodeConnector dstNodeConnector, Ethernet ethPkt) {
- if ((dstNodeConnector == null) || (ethPkt == null)) {
- logger.trace("Ignoring processing of discovery packet: Null node connector or packet");
- return false;
- }
-
- logger.trace("Handle discovery packet {} from {}", ethPkt, dstNodeConnector);
-
- LLDP lldp = (LLDP) ethPkt.getPayload();
-
- List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
- if (optionalTLVList == null) {
- logger.info("The discovery packet with null custom option from {}", dstNodeConnector);
- return false;
- }
-
- Node srcNode = null;
- NodeConnector srcNodeConnector = null;
- for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
- if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
- String ncString = LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength());
- srcNodeConnector = NodeConnector.fromString(ncString);
- if (srcNodeConnector != null) {
- srcNode = srcNodeConnector.getNode();
- }
- }
- }
-
- if ((srcNode == null) || (srcNodeConnector == null)) {
- logger.trace("Received non-controller generated discovery packet from {}", dstNodeConnector);
- return false;
- }
-
- // push it out to Topology
- Edge edge = null;
- Set<Property> props = null;
- try {
- edge = new Edge(srcNodeConnector, dstNodeConnector);
- props = getProps(dstNodeConnector);
- } catch (ConstructionException e) {
- logger.error("Caught exception ", e);
- }
- addEdge(edge, props);
-
- logger.trace("Received discovery packet for Edge {}", edge);
-
- return true;
- }
-
- public Map<String, Property> getPropMap(NodeConnector nodeConnector) {
- if (nodeConnector == null) {
- return null;
- }
-
- if (inventoryProvider == null) {
- return null;
- }
-
- Map<NodeConnector, Map<String, Property>> props = inventoryProvider.getNodeConnectorProps(false);
- if (props == null) {
- return null;
- }
-
- return props.get(nodeConnector);
- }
-
- public Property getProp(NodeConnector nodeConnector, String propName) {
- Map<String, Property> propMap = getPropMap(nodeConnector);
- if (propMap == null) {
- return null;
- }
-
- Property prop = propMap.get(propName);
- return prop;
- }
-
- public Set<Property> getProps(NodeConnector nodeConnector) {
- Map<String, Property> propMap = getPropMap(nodeConnector);
- if (propMap == null) {
- return null;
- }
-
- Set<Property> props = new HashSet<Property>(propMap.values());
- return props;
- }
-
- private boolean isEnabled(NodeConnector nodeConnector) {
- if (nodeConnector == null) {
- return false;
- }
-
- Config config = (Config) getProp(nodeConnector, Config.ConfigPropName);
- State state = (State) getProp(nodeConnector, State.StatePropName);
- return ((config != null) && (config.getValue() == Config.ADMIN_UP) && (state != null) && (state.getValue() == State.EDGE_UP));
- }
-
- private boolean isTracked(NodeConnector nodeConnector) {
- if (readyListHi.contains(nodeConnector)) {
- return true;
- }
-
- if (readyListLo.contains(nodeConnector)) {
- return true;
- }
-
- if (holdTime.keySet().contains(nodeConnector)) {
- return true;
- }
-
- if (stagingList.contains(nodeConnector)) {
- return true;
- }
-
- return false;
- }
-
- private Set<NodeConnector> getWorkingSet() {
- Set<NodeConnector> workingSet = new HashSet<NodeConnector>();
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
-
- for (NodeConnector nodeConnector : readyListHi) {
- if (isOverLimit(workingSet.size())) {
- break;
- }
-
- workingSet.add(nodeConnector);
- removeSet.add(nodeConnector);
-
- // Put it in the map and start the timer. It may need retry.
- elapsedTime.put(nodeConnector, 0);
- }
- readyListHi.removeAll(removeSet);
-
- removeSet.clear();
- for (NodeConnector nodeConnector : readyListLo) {
- if (isOverLimit(workingSet.size())) {
- break;
- }
-
- workingSet.add(nodeConnector);
- removeSet.add(nodeConnector);
- }
- readyListLo.removeAll(removeSet);
-
- return workingSet;
- }
-
- private Boolean isOverLimit(int size) {
- return ((size >= discoveryBatchMaxPorts) && !throttling);
- }
-
- private void addDiscovery() {
- Map<Long, ISwitch> switches = controller.getSwitches();
- Set<Long> sidSet = switches.keySet();
- if (sidSet == null) {
- return;
- }
- for (Long sid : sidSet) {
- Node node = NodeCreator.createOFNode(sid);
- addDiscovery(node);
- }
- }
-
- private void addDiscovery(Node node) {
- Map<Long, ISwitch> switches = controller.getSwitches();
- ISwitch sw = switches.get(node.getID());
- List<OFPhysicalPort> ports = sw.getEnabledPorts();
- if (ports == null) {
- return;
- }
- for (OFPhysicalPort port : ports) {
- NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
- if (!readyListHi.contains(nodeConnector)) {
- readyListHi.add(nodeConnector);
- }
- }
- }
-
- private void addDiscovery(NodeConnector nodeConnector) {
- if (isTracked(nodeConnector)) {
- return;
- }
-
- readyListHi.add(nodeConnector);
- }
-
- private Set<NodeConnector> getRemoveSet(Collection<NodeConnector> c, Node node) {
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- if (c == null) {
- return removeSet;
- }
- for (NodeConnector nodeConnector : c) {
- if (node.equals(nodeConnector.getNode())) {
- Edge edge1 = edgeMap.get(nodeConnector);
- if (edge1 != null) {
- removeSet.add(nodeConnector);
-
- // check reverse direction
- Edge edge2 = edgeMap.get(edge1.getTailNodeConnector());
- if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) {
- removeSet.add(edge2.getHeadNodeConnector());
- }
- }
- }
- }
- return removeSet;
- }
-
- private void removeDiscovery(Node node) {
- Set<NodeConnector> removeSet;
-
- removeSet = getRemoveSet(readyListHi, node);
- readyListHi.removeAll(removeSet);
-
- removeSet = getRemoveSet(readyListLo, node);
- readyListLo.removeAll(removeSet);
-
- removeSet = getRemoveSet(stagingList, node);
- stagingList.removeAll(removeSet);
-
- removeSet = getRemoveSet(holdTime.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- holdTime.remove(nodeConnector);
- }
-
- removeSet = getRemoveSet(edgeMap.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector, false);
- }
-
- removeSet = getRemoveSet(prodMap.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- removeProdEdge(nodeConnector);
- }
- }
-
- private void removeDiscovery(NodeConnector nodeConnector) {
- readyListHi.remove(nodeConnector);
- readyListLo.remove(nodeConnector);
- stagingList.remove(nodeConnector);
- holdTime.remove(nodeConnector);
- removeEdge(nodeConnector, false);
- removeProdEdge(nodeConnector);
- }
-
- private void checkTimeout() {
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- int ticks;
-
- Set<NodeConnector> monitorSet = holdTime.keySet();
- if (monitorSet != null) {
- for (NodeConnector nodeConnector : monitorSet) {
- ticks = holdTime.get(nodeConnector);
- holdTime.put(nodeConnector, ++ticks);
- if (ticks >= discoveryTimeoutTicks) {
- // timeout the edge
- removeSet.add(nodeConnector);
- logger.trace("Discovery timeout {}", nodeConnector);
- }
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector);
- }
-
- Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
- Set<NodeConnector> ncSet = elapsedTime.keySet();
- if ((ncSet != null) && (ncSet.size() > 0)) {
- for (NodeConnector nodeConnector : ncSet) {
- ticks = elapsedTime.get(nodeConnector);
- elapsedTime.put(nodeConnector, ++ticks);
- if (ticks >= discoveryThresholdTicks) {
- retrySet.add(nodeConnector);
- }
- }
-
- for (NodeConnector nodeConnector : retrySet) {
- // Allow one more retry
- readyListLo.add(nodeConnector);
- elapsedTime.remove(nodeConnector);
- if (connectionOutService.isLocal(nodeConnector.getNode())) {
- transmitQ.add(nodeConnector);
- }
- }
- }
- }
-
- private void checkAging() {
- if (!discoveryAgingEnabled) {
- return;
- }
-
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- int ticks;
-
- Set<NodeConnector> agingSet = agingMap.keySet();
- if (agingSet != null) {
- for (NodeConnector nodeConnector : agingSet) {
- ticks = agingMap.get(nodeConnector);
- agingMap.put(nodeConnector, ++ticks);
- if (ticks > discoveryAgeoutTicks) {
- // age out the edge
- removeSet.add(nodeConnector);
- logger.trace("Discovery age out {}", nodeConnector);
- }
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeProdEdge(nodeConnector);
- }
- }
-
- private void doDiscovery() {
- if (++discoveryTimerTickCount <= discoveryBatchPauseTicks) {
- for (NodeConnector nodeConnector : getWorkingSet()) {
- if (connectionOutService.isLocal(nodeConnector.getNode())) {
- transmitQ.add(nodeConnector);
- // Move to staging area after it's served
- if (!stagingList.contains(nodeConnector)) {
- stagingList.add(nodeConnector);
- }
- }
- }
- } else if (discoveryTimerTickCount >= discoveryBatchRestartTicks) {
- discoveryTimerTickCount = 0;
- for (NodeConnector nodeConnector : stagingList) {
- if (!readyListLo.contains(nodeConnector)) {
- readyListLo.add(nodeConnector);
- }
- }
- stagingList.removeAll(readyListLo);
- }
- }
-
- private void doConsistencyCheck() {
- if (!discoveryConsistencyCheckEnabled) {
- return;
- }
-
- if (++discoveryConsistencyCheckTickCount % getDiscoveryConsistencyCheckInterval() != 0) {
- return;
- }
-
- discoveryConsistencyCheckCallingTimes++;
-
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- Set<NodeConnector> ncSet = edgeMap.keySet();
- if (ncSet == null) {
- return;
- }
- for (NodeConnector nodeConnector : ncSet) {
- if (!isEnabled(nodeConnector)) {
- removeSet.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
- continue;
- }
-
- if (!isTracked(nodeConnector)) {
- stagingList.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
- continue;
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector, false);
- }
-
- // remove stale entries
- removeSet.clear();
- for (NodeConnector nodeConnector : stagingList) {
- if (!isEnabled(nodeConnector)) {
- removeSet.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
- }
- }
- stagingList.removeAll(removeSet);
-
- // Get a snapshot of all the existing switches
- Map<Long, ISwitch> switches = this.controller.getSwitches();
- for (ISwitch sw : switches.values()) {
- for (OFPhysicalPort port : sw.getEnabledPorts()) {
- Node node = NodeCreator.createOFNode(sw.getId());
- NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
- if (!isTracked(nodeConnector)) {
- stagingList.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
- }
- }
- }
- }
-
- private void addEdge(Edge edge, Set<Property> props) {
- if (edge == null) {
- return;
- }
-
- NodeConnector src = edge.getTailNodeConnector();
- NodeConnector dst = edge.getHeadNodeConnector();
- if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- holdTime.put(dst, 0);
- } else {
- agingMap.put(dst, 0);
- }
- elapsedTime.remove(src);
-
- // notify
- updateEdge(edge, UpdateType.ADDED, props);
- logger.trace("Add edge {}", edge);
- }
-
- /**
- * Update Production Edge
- *
- * @param edge
- * The Production Edge
- * @param props
- * Properties associated with the edge
- */
- private void updateProdEdge(Edge edge, Set<Property> props) {
- NodeConnector edgePort = edge.getHeadNodeConnector();
-
- /* Do not update in case there is an existing OpenFlow link */
- if (edgeMap.get(edgePort) != null) {
- logger.trace("Discarded edge {} since there is an existing OF link {}", edge, edgeMap.get(edgePort));
- return;
- }
-
- /* Look for any existing Production Edge */
- Edge oldEdge = prodMap.get(edgePort);
- if (oldEdge == null) {
- /* Let's add a new one */
- addEdge(edge, props);
- } else if (!edge.equals(oldEdge)) {
- /* Remove the old one first */
- removeProdEdge(oldEdge.getHeadNodeConnector());
- /* Then add the new one */
- addEdge(edge, props);
- } else {
- /* o/w, just reset the aging timer */
- NodeConnector dst = edge.getHeadNodeConnector();
- agingMap.put(dst, 0);
- }
- }
-
- /**
- * Remove Production Edge for a given edge port
- *
- * @param edgePort
- * The OF edge port
- */
- private void removeProdEdge(NodeConnector edgePort) {
- agingMap.remove(edgePort);
-
- Edge edge = null;
- Set<NodeConnector> prodKeySet = prodMap.keySet();
- if ((prodKeySet != null) && (prodKeySet.contains(edgePort))) {
- edge = prodMap.get(edgePort);
- prodMap.remove(edgePort);
- }
-
- // notify Topology
- if (this.discoveryListener != null) {
- this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
- }
- logger.trace("Remove edge {}", edge);
- }
-
- /*
- * Remove OpenFlow edge
- */
- private void removeEdge(NodeConnector nodeConnector, boolean stillEnabled) {
- holdTime.remove(nodeConnector);
- readyListLo.remove(nodeConnector);
- readyListHi.remove(nodeConnector);
-
- if (stillEnabled) {
- // keep discovering
- if (!stagingList.contains(nodeConnector)) {
- stagingList.add(nodeConnector);
- }
- } else {
- // stop it
- stagingList.remove(nodeConnector);
- }
-
- Edge edge = null;
- Set<NodeConnector> edgeKeySet = edgeMap.keySet();
- if ((edgeKeySet != null) && (edgeKeySet.contains(nodeConnector))) {
- edge = edgeMap.get(nodeConnector);
- edgeMap.remove(nodeConnector);
- }
-
- // notify Topology
- if (this.discoveryListener != null) {
- this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
- }
- logger.trace("Remove {}", nodeConnector);
- }
-
- private void removeEdge(NodeConnector nodeConnector) {
- removeEdge(nodeConnector, isEnabled(nodeConnector));
- }
-
- private void updateEdge(Edge edge, UpdateType type, Set<Property> props) {
- if (discoveryListener == null) {
- return;
- }
-
- this.discoveryListener.notifyEdge(edge, type, props);
-
- NodeConnector src = edge.getTailNodeConnector(), dst = edge.getHeadNodeConnector();
- if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- if (type == UpdateType.ADDED) {
- edgeMap.put(dst, edge);
- } else {
- edgeMap.remove(dst);
- }
- } else {
- /*
- * Save Production edge into different DB keyed by the Edge port
- */
- if (type == UpdateType.ADDED) {
- prodMap.put(dst, edge);
- } else {
- prodMap.remove(dst);
- }
- }
- }
-
- private void moveToReadyListHi(NodeConnector nodeConnector) {
- if (readyListLo.contains(nodeConnector)) {
- readyListLo.remove(nodeConnector);
- } else if (stagingList.contains(nodeConnector)) {
- stagingList.remove(nodeConnector);
- }
- readyListHi.add(nodeConnector);
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this, null);
- }
-
- private int getDiscoveryConsistencyCheckInterval() {
- return discoveryConsistencyCheckMultiple * discoveryBatchRestartTicks;
- }
-
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("---Topology Discovery---\n");
- help.append("\t prlh - Print readyListHi entries\n");
- help.append("\t prll - Print readyListLo entries\n");
- help.append("\t psl - Print stagingList entries\n");
- help.append("\t pht - Print hold time\n");
- help.append("\t pet - Print elapsed time\n");
- help.append("\t ptick - Print tick time in msec\n");
- help.append("\t pcc - Print CC info\n");
- help.append("\t psize - Print sizes of all the lists\n");
- help.append("\t ptm - Print timeout info\n");
- help.append("\t ecc - Enable CC\n");
- help.append("\t dcc - Disable CC\n");
- help.append("\t scc [multiple] - Set/show CC multiple and interval\n");
- help.append("\t sports [ports] - Set/show max ports per batch\n");
- help.append("\t spause [ticks] - Set/show pause period\n");
- help.append("\t sdi [ticks] - Set/show discovery interval in ticks\n");
- help.append("\t addsw <swid> - Add a switch\n");
- help.append("\t remsw <swid> - Remove a switch\n");
- help.append("\t page - Print aging info\n");
- help.append("\t sage - Set/Show aging time limit\n");
- help.append("\t eage - Enable aging\n");
- help.append("\t dage - Disable aging\n");
- help.append("\t pthrot - Print throttling\n");
- help.append("\t ethrot - Enable throttling\n");
- help.append("\t dthrot - Disable throttling\n");
- help.append("\t psnp - Print LLDP snooping\n");
- help.append("\t esnp <all|nodeConnector> - Enable LLDP snooping\n");
- help.append("\t dsnp <all|nodeConnector> - Disable LLDP snooping\n");
- return help.toString();
- }
-
- private List<NodeConnector> sortList(Collection<NodeConnector> ncs) {
- List<String> ncStrArray = new ArrayList<String>();
- for (NodeConnector nc : ncs) {
- ncStrArray.add(nc.toString());
- }
- Collections.sort(ncStrArray);
-
- List<NodeConnector> sortedNodeConnectors = new ArrayList<NodeConnector>();
- for (String ncStr : ncStrArray) {
- sortedNodeConnectors.add(NodeConnector.fromString(ncStr));
- }
-
- return sortedNodeConnectors;
- }
-
- public void _prlh(CommandInterpreter ci) {
- ci.println("readyListHi\n");
- for (NodeConnector nodeConnector : sortList(readyListHi)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + readyListHi.size());
- }
-
- public void _prll(CommandInterpreter ci) {
- ci.println("readyListLo\n");
- for (NodeConnector nodeConnector : sortList(readyListLo)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + readyListLo.size());
- }
-
- public void _psl(CommandInterpreter ci) {
- ci.println("stagingList\n");
- for (NodeConnector nodeConnector : sortList(stagingList)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + stagingList.size());
- }
-
- public void _pht(CommandInterpreter ci) {
- ci.println(" NodeConnector Last rx LLDP (sec)");
- for (ConcurrentMap.Entry<NodeConnector, Integer> entry: holdTime.entrySet()) {
- ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
- }
- ci.println("\nSize: " + holdTime.size() + "\tTimeout: " + discoveryTimeoutTicks * (discoveryTimerTick / 1000)
- + " sec");
- }
-
- public void _pet(CommandInterpreter ci) {
- ci.println(" NodeConnector Elapsed Time (sec)");
- for (ConcurrentMap.Entry<NodeConnector, Integer> entry: elapsedTime.entrySet()) {
- ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
- }
- ci.println("\nSize: " + elapsedTime.size() + "\tThreshold: " + DiscoveryPeriod.THRESHOLD.getTime() + " sec");
- }
-
- public void _ptick(CommandInterpreter ci) {
- ci.println("Current timer is " + discoveryTimerTick + " msec per tick");
- }
-
- public void _pcc(CommandInterpreter ci) {
- if (discoveryConsistencyCheckEnabled) {
- ci.println("ConsistencyChecker is currently enabled");
- } else {
- ci.println("ConsistencyChecker is currently disabled");
- }
- ci.println("Interval " + getDiscoveryConsistencyCheckInterval());
- ci.println("Multiple " + discoveryConsistencyCheckMultiple);
- ci.println("Number of times called " + discoveryConsistencyCheckCallingTimes);
- ci.println("Corrected count " + discoveryConsistencyCheckCorrected);
- }
-
- public void _ptm(CommandInterpreter ci) {
- ci.println("Timeout " + discoveryTimeoutTicks + " ticks, " + discoveryTimerTick / 1000 + " sec per tick.");
- }
-
- public void _psize(CommandInterpreter ci) {
- ci.println("readyListLo size " + readyListLo.size() + "\n" + "readyListHi size " + readyListHi.size() + "\n"
- + "stagingList size " + stagingList.size() + "\n" + "holdTime size " + holdTime.size() + "\n"
- + "edgeMap size " + edgeMap.size() + "\n" + "prodMap size " + prodMap.size() + "\n" + "agingMap size "
- + agingMap.size() + "\n" + "elapsedTime size " + elapsedTime.size());
- }
-
- public void _page(CommandInterpreter ci) {
- if (this.discoveryAgingEnabled) {
- ci.println("Aging is enabled");
- } else {
- ci.println("Aging is disabled");
- }
- ci.println("Current aging time limit " + this.discoveryAgeoutTicks);
- ci.println("\n");
- ci.println(" Edge Aging ");
- Collection<Edge> prodSet = prodMap.values();
- if (prodSet == null) {
- return;
- }
- for (Edge edge : prodSet) {
- Integer aging = agingMap.get(edge.getHeadNodeConnector());
- if (aging != null) {
- ci.println(edge + " " + aging);
- }
- }
- ci.println("\n");
- ci.println(" NodeConnector Edge ");
- Set<NodeConnector> keySet = prodMap.keySet();
- if (keySet == null) {
- return;
- }
- for (NodeConnector nc : keySet) {
- ci.println(nc + " " + prodMap.get(nc));
- }
- return;
- }
-
- public void _sage(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter aging time limit. Current value " + this.discoveryAgeoutTicks);
- return;
- }
- try {
- this.discoveryAgeoutTicks = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _eage(CommandInterpreter ci) {
- this.discoveryAgingEnabled = true;
- ci.println("Aging is enabled");
- return;
- }
-
- public void _dage(CommandInterpreter ci) {
- this.discoveryAgingEnabled = false;
- ci.println("Aging is disabled");
- return;
- }
-
- public void _scc(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter CC multiple. Current multiple " + discoveryConsistencyCheckMultiple
- + " (interval " + getDiscoveryConsistencyCheckInterval() + ") calling times "
- + discoveryConsistencyCheckCallingTimes);
- return;
- }
- try {
- discoveryConsistencyCheckMultiple = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _ecc(CommandInterpreter ci) {
- this.discoveryConsistencyCheckEnabled = true;
- ci.println("ConsistencyChecker is enabled");
- return;
- }
-
- public void _dcc(CommandInterpreter ci) {
- this.discoveryConsistencyCheckEnabled = false;
- ci.println("ConsistencyChecker is disabled");
- return;
- }
-
- public void _psnp(CommandInterpreter ci) {
- if (this.discoverySnoopingEnabled) {
- ci.println("Discovery snooping is globally enabled");
- } else {
- ci.println("Discovery snooping is globally disabled");
- }
-
- ci.println("\nDiscovery snooping is locally disabled on these ports");
- for (NodeConnector nodeConnector : discoverySnoopingDisableList) {
- ci.println(nodeConnector);
- }
- return;
- }
-
- public void _esnp(CommandInterpreter ci) {
- String val = ci.nextArgument();
-
- if (val == null) {
- ci.println("Usage: esnp <all|nodeConnector>");
- } else if (val.equalsIgnoreCase("all")) {
- this.discoverySnoopingEnabled = true;
- ci.println("Discovery snooping is globally enabled");
- } else {
- NodeConnector nodeConnector = NodeConnector.fromString(val);
- if (nodeConnector != null) {
- discoverySnoopingDisableList.remove(nodeConnector);
- ci.println("Discovery snooping is locally enabled on port " + nodeConnector);
- } else {
- ci.println("Entered invalid NodeConnector " + val);
- }
- }
- return;
- }
-
- public void _dsnp(CommandInterpreter ci) {
- String val = ci.nextArgument();
-
- if (val == null) {
- ci.println("Usage: dsnp <all|nodeConnector>");
- } else if (val.equalsIgnoreCase("all")) {
- this.discoverySnoopingEnabled = false;
- ci.println("Discovery snooping is globally disabled");
- } else {
- NodeConnector nodeConnector = NodeConnector.fromString(val);
- if (nodeConnector != null) {
- discoverySnoopingDisableList.add(nodeConnector);
- ci.println("Discovery snooping is locally disabled on port " + nodeConnector);
- } else {
- ci.println("Entered invalid NodeConnector " + val);
- }
- }
- return;
- }
-
- public void _spause(CommandInterpreter ci) {
- String val = ci.nextArgument();
- String out = "Please enter pause period less than " + discoveryBatchRestartTicks + ". Current pause period is "
- + discoveryBatchPausePeriod + " ticks, pause at " + discoveryBatchPauseTicks + " ticks, "
- + discoveryTimerTick / 1000 + " sec per tick.";
-
- if (val != null) {
- try {
- int pause = Integer.parseInt(val);
- if (pause < discoveryBatchRestartTicks) {
- discoveryBatchPausePeriod = pause;
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- return;
- }
- } catch (Exception e) {
- }
- }
-
- ci.println(out);
- }
-
- public void _sdi(CommandInterpreter ci) {
- String val = ci.nextArgument();
- String out = "Please enter discovery interval in ticks. Current value is " + discoveryBatchRestartTicks + " ticks, "
- + discoveryTimerTick / 1000 + " sec per tick.";
-
- if (val != null) {
- try {
- int ticks = Integer.parseInt(val);
- DiscoveryPeriod.INTERVAL.setTick(ticks);
- discoveryBatchRestartTicks = getDiscoveryInterval();
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- discoveryTimeoutTicks = getDiscoveryTimeout();
- return;
- } catch (Exception e) {
- }
- }
- ci.println(out);
- }
-
- public void _sports(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter max ports per batch. Current value is " + discoveryBatchMaxPorts);
- return;
- }
- try {
- discoveryBatchMaxPorts = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _addsw(CommandInterpreter ci) {
- String val = ci.nextArgument();
- Long sid;
- try {
- sid = Long.parseLong(val);
- Node node = NodeCreator.createOFNode(sid);
- addDiscovery(node);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _remsw(CommandInterpreter ci) {
- String val = ci.nextArgument();
- Long sid;
- try {
- sid = Long.parseLong(val);
- Node node = NodeCreator.createOFNode(sid);
- removeDiscovery(node);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _pthrot(CommandInterpreter ci) {
- if (this.throttling) {
- ci.println("Throttling is enabled");
- } else {
- ci.println("Throttling is disabled");
- }
- }
-
- public void _ethrot(CommandInterpreter ci) {
- this.throttling = true;
- ci.println("Throttling is enabled");
- return;
- }
-
- public void _dthrot(CommandInterpreter ci) {
- this.throttling = false;
- ci.println("Throttling is disabled");
- return;
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- switch (type) {
- case ADDED:
- addNode(node, props);
- break;
- case REMOVED:
- removeNode(node);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- Config config = null;
- State state = null;
- boolean enabled = false;
-
- for (Property prop : props) {
- if (prop.getName().equals(Config.ConfigPropName)) {
- config = (Config) prop;
- } else if (prop.getName().equals(State.StatePropName)) {
- state = (State) prop;
- }
- }
- enabled = ((config != null) && (config.getValue() == Config.ADMIN_UP) && (state != null) && (state.getValue() == State.EDGE_UP));
-
- switch (type) {
- case ADDED:
- if (enabled) {
- addDiscovery(nodeConnector);
- logger.trace("ADDED enabled {}", nodeConnector);
- } else {
- logger.trace("ADDED disabled {}", nodeConnector);
- }
- break;
- case CHANGED:
- if (enabled) {
- addDiscovery(nodeConnector);
- logger.trace("CHANGED enabled {}", nodeConnector);
- } else {
- removeDiscovery(nodeConnector);
- logger.trace("CHANGED disabled {}", nodeConnector);
- }
- break;
- case REMOVED:
- removeDiscovery(nodeConnector);
- logger.trace("REMOVED enabled {}", nodeConnector);
- break;
- default:
- return;
- }
- }
-
- public void addNode(Node node, Set<Property> props) {
- if (node == null) {
- return;
- }
-
- addDiscovery(node);
- }
-
- public void removeNode(Node node) {
- if (node == null) {
- return;
- }
-
- removeDiscovery(node);
- }
-
- void setController(IController s) {
- this.controller = s;
- }
-
- void unsetController(IController s) {
- if (this.controller == s) {
- this.controller = null;
- }
- }
-
- public void setInventoryProvider(IInventoryProvider service) {
- this.inventoryProvider = service;
- }
-
- public void unsetInventoryProvider(IInventoryProvider service) {
- this.inventoryProvider = null;
- }
-
- public void setIDataPacketMux(IDataPacketMux service) {
- this.iDataPacketMux = service;
- }
-
- public void unsetIDataPacketMux(IDataPacketMux service) {
- if (this.iDataPacketMux == service) {
- this.iDataPacketMux = null;
- }
- }
-
- void setDiscoveryListener(IDiscoveryListener s) {
- this.discoveryListener = s;
- }
-
- void unsetDiscoveryListener(IDiscoveryListener s) {
- if (this.discoveryListener == s) {
- this.discoveryListener = null;
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- private void initDiscoveryPacket() {
- // Create LLDP ChassisID TLV
- chassisIdTlv = new LLDPTLV();
- chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue());
-
- // Create LLDP PortID TLV
- portIdTlv = new LLDPTLV();
- portIdTlv.setType(LLDPTLV.TLVType.PortID.getValue());
-
- // Create LLDP TTL TLV
- byte[] ttl = new byte[] { (byte) 0, (byte) 120 };
- ttlTlv = new LLDPTLV();
- ttlTlv.setType(LLDPTLV.TLVType.TTL.getValue()).setLength((short) ttl.length).setValue(ttl);
-
- customTlv = new LLDPTLV();
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- logger.trace("Init called");
-
- transmitQ = new LinkedBlockingQueue<NodeConnector>();
-
- readyListHi = new CopyOnWriteArrayList<NodeConnector>();
- readyListLo = new CopyOnWriteArrayList<NodeConnector>();
- stagingList = new CopyOnWriteArrayList<NodeConnector>();
- holdTime = new ConcurrentHashMap<NodeConnector, Integer>();
- elapsedTime = new ConcurrentHashMap<NodeConnector, Integer>();
- edgeMap = new ConcurrentHashMap<NodeConnector, Edge>();
- agingMap = new ConcurrentHashMap<NodeConnector, Integer>();
- prodMap = new ConcurrentHashMap<NodeConnector, Edge>();
- discoverySnoopingDisableList = new CopyOnWriteArrayList<NodeConnector>();
-
- discoveryBatchRestartTicks = getDiscoveryInterval();
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- discoveryTimeoutTicks = getDiscoveryTimeout();
- discoveryThresholdTicks = getDiscoveryThreshold();
- discoveryAgeoutTicks = getDiscoveryAgeout();
- discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
- discoveryBatchMaxPorts = getDiscoveryBatchMaxPorts();
-
- discoveryTimer = new Timer("DiscoveryService");
- discoveryTimerTask = new DiscoveryTimerTask();
-
- transmitThread = new Thread(new DiscoveryTransmit(transmitQ));
-
- initDiscoveryPacket();
-
- registerWithOSGIConsole();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- transmitQ = null;
- readyListHi = null;
- readyListLo = null;
- stagingList = null;
- holdTime = null;
- edgeMap = null;
- agingMap = null;
- prodMap = null;
- discoveryTimer = null;
- discoveryTimerTask = null;
- transmitThread = null;
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- discoveryTimer.schedule(discoveryTimerTask, discoveryTimerTick, discoveryTimerTick);
- transmitThread.start();
- }
-
- /**
- * Function called after registering the service in OSGi service registry.
- */
- void started() {
- /* get a snapshot of all the existing switches */
- addDiscovery();
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- shuttingDown = true;
- discoveryTimer.cancel();
- transmitThread.interrupt();
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) {
- }
-
- @Override
- public void containerFlowUpdated(String containerName, ContainerFlow previousFlow, ContainerFlow currentFlow,
- UpdateType t) {
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType t) {
- switch (t) {
- case ADDED:
- moveToReadyListHi(p);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // do nothing
- }
-
- private byte[] getSourceMACFromNodeID(String nodeId) {
- byte[] cid = HexEncode.bytesFromHexString(nodeId);
- byte[] sourceMac = new byte[6];
- int pos = cid.length - sourceMac.length;
-
- if (pos >= 0) {
- System.arraycopy(cid, pos, sourceMac, 0, sourceMac.length);
- }
-
- return sourceMac;
- }
-
- private int getDiscoveryTicks(DiscoveryPeriod dp, String val) {
- if (dp == null) {
- return 0;
- }
-
- if (val != null) {
- try {
- dp.setTime(Integer.parseInt(val));
- } catch (Exception e) {
- }
- }
-
- return dp.getTick();
- }
-
- /**
- * This method returns the interval which determines how often the discovery
- * packets will be sent.
- *
- * @return The discovery interval in ticks
- */
- private int getDiscoveryInterval() {
- String intvl = System.getProperty("of.discoveryInterval");
- return getDiscoveryTicks(DiscoveryPeriod.INTERVAL, intvl);
- }
-
- /**
- * This method returns the timeout value in receiving subsequent discovery packets on a port.
- *
- * @return The discovery timeout in ticks
- */
- private int getDiscoveryTimeout() {
- String val = System.getProperty("of.discoveryTimeoutMultiple");
- int multiple = 2;
-
- if (val != null) {
- try {
- multiple = Integer.parseInt(val);
- } catch (Exception e) {
- }
- }
- return getDiscoveryInterval() * multiple + 3;
- }
-
- /**
- * This method returns the user configurable threshold value
- *
- * @return The discovery threshold value in ticks
- */
- private int getDiscoveryThreshold() {
- String val = System.getProperty("of.discoveryThreshold");
- return getDiscoveryTicks(DiscoveryPeriod.THRESHOLD, val);
- }
-
- /**
- * This method returns the discovery entry aging time in ticks.
- *
- * @return The aging time in ticks
- */
- private int getDiscoveryAgeout() {
- return getDiscoveryTicks(DiscoveryPeriod.AGEOUT, null);
- }
-
- /**
- * This method returns the pause interval
- *
- * @return The pause interval in ticks
- */
- private int getDiscoveryPauseInterval() {
- if (discoveryBatchRestartTicks > discoveryBatchPausePeriod) {
- return discoveryBatchRestartTicks - discoveryBatchPausePeriod;
- } else {
- return discoveryBatchRestartTicks - 1;
- }
- }
-
- /**
- * This method returns the user configurable maximum number of ports handled
- * in one discovery batch.
- *
- * @return The maximum number of ports
- */
- private int getDiscoveryBatchMaxPorts() {
- String val = System.getProperty("of.discoveryBatchMaxPorts");
- int ports = 1024;
-
- if (val != null) {
- try {
- ports = Integer.parseInt(val);
- } catch (Exception e) {
- }
- }
- return ports;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.controller.sal.action.Action;
-import org.opendaylight.controller.sal.action.ActionType;
-import org.opendaylight.controller.sal.action.Controller;
-import org.opendaylight.controller.sal.action.Drop;
-import org.opendaylight.controller.sal.action.Flood;
-import org.opendaylight.controller.sal.action.FloodAll;
-import org.opendaylight.controller.sal.action.HwPath;
-import org.opendaylight.controller.sal.action.Loopback;
-import org.opendaylight.controller.sal.action.Output;
-import org.opendaylight.controller.sal.action.PopVlan;
-import org.opendaylight.controller.sal.action.SetDlDst;
-import org.opendaylight.controller.sal.action.SetDlSrc;
-import org.opendaylight.controller.sal.action.SetNwDst;
-import org.opendaylight.controller.sal.action.SetNwSrc;
-import org.opendaylight.controller.sal.action.SetNwTos;
-import org.opendaylight.controller.sal.action.SetTpDst;
-import org.opendaylight.controller.sal.action.SetTpSrc;
-import org.opendaylight.controller.sal.action.SetVlanId;
-import org.opendaylight.controller.sal.action.SetVlanPcp;
-import org.opendaylight.controller.sal.action.SwPath;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.match.Match;
-import org.opendaylight.controller.sal.match.MatchField;
-import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6FlowMod;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6Match;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFVendor;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayer;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
-import org.openflow.protocol.action.OFActionDataLayerSource;
-import org.openflow.protocol.action.OFActionNetworkLayerAddress;
-import org.openflow.protocol.action.OFActionNetworkLayerDestination;
-import org.openflow.protocol.action.OFActionNetworkLayerSource;
-import org.openflow.protocol.action.OFActionNetworkTypeOfService;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.protocol.action.OFActionTransportLayer;
-import org.openflow.protocol.action.OFActionTransportLayerDestination;
-import org.openflow.protocol.action.OFActionTransportLayerSource;
-import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
-import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
-import org.openflow.util.U16;
-import org.openflow.util.U32;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class for converting a SAL Flow into the OF flow and vice-versa
- */
-public class FlowConverter {
- protected static final Logger logger = LoggerFactory
- .getLogger(FlowConverter.class);
-
- /*
- * The value 0xffff (OFP_VLAN_NONE) is used to indicate
- * that no VLAN ID is set for OF Flow.
- */
- private static final short OFP_VLAN_NONE = (short) 0xffff;
-
- private Flow flow; // SAL Flow
- private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
- private List<OFAction> actionsList; // OF 1.0 actions
- private int actionsLength;
- private boolean isIPv6;
-
- public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
- this.ofMatch = ofMatch;
- this.actionsList = actionsList;
- this.actionsLength = 0;
- this.flow = null;
- this.isIPv6 = ofMatch instanceof V6Match;
- }
-
- public FlowConverter(Flow flow) {
- this.ofMatch = null;
- this.actionsList = null;
- this.actionsLength = 0;
- this.flow = flow;
- this.isIPv6 = flow.isIPv6();
- }
-
- /**
- * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
- * form (V6Match)
- *
- * @return
- */
- public OFMatch getOFMatch() {
- if (ofMatch == null) {
- Match match = flow.getMatch();
- ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
-
- int wildcards = OFMatch.OFPFW_ALL;
- if (match.isPresent(MatchType.IN_PORT)) {
- short port = (Short) ((NodeConnector) match.getField(
- MatchType.IN_PORT).getValue()).getID();
- if (!isIPv6) {
- ofMatch.setInputPort(port);
- wildcards &= ~OFMatch.OFPFW_IN_PORT;
- } else {
- ((V6Match) ofMatch).setInputPort(port, (short) 0);
- }
- }
- if (match.isPresent(MatchType.DL_SRC)) {
- byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
- .getValue();
- if (!isIPv6) {
- ofMatch.setDataLayerSource(srcMac.clone());
- wildcards &= ~OFMatch.OFPFW_DL_SRC;
- } else {
- ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
- }
- }
- if (match.isPresent(MatchType.DL_DST)) {
- byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
- .getValue();
- if (!isIPv6) {
- ofMatch.setDataLayerDestination(dstMac.clone());
- wildcards &= ~OFMatch.OFPFW_DL_DST;
- } else {
- ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
- }
- }
- if (match.isPresent(MatchType.DL_VLAN)) {
- short vlan = (Short) match.getField(MatchType.DL_VLAN)
- .getValue();
- if (vlan == MatchType.DL_VLAN_NONE) {
- vlan = OFP_VLAN_NONE;
- }
- if (!isIPv6) {
- ofMatch.setDataLayerVirtualLan(vlan);
- wildcards &= ~OFMatch.OFPFW_DL_VLAN;
- } else {
- ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
- }
- }
- if (match.isPresent(MatchType.DL_VLAN_PR)) {
- byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
- .getValue();
- if (!isIPv6) {
- ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
- wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
- } else {
- ((V6Match) ofMatch)
- .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
- (byte) 0);
- }
- }
- if (match.isPresent(MatchType.DL_TYPE)) {
- short ethType = (Short) match.getField(MatchType.DL_TYPE)
- .getValue();
- if (!isIPv6) {
- ofMatch.setDataLayerType(ethType);
- wildcards &= ~OFMatch.OFPFW_DL_TYPE;
- } else {
- ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
- }
- }
- if (match.isPresent(MatchType.NW_TOS)) {
- /*
- * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
- * actually the DSCP field followed by a zero ECN
- */
- byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
- byte dscp = (byte) (tos << 2);
- if (!isIPv6) {
- ofMatch.setNetworkTypeOfService(dscp);
- wildcards &= ~OFMatch.OFPFW_NW_TOS;
- } else {
- ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
- }
- }
- if (match.isPresent(MatchType.NW_PROTO)) {
- byte proto = (Byte) match.getField(MatchType.NW_PROTO)
- .getValue();
- if (!isIPv6) {
- ofMatch.setNetworkProtocol(proto);
- wildcards &= ~OFMatch.OFPFW_NW_PROTO;
- } else {
- ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
- }
- }
- if (match.isPresent(MatchType.NW_SRC)) {
- InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
- InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
- if (!isIPv6) {
- ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
- int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
- wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
- } else {
- ((V6Match) ofMatch).setNetworkSource(address, mask);
- }
- }
- if (match.isPresent(MatchType.NW_DST)) {
- InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
- InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
- if (!isIPv6) {
- ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
- int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
- wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
- } else {
- ((V6Match) ofMatch).setNetworkDestination(address, mask);
- }
- }
- if (match.isPresent(MatchType.TP_SRC)) {
- short port = (Short) match.getField(MatchType.TP_SRC)
- .getValue();
- if (!isIPv6) {
- ofMatch.setTransportSource(port);
- wildcards &= ~OFMatch.OFPFW_TP_SRC;
- } else {
- ((V6Match) ofMatch).setTransportSource(port, (short) 0);
- }
- }
- if (match.isPresent(MatchType.TP_DST)) {
- short port = (Short) match.getField(MatchType.TP_DST)
- .getValue();
- if (!isIPv6) {
- ofMatch.setTransportDestination(port);
- wildcards &= ~OFMatch.OFPFW_TP_DST;
- } else {
- ((V6Match) ofMatch)
- .setTransportDestination(port, (short) 0);
- }
- }
-
- if (!isIPv6) {
- ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
- }
- }
- logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
- ofMatch);
- return ofMatch;
- }
-
- /**
- * Returns the list of actions in OF 1.0 form
- *
- * @return
- */
- public List<OFAction> getOFActions() {
- if (this.actionsList == null) {
- actionsList = new ArrayList<OFAction>();
- for (Action action : flow.getActions()) {
- if (action.getType() == ActionType.OUTPUT) {
- Output a = (Output) action;
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setMaxLength((short) 0xffff);
- ofAction.setPort(PortConverter.toOFPort(a.getPort()));
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.DROP) {
- continue;
- }
- if (action.getType() == ActionType.LOOPBACK) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.FLOOD) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.FLOOD_ALL) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_ALL.getValue());
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.CONTROLLER) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
- // We want the whole frame hitting the match be sent to the
- // controller
- ofAction.setMaxLength((short) 0xffff);
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SW_PATH) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.HW_PATH) {
- OFActionOutput ofAction = new OFActionOutput();
- ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
- actionsList.add(ofAction);
- actionsLength += OFActionOutput.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_VLAN_ID) {
- SetVlanId a = (SetVlanId) action;
- OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
- ofAction.setVirtualLanIdentifier((short) a.getVlanId());
- actionsList.add(ofAction);
- actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_VLAN_PCP) {
- SetVlanPcp a = (SetVlanPcp) action;
- OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
- ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
- a.getPcp()).byteValue());
- actionsList.add(ofAction);
- actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.POP_VLAN) {
- OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
- actionsList.add(ofAction);
- actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_DL_SRC) {
- SetDlSrc a = (SetDlSrc) action;
- OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
- ofAction.setDataLayerAddress(a.getDlAddress());
- actionsList.add(ofAction);
- actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_DL_DST) {
- SetDlDst a = (SetDlDst) action;
- OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
- ofAction.setDataLayerAddress(a.getDlAddress());
- actionsList.add(ofAction);
- actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_NW_SRC) {
- SetNwSrc a = (SetNwSrc) action;
- OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
- ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
- .getAddress().getAddress()));
- actionsList.add(ofAction);
- actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_NW_DST) {
- SetNwDst a = (SetNwDst) action;
- OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
- ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
- .getAddress().getAddress()));
- actionsList.add(ofAction);
- actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_NW_TOS) {
- SetNwTos a = (SetNwTos) action;
- OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
- ofAction.setNetworkTypeOfService(Integer.valueOf(
- a.getNwTos()).byteValue());
- actionsList.add(ofAction);
- actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_TP_SRC) {
- SetTpSrc a = (SetTpSrc) action;
- OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
- ofAction.setTransportPort(Integer.valueOf(a.getPort())
- .shortValue());
- actionsList.add(ofAction);
- actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_TP_DST) {
- SetTpDst a = (SetTpDst) action;
- OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
- ofAction.setTransportPort(Integer.valueOf(a.getPort())
- .shortValue());
- actionsList.add(ofAction);
- actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
- continue;
- }
- if (action.getType() == ActionType.SET_NEXT_HOP) {
- logger.info("Unsupported action: {}", action);
- continue;
- }
- }
- }
- logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
- actionsList);
- return actionsList;
- }
-
- /**
- * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
- * IPv6 extension (V6FlowMod) Flow modifier Message
- *
- * @param sw
- * @param command
- * @param port
- * @return
- */
- public OFMessage getOFFlowMod(short command, OFPort port) {
- OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
- if (this.ofMatch == null) {
- getOFMatch();
- }
- if (this.actionsList == null) {
- getOFActions();
- }
- if (!isIPv6) {
- ((OFFlowMod) fm).setMatch(this.ofMatch);
- ((OFFlowMod) fm).setActions(this.actionsList);
- ((OFFlowMod) fm).setPriority(flow.getPriority());
- ((OFFlowMod) fm).setCookie(flow.getId());
- ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
- ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
- + actionsLength));
- ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
- ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
- ((OFFlowMod) fm).setCommand(command);
- if (port != null) {
- ((OFFlowMod) fm).setOutPort(port);
- }
- if (command == OFFlowMod.OFPFC_ADD
- || command == OFFlowMod.OFPFC_MODIFY
- || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
- if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
- // Instruct switch to let controller know when flow expires
- ((OFFlowMod) fm).setFlags((short) 1);
- }
- }
- } else {
- ((V6FlowMod) fm).setVendor();
- ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
- ((V6FlowMod) fm).setActions(this.actionsList);
- ((V6FlowMod) fm).setPriority(flow.getPriority());
- ((V6FlowMod) fm).setCookie(flow.getId());
- ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
- + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
- + ((V6Match) ofMatch).getIPv6MatchLen()
- + ((V6Match) ofMatch).getPadSize() + actionsLength));
- ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
- ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
- ((V6FlowMod) fm).setCommand(command);
- if (port != null) {
- ((V6FlowMod) fm).setOutPort(port);
- }
- if (command == OFFlowMod.OFPFC_ADD
- || command == OFFlowMod.OFPFC_MODIFY
- || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
- if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
- // Instruct switch to let controller know when flow expires
- ((V6FlowMod) fm).setFlags((short) 1);
- }
- }
- }
- logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
- actionsList);
- logger.trace("Openflow Mod Message: {}", fm);
- return fm;
- }
-
- public Flow getFlow(Node node) {
- if (this.flow == null) {
- Match salMatch = new Match();
-
- /*
- * Installed flow may not have a Match defined like in case of a
- * drop all flow
- */
- if (ofMatch != null) {
- if (!isIPv6) {
- // Compute OF1.0 Match
- if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
- salMatch.setField(new MatchField(MatchType.IN_PORT,
- NodeConnectorCreator.createNodeConnector(
- ofMatch.getInputPort(), node)));
- }
- if (ofMatch.getDataLayerSource() != null
- && !NetUtils
- .isZeroMAC(ofMatch.getDataLayerSource())) {
- byte srcMac[] = ofMatch.getDataLayerSource();
- salMatch.setField(new MatchField(MatchType.DL_SRC,
- srcMac.clone()));
- }
- if (ofMatch.getDataLayerDestination() != null
- && !NetUtils.isZeroMAC(ofMatch
- .getDataLayerDestination())) {
- byte dstMac[] = ofMatch.getDataLayerDestination();
- salMatch.setField(new MatchField(MatchType.DL_DST,
- dstMac.clone()));
- }
- if (ofMatch.getDataLayerType() != 0) {
- salMatch.setField(new MatchField(MatchType.DL_TYPE,
- ofMatch.getDataLayerType()));
- }
- short vlan = ofMatch.getDataLayerVirtualLan();
- if (vlan != 0) {
- if (vlan == OFP_VLAN_NONE) {
- vlan = MatchType.DL_VLAN_NONE;
- }
- salMatch.setField(new MatchField(MatchType.DL_VLAN,
- vlan));
- }
- if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
- salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
- .getDataLayerVirtualLanPriorityCodePoint());
- }
- if (ofMatch.getNetworkSource() != 0) {
- salMatch.setField(MatchType.NW_SRC, NetUtils
- .getInetAddress(ofMatch.getNetworkSource()),
- NetUtils.getInetNetworkMask(
- ofMatch.getNetworkSourceMaskLen(),
- false));
- }
- if (ofMatch.getNetworkDestination() != 0) {
- salMatch.setField(MatchType.NW_DST,
- NetUtils.getInetAddress(ofMatch
- .getNetworkDestination()),
- NetUtils.getInetNetworkMask(
- ofMatch.getNetworkDestinationMaskLen(),
- false));
- }
- if (ofMatch.getNetworkTypeOfService() != 0) {
- int dscp = NetUtils.getUnsignedByte(ofMatch
- .getNetworkTypeOfService());
- byte tos = (byte) (dscp >> 2);
- salMatch.setField(MatchType.NW_TOS, tos);
- }
- if (ofMatch.getNetworkProtocol() != 0) {
- salMatch.setField(MatchType.NW_PROTO,
- ofMatch.getNetworkProtocol());
- }
- if (ofMatch.getTransportSource() != 0) {
- salMatch.setField(MatchType.TP_SRC,
- ofMatch.getTransportSource());
- }
- if (ofMatch.getTransportDestination() != 0) {
- salMatch.setField(MatchType.TP_DST,
- ofMatch.getTransportDestination());
- }
- } else {
- // Compute OF1.0 + IPv6 extensions Match
- V6Match v6Match = (V6Match) ofMatch;
- if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
- // Mask on input port is not defined
- salMatch.setField(new MatchField(MatchType.IN_PORT,
- NodeConnectorCreator.createOFNodeConnector(
- v6Match.getInputPort(), node)));
- }
- if (v6Match.getDataLayerSource() != null
- && !NetUtils
- .isZeroMAC(ofMatch.getDataLayerSource())) {
- byte srcMac[] = v6Match.getDataLayerSource();
- salMatch.setField(new MatchField(MatchType.DL_SRC,
- srcMac.clone()));
- }
- if (v6Match.getDataLayerDestination() != null
- && !NetUtils.isZeroMAC(ofMatch
- .getDataLayerDestination())) {
- byte dstMac[] = v6Match.getDataLayerDestination();
- salMatch.setField(new MatchField(MatchType.DL_DST,
- dstMac.clone()));
- }
- if (v6Match.getDataLayerType() != 0) {
- salMatch.setField(new MatchField(MatchType.DL_TYPE,
- v6Match.getDataLayerType()));
- }
- short vlan = v6Match.getDataLayerVirtualLan();
- if (vlan != 0) {
- if (vlan == OFP_VLAN_NONE) {
- vlan = MatchType.DL_VLAN_NONE;
- }
- salMatch.setField(new MatchField(MatchType.DL_VLAN,
- vlan));
- }
- if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
- salMatch.setField(MatchType.DL_VLAN_PR, v6Match
- .getDataLayerVirtualLanPriorityCodePoint());
- }
- // V6Match may carry IPv4 address
- if (v6Match.getNetworkSrc() != null) {
- salMatch.setField(MatchType.NW_SRC,
- v6Match.getNetworkSrc(),
- v6Match.getNetworkSourceMask());
- } else if (v6Match.getNetworkSource() != 0) {
- salMatch.setField(MatchType.NW_SRC, NetUtils
- .getInetAddress(v6Match.getNetworkSource()),
- NetUtils.getInetNetworkMask(
- v6Match.getNetworkSourceMaskLen(),
- false));
- }
- // V6Match may carry IPv4 address
- if (v6Match.getNetworkDest() != null) {
- salMatch.setField(MatchType.NW_DST,
- v6Match.getNetworkDest(),
- v6Match.getNetworkDestinationMask());
- } else if (v6Match.getNetworkDestination() != 0) {
- salMatch.setField(MatchType.NW_DST,
- NetUtils.getInetAddress(v6Match
- .getNetworkDestination()),
- NetUtils.getInetNetworkMask(
- v6Match.getNetworkDestinationMaskLen(),
- false));
- }
- if (v6Match.getNetworkTypeOfService() != 0) {
- int dscp = NetUtils.getUnsignedByte(v6Match
- .getNetworkTypeOfService());
- byte tos = (byte) (dscp >> 2);
- salMatch.setField(MatchType.NW_TOS, tos);
- }
- if (v6Match.getNetworkProtocol() != 0) {
- salMatch.setField(MatchType.NW_PROTO,
- v6Match.getNetworkProtocol());
- }
- if (v6Match.getTransportSource() != 0) {
- salMatch.setField(MatchType.TP_SRC,
- (v6Match.getTransportSource()));
- }
- if (v6Match.getTransportDestination() != 0) {
- salMatch.setField(MatchType.TP_DST,
- (v6Match.getTransportDestination()));
- }
- }
- }
-
- // Convert actions
- Action salAction = null;
- List<Action> salActionList = new ArrayList<Action>();
- if (actionsList == null) {
- salActionList.add(new Drop());
- } else {
- for (OFAction ofAction : actionsList) {
- if (ofAction instanceof OFActionOutput) {
- short ofPort = ((OFActionOutput) ofAction).getPort();
- if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
- salAction = new Controller();
- } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
- salAction = new Drop();
- } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
- salAction = new Loopback();
- } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
- salAction = new Flood();
- } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
- salAction = new FloodAll();
- } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
- salAction = new SwPath();
- } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
- salAction = new HwPath();
- } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
- salAction = new HwPath(); // TODO: we do not handle
- // table in sal for now
- } else {
- salAction = new Output(
- NodeConnectorCreator.createOFNodeConnector(
- ofPort, node));
- }
- } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
- salAction = new SetVlanId(
- ((OFActionVirtualLanIdentifier) ofAction)
- .getVirtualLanIdentifier());
- } else if (ofAction instanceof OFActionStripVirtualLan) {
- salAction = new PopVlan();
- } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
- salAction = new SetVlanPcp(
- ((OFActionVirtualLanPriorityCodePoint) ofAction)
- .getVirtualLanPriorityCodePoint());
- } else if (ofAction instanceof OFActionDataLayerSource) {
- salAction = new SetDlSrc(
- ((OFActionDataLayerSource) ofAction)
- .getDataLayerAddress().clone());
- } else if (ofAction instanceof OFActionDataLayerDestination) {
- salAction = new SetDlDst(
- ((OFActionDataLayerDestination) ofAction)
- .getDataLayerAddress().clone());
- } else if (ofAction instanceof OFActionNetworkLayerSource) {
- byte addr[] = BigInteger.valueOf(
- ((OFActionNetworkLayerSource) ofAction)
- .getNetworkAddress()).toByteArray();
- InetAddress ip = null;
- try {
- ip = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {
- logger.error("", e);
- }
- salAction = new SetNwSrc(ip);
- } else if (ofAction instanceof OFActionNetworkLayerDestination) {
- byte addr[] = BigInteger.valueOf(
- ((OFActionNetworkLayerDestination) ofAction)
- .getNetworkAddress()).toByteArray();
- InetAddress ip = null;
- try {
- ip = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {
- logger.error("", e);
- }
- salAction = new SetNwDst(ip);
- } else if (ofAction instanceof OFActionNetworkTypeOfService) {
- salAction = new SetNwTos(
- ((OFActionNetworkTypeOfService) ofAction)
- .getNetworkTypeOfService());
- } else if (ofAction instanceof OFActionTransportLayerSource) {
- Short port = ((OFActionTransportLayerSource) ofAction)
- .getTransportPort();
- int intPort = NetUtils.getUnsignedShort(port);
- salAction = new SetTpSrc(intPort);
- } else if (ofAction instanceof OFActionTransportLayerDestination) {
- Short port = ((OFActionTransportLayerDestination) ofAction)
- .getTransportPort();
- int intPort = NetUtils.getUnsignedShort(port);
- salAction = new SetTpDst(intPort);
- }
- salActionList.add(salAction);
- }
- }
- // Create Flow
- flow = new Flow(salMatch, salActionList);
- }
- logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
- actionsList);
- logger.trace("SAL Flow: {}", flow);
- return flow;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService;
-import org.opendaylight.openflowplugin.openflow.IFlowProgrammerNotifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Flow Programmer Notifier class for relaying asynchronous messages received
- * from the network node to the listeners on the proper container
- */
-public class FlowProgrammerNotifier implements IFlowProgrammerNotifier {
- protected static final Logger logger = LoggerFactory
- .getLogger(FlowProgrammerNotifier.class);
- private IPluginOutFlowProgrammerService salNotifier;
- private IPluginOutConnectionService connectionOutService;
-
- public FlowProgrammerNotifier() {
- salNotifier = null;
- }
-
- void init(Component c) {
- logger.debug("INIT called!");
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- logger.debug("DESTROY called!");
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- logger.debug("START called!");
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- logger.debug("STOP called!");
- }
-
- public void setPluginOutFlowProgrammerService(
- IPluginOutFlowProgrammerService s) {
- this.salNotifier = s;
- }
-
- public void unsetPluginOutFlowProgrammerService(
- IPluginOutFlowProgrammerService s) {
- if (this.salNotifier == s) {
- this.salNotifier = null;
- }
- }
-
- @Override
- public void flowRemoved(Node node, Flow flow) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("flow removed will not be notified in a non-master controller for node "+node);
- return;
- }
-
- if (salNotifier != null) {
- salNotifier.flowRemoved(node, flow);
- } else {
- logger.warn("Unable to relay switch message to upper layer");
- }
- }
-
- @Override
- public void flowErrorReported(Node node, long rid, Object err) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("flow error will not be notified in a non-master controller for node "+node);
- return;
- }
-
- if (salNotifier != null) {
- salNotifier.flowErrorReported(node, rid, err);
- } else {
- logger.warn("Unable to relay switch error message to upper layer");
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Future;
-
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
-import org.opendaylight.controller.sal.match.Match;
-import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.openflowplugin.openflow.IFlowProgrammerNotifier;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents the openflow plugin component in charge of programming the flows
- * the flow programming and relay them to functional modules above SAL.
- */
-public class FlowProgrammerService implements IPluginInFlowProgrammerService, SalFlowService,
- IMessageListener, IContainerListener, IInventoryShimExternalListener,
- CommandProvider {
- private static final Logger log = LoggerFactory
- .getLogger(FlowProgrammerService.class);
- private IController controller;
- private ConcurrentMap<String, IFlowProgrammerNotifier> flowProgrammerNotifiers;
- private Map<String, Set<NodeConnector>> containerToNc;
- private ConcurrentMap<Long, Map<Integer, Long>> xid2rid;
- private int barrierMessagePriorCount = getBarrierMessagePriorCount();
- private IPluginOutConnectionService connectionOutService;
-
- public FlowProgrammerService() {
- controller = null;
- flowProgrammerNotifiers = new ConcurrentHashMap<String, IFlowProgrammerNotifier>();
- containerToNc = new HashMap<String, Set<NodeConnector>>();
- xid2rid = new ConcurrentHashMap<Long, Map<Integer, Long>>();
- }
-
- public void setController(IController core) {
- this.controller = core;
- }
-
- public void unsetController(IController core) {
- if (this.controller == core) {
- this.controller = null;
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- public void setFlowProgrammerNotifier(Map<String, ?> props,
- IFlowProgrammerNotifier s) {
- if (props == null || props.get("containerName") == null) {
- log.error("Didn't receive the service correct properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- this.flowProgrammerNotifiers.put(containerName, s);
- }
-
- public void unsetFlowProgrammerNotifier(Map<String, ?> props,
- IFlowProgrammerNotifier s) {
- if (props == null || props.get("containerName") == null) {
- log.error("Didn't receive the service correct properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (this.flowProgrammerNotifiers != null
- && this.flowProgrammerNotifiers.containsKey(containerName)
- && this.flowProgrammerNotifiers.get(containerName) == s) {
- this.flowProgrammerNotifiers.remove(containerName);
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- this.controller.addMessageListener(OFType.FLOW_REMOVED, this);
- this.controller.addMessageListener(OFType.ERROR, this);
- registerWithOSGIConsole();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- }
-
- @Override
- public Status addFlow(Node node, Flow flow) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Add flow will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return addFlowInternal(node, flow, 0);
- }
-
- @Override
- public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Modify flow will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return modifyFlowInternal(node, oldFlow, newFlow, 0);
- }
-
- @Override
- public Status removeFlow(Node node, Flow flow) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Remove flow will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return removeFlowInternal(node, flow, 0);
- }
-
- @Override
- public Status addFlowAsync(Node node, Flow flow, long rid) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Add flow Async will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return addFlowInternal(node, flow, rid);
- }
-
- @Override
- public Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow,
- long rid) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Modify flow async will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return modifyFlowInternal(node, oldFlow, newFlow, rid);
- }
-
- @Override
- public Status removeFlowAsync(Node node, Flow flow, long rid) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Remove flow async will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return removeFlowInternal(node, flow, rid);
- }
-
- private Status addFlowInternal(Node node, Flow flow, long rid) {
- String action = "add";
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
- action, "Invalid node type"));
- }
-
- if (controller != null) {
- ISwitch sw = controller.getSwitch((Long) node.getID());
- if (sw != null) {
- FlowConverter x = new FlowConverter(flow);
- OFMessage msg = x.getOFFlowMod(OFFlowMod.OFPFC_ADD, null);
-
- Object result;
- if (rid == 0) {
- /*
- * Synchronous message send. Each message is followed by a
- * Barrier message.
- */
- result = sw.syncSend(msg);
- } else {
- /*
- * Message will be sent asynchronously. A Barrier message
- * will be inserted automatically to synchronize the
- * progression.
- */
- result = asyncMsgSend(node, sw, msg, rid);
- }
- return getStatusInternal(result, action, rid);
- } else {
- return new Status(StatusCode.GONE, errorString("send", action,
- "Switch is not available"));
- }
- }
- return new Status(StatusCode.INTERNALERROR, errorString("send", action,
- "Internal plugin error"));
- }
-
- private Status modifyFlowInternal(Node node, Flow oldFlow, Flow newFlow, long rid) {
- String action = "modify";
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
- action, "Invalid node type"));
- }
- if (controller != null) {
- ISwitch sw = controller.getSwitch((Long) node.getID());
- if (sw != null) {
- OFMessage msg1 = null, msg2 = null;
-
- // If priority and match portion are the same, send a
- // modification message
- if (oldFlow.getPriority() != newFlow.getPriority()
- || !oldFlow.getMatch().equals(newFlow.getMatch())) {
- msg1 = new FlowConverter(oldFlow).getOFFlowMod(
- OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE);
- msg2 = new FlowConverter(newFlow).getOFFlowMod(
- OFFlowMod.OFPFC_ADD, null);
- } else {
- msg1 = new FlowConverter(newFlow).getOFFlowMod(
- OFFlowMod.OFPFC_MODIFY_STRICT, null);
- }
- /*
- * Synchronous message send
- */
- action = (msg2 == null) ? "modify" : "delete";
- Object result;
- if (rid == 0) {
- /*
- * Synchronous message send. Each message is followed by a
- * Barrier message.
- */
- result = sw.syncSend(msg1);
- } else {
- /*
- * Message will be sent asynchronously. A Barrier message
- * will be inserted automatically to synchronize the
- * progression.
- */
- result = asyncMsgSend(node, sw, msg1, rid);
- }
-
- Status rv = getStatusInternal(result, action, rid);
- if ((msg2 == null) || !rv.isSuccess()) {
- return rv;
- }
-
- action = "add";
- if (rid == 0) {
- /*
- * Synchronous message send. Each message is followed by a
- * Barrier message.
- */
- result = sw.syncSend(msg2);
- } else {
- /*
- * Message will be sent asynchronously. A Barrier message
- * will be inserted automatically to synchronize the
- * progression.
- */
- result = asyncMsgSend(node, sw, msg2, rid);
- }
- return getStatusInternal(result, action, rid);
- } else {
- return new Status(StatusCode.GONE, errorString("send", action,
- "Switch is not available"));
- }
- }
- return new Status(StatusCode.INTERNALERROR, errorString("send", action,
- "Internal plugin error"));
- }
-
- private Status removeFlowInternal(Node node, Flow flow, long rid) {
- String action = "remove";
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
- action, "Invalid node type"));
- }
- if (controller != null) {
- ISwitch sw = controller.getSwitch((Long) node.getID());
- if (sw != null) {
- OFMessage msg = new FlowConverter(flow).getOFFlowMod(
- OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE);
- Object result;
- if (rid == 0) {
- /*
- * Synchronous message send. Each message is followed by a
- * Barrier message.
- */
- result = sw.syncSend(msg);
- } else {
- /*
- * Message will be sent asynchronously. A Barrier message
- * will be inserted automatically to synchronize the
- * progression.
- */
- result = asyncMsgSend(node, sw, msg, rid);
- }
- return getStatusInternal(result, action, rid);
- } else {
- return new Status(StatusCode.GONE, errorString("send", action,
- "Switch is not available"));
- }
- }
- return new Status(StatusCode.INTERNALERROR, errorString("send", action,
- "Internal plugin error"));
- }
-
- @Override
- public Status removeAllFlows(Node node) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Remove all flows will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- return new Status(StatusCode.SUCCESS);
- }
-
- private String errorString(String phase, String action, String cause) {
- return "Failed to "
- + ((phase != null) ? phase + " the " + action
- + " flow message: " : action + " the flow: ") + cause;
- }
-
- @Override
- public void receive(ISwitch sw, OFMessage msg) {
- if (msg instanceof OFFlowRemoved) {
- handleFlowRemovedMessage(sw, (OFFlowRemoved) msg);
- } else if (msg instanceof OFError) {
- handleErrorMessage(sw, (OFError) msg);
- }
- }
-
- private void handleFlowRemovedMessage(ISwitch sw, OFFlowRemoved msg) {
- Node node = NodeCreator.createOFNode(sw.getId());
- Flow flow = new FlowConverter(msg.getMatch(),
- new ArrayList<OFAction>(0)).getFlow(node);
- flow.setPriority(msg.getPriority());
- flow.setIdleTimeout(msg.getIdleTimeout());
- flow.setId(msg.getCookie());
-
- Match match = flow.getMatch();
- NodeConnector inPort = match.isPresent(MatchType.IN_PORT) ? (NodeConnector) match
- .getField(MatchType.IN_PORT).getValue() : null;
-
- for (Map.Entry<String, IFlowProgrammerNotifier> containerNotifier : flowProgrammerNotifiers
- .entrySet()) {
- String container = containerNotifier.getKey();
- IFlowProgrammerNotifier notifier = containerNotifier.getValue();
- /*
- * Switch only provide us with the match information. For now let's
- * try to identify the container membership only from the input port
- * match field. In any case, upper layer consumers can derive
- * whether the notification was not for them. More sophisticated
- * filtering can be added later on.
- */
- if (inPort == null
- || container.equals(GlobalConstants.DEFAULT.toString())
- || this.containerToNc.get(container).contains(inPort)) {
- notifier.flowRemoved(node, flow);
- }
- }
- }
-
- private void handleErrorMessage(ISwitch sw, OFError errorMsg) {
- Node node = NodeCreator.createOFNode(sw.getId());
- OFMessage offendingMsg = errorMsg.getOffendingMsg();
- Integer xid;
- if (offendingMsg != null) {
- xid = offendingMsg.getXid();
- } else {
- xid = errorMsg.getXid();
- }
-
- Long rid = getMessageRid(sw.getId(), xid);
- /*
- * Null or zero requestId indicates that the error message is meant for
- * a sync message. It will be handled by the sync message worker thread.
- * Hence we are done here.
- */
- if ((rid == null) || (rid == 0)) {
- return;
- }
-
- /*
- * Notifies the caller that error has been reported for a previous flow
- * programming request
- */
- for (Map.Entry<String, IFlowProgrammerNotifier> containerNotifier : flowProgrammerNotifiers
- .entrySet()) {
- IFlowProgrammerNotifier notifier = containerNotifier.getValue();
- notifier.flowErrorReported(node, rid, errorMsg);
- }
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag,
- short newTag, UpdateType t) {
-
- }
-
- @Override
- public void containerFlowUpdated(String containerName,
- ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t) {
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p,
- UpdateType type) {
- Set<NodeConnector> target = null;
-
- switch (type) {
- case ADDED:
- if (!containerToNc.containsKey(containerName)) {
- containerToNc.put(containerName, new HashSet<NodeConnector>());
- }
- containerToNc.get(containerName).add(p);
- break;
- case CHANGED:
- break;
- case REMOVED:
- target = containerToNc.get(containerName);
- if (target != null) {
- target.remove(p);
- }
- break;
- default:
- }
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
-
- }
-
- @Override
- public Status syncSendBarrierMessage(Node node) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("Sync Send Barrier will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- return new Status(StatusCode.NOTACCEPTABLE,
- "The node does not support Barrier message.");
- }
-
- if (controller != null) {
- long swid = (Long) node.getID();
- ISwitch sw = controller.getSwitch(swid);
- if (sw != null) {
- sw.syncSendBarrierMessage();
- clearXid2Rid(swid);
- return (new Status(StatusCode.SUCCESS));
- } else {
- return new Status(StatusCode.GONE,
- "The node does not have a valid Switch reference.");
- }
- }
- return new Status(StatusCode.INTERNALERROR,
- "Failed to send Barrier message.");
- }
-
- @Override
- public Status asyncSendBarrierMessage(Node node) {
- if (!connectionOutService.isLocal(node)) {
- log.debug("ASync Send Barrier will not be processed in a non-master controller for node " + node);
- return new Status(StatusCode.NOTALLOWED, "This is not the master controller for " + node);
- }
-
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- return new Status(StatusCode.NOTACCEPTABLE,
- "The node does not support Barrier message.");
- }
-
- if (controller != null) {
- long swid = (Long) node.getID();
- ISwitch sw = controller.getSwitch(swid);
- if (sw != null) {
- sw.asyncSendBarrierMessage();
- clearXid2Rid(swid);
- return (new Status(StatusCode.SUCCESS));
- } else {
- return new Status(StatusCode.GONE,
- "The node does not have a valid Switch reference.");
- }
- }
- return new Status(StatusCode.INTERNALERROR,
- "Failed to send Barrier message.");
- }
-
- /**
- * This method sends the message asynchronously until the number of messages
- * sent reaches a threshold. Then a Barrier message is sent automatically
- * for sync purpose. An unique Request ID associated with the message is
- * passed down by the caller. The Request ID will be returned to the caller
- * when an error message is received from the switch.
- *
- * @param node
- * The node
- * @param msg
- * The switch
- * @param msg
- * The OF message to be sent
- * @param rid
- * The Request Id
- * @return result
- */
- private Object asyncMsgSend(Node node, ISwitch sw, OFMessage msg, long rid) {
- Object result = Boolean.TRUE;
- long swid = (Long) node.getID();
- int xid;
-
- xid = sw.asyncSend(msg);
- addXid2Rid(swid, xid, rid);
-
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- if (swxid2rid == null) {
- return result;
- }
-
- int size = swxid2rid.size();
- if (size % barrierMessagePriorCount == 0) {
- result = asyncSendBarrierMessage(node);
- }
-
- return result;
- }
-
- /**
- * A number of async messages are sent followed by a synchronous Barrier
- * message. This method returns the maximum async messages that can be sent
- * before the Barrier message.
- *
- * @return The max count of async messages sent prior to Barrier message
- */
- private int getBarrierMessagePriorCount() {
- String count = System.getProperty("of.barrierMessagePriorCount");
- int rv = 100;
-
- if (count != null) {
- try {
- rv = Integer.parseInt(count);
- } catch (Exception e) {
- }
- }
-
- return rv;
- }
-
- /**
- * This method returns the message Request ID previously assigned by the
- * caller for a given OF message xid
- *
- * @param swid
- * The switch id
- * @param xid
- * The OF message xid
- * @return The Request ID
- */
- private Long getMessageRid(long swid, Integer xid) {
- Long rid = null;
-
- if (xid == null) {
- return rid;
- }
-
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- if (swxid2rid != null) {
- rid = swxid2rid.get(xid);
- }
- return rid;
- }
-
- /**
- * This method returns a copy of outstanding xid to rid mappings.for a given
- * switch
- *
- * @param swid
- * The switch id
- * @return a copy of xid2rid mappings
- */
- public Map<Integer, Long> getSwXid2Rid(long swid) {
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
-
- if (swxid2rid != null) {
- return new HashMap<Integer, Long>(swxid2rid);
- } else {
- return new HashMap<Integer, Long>();
- }
- }
-
- /**
- * Adds xid to rid mapping to the local DB
- *
- * @param swid
- * The switch id
- * @param xid
- * The OF message xid
- * @param rid
- * The message Request ID
- */
- private void addXid2Rid(long swid, int xid, long rid) {
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- if (swxid2rid != null) {
- swxid2rid.put(xid, rid);
- }
- }
-
- /**
- * When an Error message is received, this method will be invoked to remove
- * the offending xid from the local DB.
- *
- * @param swid
- * The switch id
- * @param xid
- * The OF message xid
- */
- private void removeXid2Rid(long swid, int xid) {
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- if (swxid2rid != null) {
- swxid2rid.remove(xid);
- }
- }
-
- /**
- * Convert various result into Status
- *
- * @param result
- * The returned result from previous action
- * @param action
- * add/modify/delete flow action
- * @param rid
- * The Request ID associated with the flow message
- * @return Status
- */
- private Status getStatusInternal(Object result, String action, long rid) {
- if (result instanceof Boolean) {
- return ((Boolean) result == Boolean.TRUE) ? new Status(
- StatusCode.SUCCESS, rid) : new Status(
- StatusCode.TIMEOUT, errorString(null, action,
- "Request Timed Out"));
- } else if (result instanceof Status) {
- return (Status) result;
- } else if (result instanceof OFError) {
- OFError res = (OFError) result;
- return new Status(StatusCode.INTERNALERROR, errorString(
- "program", action, Utils.getOFErrorString(res)));
- } else {
- return new Status(StatusCode.INTERNALERROR, errorString(
- "send", action, "Internal Error"));
- }
- }
-
- /**
- * When a Barrier reply is received, this method will be invoked to clear
- * the local DB
- *
- * @param swid
- * The switch id
- */
- private void clearXid2Rid(long swid) {
- Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- if (swxid2rid != null) {
- swxid2rid.clear();
- }
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- long swid = (Long)node.getID();
-
- switch (type) {
- case ADDED:
- Map<Integer, Long> swxid2rid = new HashMap<Integer, Long>();
- this.xid2rid.put(swid, swxid2rid);
- break;
- case CHANGED:
- break;
- case REMOVED:
- this.xid2rid.remove(swid);
- break;
- default:
- }
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
- .getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this,
- null);
- }
-
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("-- Flow Programmer Service --\n");
- help.append("\t px2r <node id> - Print outstanding xid2rid mappings for a given node id\n");
- help.append("\t px2rc - Print max num of async msgs prior to the Barrier\n");
- return help.toString();
- }
-
- public void _px2r(CommandInterpreter ci) {
- String st = ci.nextArgument();
- if (st == null) {
- ci.println("Please enter a valid node id");
- return;
- }
-
- long sid;
- try {
- sid = HexEncode.stringToLong(st);
- } catch (NumberFormatException e) {
- ci.println("Please enter a valid node id");
- return;
- }
-
- Map<Integer, Long> swxid2rid = this.xid2rid.get(sid);
- if (swxid2rid == null) {
- ci.println("The node id entered does not exist");
- return;
- }
-
- ci.println("xid rid");
-
- Set<Integer> xidSet = swxid2rid.keySet();
- if (xidSet == null) {
- return;
- }
-
- for (Integer xid : xidSet) {
- ci.println(xid + " " + swxid2rid.get(xid));
- }
- }
-
- public void _px2rc(CommandInterpreter ci) {
- ci.println("Max num of async messages sent prior to the Barrier message is "
- + barrierMessagePriorCount);
- }
-
-
-
- @Override
- public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
- throw new UnsupportedOperationException("Not implemented yet.");
- }
-
-
- @Override
- public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
- throw new UnsupportedOperationException("Not implemented yet.");
- }
-
- @Override
- public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
- throw new UnsupportedOperationException("Not implemented yet.");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.reader.FlowOnNode;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6StatsReply;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Converts an openflow list of flow statistics in a SAL list of FlowOnNode
- * objects
- *
- *
- *
- */
-public class FlowStatisticsConverter {
- private static final Logger log = LoggerFactory
- .getLogger(FlowStatisticsConverter.class);
- private List<OFStatistics> ofStatsList;
- private List<FlowOnNode> flowOnNodeList;
-
- public FlowStatisticsConverter(List<OFStatistics> statsList) {
- if (statsList == null) {// || statsList.isEmpty()) {
- this.ofStatsList = new ArrayList<OFStatistics>(1); // dummy list
- } else {
- this.ofStatsList = statsList; // new
- // ArrayList<OFStatistics>(statsList);
- }
- this.flowOnNodeList = null;
- }
-
- public List<FlowOnNode> getFlowOnNodeList(Node node) {
- if (ofStatsList != null && flowOnNodeList == null) {
- flowOnNodeList = new ArrayList<FlowOnNode>();
- FlowConverter flowConverter = null;
- OFFlowStatisticsReply ofFlowStat;
- V6StatsReply v6StatsReply;
- for (OFStatistics ofStat : ofStatsList) {
- FlowOnNode flowOnNode = null;
- if (ofStat instanceof OFFlowStatisticsReply) {
- ofFlowStat = (OFFlowStatisticsReply) ofStat;
- flowConverter = new FlowConverter(ofFlowStat.getMatch(),
- ofFlowStat.getActions());
- Flow flow = flowConverter.getFlow(node);
- flow.setPriority(ofFlowStat.getPriority());
- flow.setIdleTimeout(ofFlowStat.getIdleTimeout());
- flow.setHardTimeout(ofFlowStat.getHardTimeout());
- flowOnNode = new FlowOnNode(flow);
- flowOnNode.setByteCount(ofFlowStat.getByteCount());
- flowOnNode.setPacketCount(ofFlowStat.getPacketCount());
- flowOnNode.setDurationSeconds(ofFlowStat
- .getDurationSeconds());
- flowOnNode.setDurationNanoseconds(ofFlowStat
- .getDurationNanoseconds());
- } else if (ofStat instanceof V6StatsReply) {
- v6StatsReply = (V6StatsReply) ofStat;
- flowConverter = new FlowConverter(v6StatsReply.getMatch(),
- v6StatsReply.getActions());
- Flow flow = flowConverter.getFlow(node);
- flow.setPriority(v6StatsReply.getPriority());
- flow.setIdleTimeout(v6StatsReply.getIdleTimeout());
- flow.setHardTimeout(v6StatsReply.getHardTimeout());
- flowOnNode = new FlowOnNode(flow);
- flowOnNode.setByteCount(v6StatsReply.getByteCount());
- flowOnNode.setPacketCount(v6StatsReply.getPacketCount());
- flowOnNode.setDurationSeconds(v6StatsReply
- .getDurationSeconds());
- flowOnNode.setDurationNanoseconds(v6StatsReply
- .getDurationNanoseconds());
- } else {
- continue;
- }
- flowOnNodeList.add(flowOnNode);
- }
- }
- log.trace("OFStatistics: {} FlowOnNode: {}", ofStatsList,
- flowOnNodeList);
- return flowOnNodeList;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.openflowplugin.openflow.IInventoryProvider;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimInternalListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The class describes inventory service protocol plugin. One instance per
- * container of the network. Each instance gets container specific inventory
- * events from InventoryServiceShim. It interacts with SAL to pass inventory
- * data to the upper application.
- *
- *
- */
-public class InventoryService implements IInventoryShimInternalListener,
- IPluginInInventoryService, IInventoryProvider {
- protected static final Logger logger = LoggerFactory
- .getLogger(InventoryService.class);
- private Set<IPluginOutInventoryService> pluginOutInventoryServices;
- private IController controller = null;
- private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
- private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
- private boolean isDefaultContainer = false;
- private String containerName = null;
-
- void setController(IController s) {
- this.controller = s;
- }
-
- void unsetController(IController s) {
- if (this.controller == s) {
- this.controller = null;
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- @SuppressWarnings("rawtypes")
- void init(Component c) {
- logger.trace("INIT called!");
-
- Dictionary props = c.getServiceProperties();
- if (props != null) {
- containerName = (String) props.get("containerName");
- if (containerName != null) {
- isDefaultContainer = containerName.equals(GlobalConstants.DEFAULT
- .toString());
- }
- }
-
- nodeProps = new ConcurrentHashMap<Node, Map<String, Property>>();
- nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Map<String, Property>>();
- pluginOutInventoryServices = new CopyOnWriteArraySet<IPluginOutInventoryService>();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- logger.trace("DESTROY called!");
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- logger.trace("START called!");
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- logger.trace("STOP called!");
- }
-
- public void setPluginOutInventoryServices(IPluginOutInventoryService service) {
- logger.trace("Got a service set request {}", service);
- if (this.pluginOutInventoryServices != null) {
- this.pluginOutInventoryServices.add(service);
- }
- }
-
- public void unsetPluginOutInventoryServices(
- IPluginOutInventoryService service) {
- logger.trace("Got a service UNset request");
- if (this.pluginOutInventoryServices != null) {
- this.pluginOutInventoryServices.remove(service);
- }
- }
-
- /**
- * Retrieve nodes from openflow
- */
- @Override
- public ConcurrentMap<Node, Map<String, Property>> getNodeProps() {
- logger.debug("getNodePros for container {}", containerName);
- return nodeProps;
- }
-
- @Override
- public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps(
- Boolean refresh) {
- if (nodeConnectorProps == null) {
- return null;
- }
-
- if (isDefaultContainer && refresh) {
- Map<Long, ISwitch> switches = controller.getSwitches();
- for (ISwitch sw : switches.values()) {
- Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
- .OFSwitchToProps(sw);
- for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps
- .entrySet()) {
- updateNodeConnector(entry.getKey(), UpdateType.ADDED,
- entry.getValue());
- }
- }
- }
-
- return nodeConnectorProps;
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- logger.trace("updateNodeConnector {} type {}", nodeConnector,
- type.getName());
- if (nodeConnectorProps == null) {
- logger.trace("nodeConnectorProps is null");
- return;
- }
-
- Map<String, Property> propMap = nodeConnectorProps.get(nodeConnector);
- switch (type) {
- case ADDED:
- case CHANGED:
- if (propMap == null) {
- propMap = new HashMap<String, Property>();
- }
- if (props != null) {
- for (Property prop : props) {
- propMap.put(prop.getName(), prop);
- }
- }
- nodeConnectorProps.put(nodeConnector, propMap);
- break;
- case REMOVED:
- nodeConnectorProps.remove(nodeConnector);
- break;
- default:
- return;
- }
-
- // update sal and discovery
- for (IPluginOutInventoryService service : pluginOutInventoryServices) {
- service.updateNodeConnector(nodeConnector, type, props);
- }
-
- }
-
- private void addNode(Node node, Set<Property> props) {
- if (nodeProps == null) {
- return;
- }
-
- logger.trace("addNode: {} added, props: {} for container {}",
- new Object[] { node, props, containerName });
-
- // update local cache
- Map<String, Property> propMap = nodeProps.get(node);
- if (propMap == null) {
- propMap = new HashMap<String, Property>();
- }
-
- if (props != null) {
- for (Property prop : props) {
- propMap.put(prop.getName(), prop);
- }
- }
- nodeProps.put(node, propMap);
-
- // update sal
- for (IPluginOutInventoryService service : pluginOutInventoryServices) {
- service.updateNode(node, UpdateType.ADDED, props);
- }
- }
-
- private void removeNode(Node node) {
- logger.trace("{} removed", node);
- if (nodeProps == null)
- return;
-
- // update local cache
- nodeProps.remove(node);
-
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
- if (nodeConnector.getNode().equals(node)) {
- removeSet.add(nodeConnector);
- }
- }
- for (NodeConnector nodeConnector : removeSet) {
- nodeConnectorProps.remove(nodeConnector);
- }
-
- // update sal
- for (IPluginOutInventoryService service : pluginOutInventoryServices) {
- service.updateNode(node, UpdateType.REMOVED, null);
- }
- }
-
- private void updateNode(Node node, Set<Property> properties) {
- logger.trace("{} updated, props: {}", node, properties);
- if (nodeProps == null || !nodeProps.containsKey(node) ||
- properties == null || properties.isEmpty()) {
- return;
- }
-
- // Update local cache with new properties
- Set<Property> newProperties = new HashSet<Property>(properties.size());
- Map<String, Property> propertyMap = nodeProps.get(node);
- for (Property property : properties) {
- String name = property.getName();
- Property currentProperty = propertyMap.get(name);
- if (!property.equals(currentProperty)) {
- propertyMap.put(name, property);
- newProperties.add(property);
- }
- }
-
- // Update SAL if we got new properties
- if (!newProperties.isEmpty()) {
- for (IPluginOutInventoryService service : pluginOutInventoryServices) {
- service.updateNode(node, UpdateType.CHANGED, newProperties);
- }
- }
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- switch (type) {
- case ADDED:
- addNode(node, props);
- break;
- case REMOVED:
- removeNode(node);
- break;
- case CHANGED:
- updateNode(node, props);
- break;
- default:
- break;
- }
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.core.Bandwidth;
-import org.opendaylight.controller.sal.core.AdvertisedBandwidth;
-import org.opendaylight.controller.sal.core.SupportedBandwidth;
-import org.opendaylight.controller.sal.core.PeerBandwidth;
-import org.opendaylight.controller.sal.core.Config;
-import org.opendaylight.controller.sal.core.Name;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.State;
-
-import org.opendaylight.controller.sal.utils.NodeCreator;
-
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
-import org.openflow.protocol.OFPhysicalPort.OFPortFeatures;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-
-/**
- * The class provides helper functions to retrieve inventory properties from
- * OpenFlow messages
- */
-public class InventoryServiceHelper {
- /*
- * Returns BandWidth property from OpenFlow OFPhysicalPort features
- */
- public static Bandwidth OFPortToBandWidth(int portFeatures) {
- Bandwidth bw = null;
- int value = portFeatures
- & (OFPortFeatures.OFPPF_10MB_FD.getValue()
- | OFPortFeatures.OFPPF_10MB_HD.getValue()
- | OFPortFeatures.OFPPF_100MB_FD.getValue()
- | OFPortFeatures.OFPPF_100MB_HD.getValue()
- | OFPortFeatures.OFPPF_1GB_FD.getValue()
- | OFPortFeatures.OFPPF_1GB_HD.getValue() | OFPortFeatures.OFPPF_10GB_FD
- .getValue());
-
- switch (value) {
- case 1:
- case 2:
- bw = new Bandwidth(Bandwidth.BW10Mbps);
- break;
- case 4:
- case 8:
- bw = new Bandwidth(Bandwidth.BW100Mbps);
- break;
- case 16:
- case 32:
- bw = new Bandwidth(Bandwidth.BW1Gbps);
- break;
- case 64:
- bw = new Bandwidth(Bandwidth.BW10Gbps);
- break;
- default:
- break;
- }
- return bw;
- }
-
- /*
- * Returns Config property from OpenFLow OFPhysicalPort config
- */
- public static Config OFPortToConfig(int portConfig) {
- Config config;
- if ((OFPortConfig.OFPPC_PORT_DOWN.getValue() & portConfig) != 0)
- config = new Config(Config.ADMIN_DOWN);
- else
- config = new Config(Config.ADMIN_UP);
- return config;
- }
-
- /*
- * Returns State property from OpenFLow OFPhysicalPort state
- */
- public static State OFPortToState(int portState) {
- State state;
- if ((OFPortState.OFPPS_LINK_DOWN.getValue() & portState) != 0)
- state = new State(State.EDGE_DOWN);
- else
- state = new State(State.EDGE_UP);
- return state;
- }
-
- /*
- * Returns set of properties from OpenFLow OFPhysicalPort
- */
- public static Set<Property> OFPortToProps(OFPhysicalPort port) {
- Set<Property> props = new HashSet<Property>();
- Bandwidth bw = InventoryServiceHelper.OFPortToBandWidth(port
- .getCurrentFeatures());
- if (bw != null) {
- props.add(bw);
- }
-
- Bandwidth abw = InventoryServiceHelper.OFPortToBandWidth(port.getAdvertisedFeatures());
- if (abw != null) {
- AdvertisedBandwidth a = new AdvertisedBandwidth(abw.getValue());
- if (a != null) {
- props.add(a);
- }
- }
- Bandwidth sbw = InventoryServiceHelper.OFPortToBandWidth(port.getSupportedFeatures());
- if (sbw != null) {
- SupportedBandwidth s = new SupportedBandwidth(sbw.getValue());
- if (s != null) {
- props.add(s);
- }
- }
- Bandwidth pbw = InventoryServiceHelper.OFPortToBandWidth(port.getPeerFeatures());
- if (pbw != null) {
- PeerBandwidth p = new PeerBandwidth(pbw.getValue());
- if (p != null) {
- props.add(p);
- }
- }
- props.add(new Name(port.getName()));
- props.add(InventoryServiceHelper.OFPortToConfig(port.getConfig()));
- props.add(InventoryServiceHelper.OFPortToState(port.getState()));
- return props;
- }
-
- /*
- * Returns set of properties for each nodeConnector in an OpenFLow switch
- */
- public static Map<NodeConnector, Set<Property>> OFSwitchToProps(ISwitch sw) {
- Map<NodeConnector, Set<Property>> ncProps = new HashMap<NodeConnector, Set<Property>>();
-
- if (sw == null) {
- return ncProps;
- }
-
- Node node = NodeCreator.createOFNode(sw.getId());
- if (node == null) {
- return ncProps;
- }
-
- Set<Property> props;
- NodeConnector nodeConnector;
- OFPhysicalPort port;
- Map<Short, OFPhysicalPort> ports = sw.getPhysicalPorts();
- for (Map.Entry<Short, OFPhysicalPort> entry : ports.entrySet()) {
- nodeConnector = PortConverter.toNodeConnector(entry.getKey(), node);
- port = entry.getValue();
- props = InventoryServiceHelper.OFPortToProps(port);
- ncProps.put(nodeConnector, props);
- }
-
- return ncProps;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Actions;
-import org.opendaylight.controller.sal.core.Buffers;
-import org.opendaylight.controller.sal.core.Capabilities;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.Description;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.MacAddress;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.Tables;
-import org.opendaylight.controller.sal.core.TimeStamp;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimInternalListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.IMessageListener;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.opendaylight.openflowplugin.openflow.core.ISwitchStateListener;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.statistics.OFDescriptionStatistics;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The class describes a shim layer that bridges inventory events from Openflow
- * core to various listeners. The notifications are filtered based on container
- * configurations.
- *
- *
- */
-public class InventoryServiceShim implements IContainerListener,
- IMessageListener, ISwitchStateListener, IOFStatisticsListener {
- protected static final Logger logger = LoggerFactory
- .getLogger(InventoryServiceShim.class);
- private IController controller = null;
- private final ConcurrentMap<String, IInventoryShimInternalListener> inventoryShimInternalListeners = new ConcurrentHashMap<String, IInventoryShimInternalListener>();
- private final Set<IInventoryShimInternalListener> globalInventoryShimInternalListeners = new HashSet<IInventoryShimInternalListener>();
- private final List<IInventoryShimExternalListener> inventoryShimExternalListeners = new CopyOnWriteArrayList<IInventoryShimExternalListener>();
- private final ConcurrentMap<NodeConnector, Set<String>> nodeConnectorContainerMap = new ConcurrentHashMap<NodeConnector, Set<String>>();
- private final ConcurrentMap<Node, Set<String>> nodeContainerMap = new ConcurrentHashMap<Node, Set<String>>();
- private final ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Set<Property>>();
- private final ConcurrentMap<Node, Set<Property>> nodeProps = new ConcurrentHashMap<Node, Set<Property>>();
- private IPluginOutConnectionService connectionOutService;
-
- void setController(IController s) {
- this.controller = s;
- }
-
- void unsetController(IController s) {
- if (this.controller == s) {
- this.controller = null;
- }
- }
-
- void setInventoryShimGlobalInternalListener(Map<?, ?> props,
- IInventoryShimInternalListener s) {
- if ((this.globalInventoryShimInternalListeners != null)) {
- this.globalInventoryShimInternalListeners.add(s);
- }
- }
-
- void unsetInventoryShimGlobalInternalListener(Map<?, ?> props,
- IInventoryShimInternalListener s) {
- if ((this.globalInventoryShimInternalListeners != null)) {
- this.globalInventoryShimInternalListeners.remove(s);
- }
- }
-
- void setInventoryShimInternalListener(Map<?, ?> props,
- IInventoryShimInternalListener s) {
- if (props == null) {
- logger.error("setInventoryShimInternalListener property is null");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("setInventoryShimInternalListener containerName not supplied");
- return;
- }
- if ((this.inventoryShimInternalListeners != null)
- && !this.inventoryShimInternalListeners.containsValue(s)) {
- this.inventoryShimInternalListeners.put(containerName, s);
- logger.trace(
- "Added inventoryShimInternalListener for container {}",
- containerName);
- }
- }
-
- void unsetInventoryShimInternalListener(Map<?, ?> props,
- IInventoryShimInternalListener s) {
- if (props == null) {
- logger.error("unsetInventoryShimInternalListener property is null");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("setInventoryShimInternalListener containerName not supplied");
- return;
- }
- if ((this.inventoryShimInternalListeners != null)
- && this.inventoryShimInternalListeners.get(containerName) != null
- && this.inventoryShimInternalListeners.get(containerName)
- .equals(s)) {
- this.inventoryShimInternalListeners.remove(containerName);
- logger.trace(
- "Removed inventoryShimInternalListener for container {}",
- containerName);
- }
- }
-
- void setInventoryShimExternalListener(IInventoryShimExternalListener s) {
- logger.trace("Set inventoryShimExternalListener");
- if ((this.inventoryShimExternalListeners != null)
- && !this.inventoryShimExternalListeners.contains(s)) {
- this.inventoryShimExternalListeners.add(s);
- }
- }
-
- void unsetInventoryShimExternalListener(IInventoryShimExternalListener s) {
- if ((this.inventoryShimExternalListeners != null)
- && this.inventoryShimExternalListeners.contains(s)) {
- this.inventoryShimExternalListeners.remove(s);
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- this.controller.addMessageListener(OFType.PORT_STATUS, this);
- this.controller.addSwitchStateListener(this);
- }
-
- /**
- * Function called after registering the service in OSGi service registry.
- */
- void started() {
- /* Start with existing switches */
- startService();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- this.controller.removeMessageListener(OFType.PACKET_IN, this);
- this.controller.removeSwitchStateListener(this);
-
- this.inventoryShimInternalListeners.clear();
- this.nodeConnectorContainerMap.clear();
- this.nodeContainerMap.clear();
- this.globalInventoryShimInternalListeners.clear();
- this.controller = null;
- }
-
- @Override
- public void receive(ISwitch sw, OFMessage msg) {
- if (msg instanceof OFPortStatus) {
- handlePortStatusMessage(sw, (OFPortStatus) msg);
- }
- return;
- }
-
- protected void handlePortStatusMessage(ISwitch sw, OFPortStatus m) {
- Node node = NodeCreator.createOFNode(sw.getId());
- NodeConnector nodeConnector = PortConverter.toNodeConnector(
- m.getDesc().getPortNumber(), node);
- // get node connector properties
- Set<Property> props = InventoryServiceHelper.OFPortToProps(m.getDesc());
-
- UpdateType type = null;
- if (m.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
- type = UpdateType.ADDED;
- nodeConnectorProps.put(nodeConnector, props);
- } else if (m.getReason() == (byte) OFPortReason.OFPPR_DELETE.ordinal()) {
- type = UpdateType.REMOVED;
- nodeConnectorProps.remove(nodeConnector);
- } else if (m.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
- type = UpdateType.CHANGED;
- nodeConnectorProps.put(nodeConnector, props);
- }
-
- logger.trace("handlePortStatusMessage {} type {}", nodeConnector, type);
-
- if (type != null) {
- notifyInventoryShimListener(nodeConnector, type, props);
- }
- }
-
- @Override
- public void switchAdded(ISwitch sw) {
- if (sw == null) {
- return;
- }
-
- // Add all the nodeConnectors of this switch
- Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
- .OFSwitchToProps(sw);
- for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps.entrySet()) {
- Set<Property> props = new HashSet<Property>();
- Set<Property> prop = entry.getValue();
- if (prop != null) {
- props.addAll(prop);
- }
- nodeConnectorProps.put(entry.getKey(), props);
- notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED,
- entry.getValue());
- }
-
- // Add this node
- addNode(sw);
- }
-
- @Override
- public void switchDeleted(ISwitch sw) {
- if (sw == null) {
- return;
- }
-
- removeNode(sw);
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // do nothing
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag,
- short newTag, UpdateType t) {
- logger.debug("tagUpdated: {} type {} for container {}", new Object[] {
- n, t, containerName });
- }
-
- @Override
- public void containerFlowUpdated(String containerName,
- ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t) {
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector nc, UpdateType t) {
- logger.debug("nodeConnectorUpdated: {} type {} for container {}", new Object[] { nc, t, containerName });
- Node node = nc.getNode();
- Set<String> ncContainers = this.nodeConnectorContainerMap.get(nc);
- Set<String> nodeContainers = this.nodeContainerMap.get(node);
- if (ncContainers == null) {
- ncContainers = new CopyOnWriteArraySet<String>();
- }
- if (nodeContainers == null) {
- nodeContainers = new CopyOnWriteArraySet<String>();
- }
- boolean notifyNodeUpdate = false;
-
- switch (t) {
- case ADDED:
- if (ncContainers.add(containerName)) {
- this.nodeConnectorContainerMap.put(nc, ncContainers);
- }
- if (nodeContainers.add(containerName)) {
- this.nodeContainerMap.put(node, nodeContainers);
- notifyNodeUpdate = true;
- }
- break;
- case REMOVED:
- if (ncContainers.remove(containerName)) {
- if (ncContainers.isEmpty()) {
- // Do cleanup to reduce memory footprint if no
- // elements to be tracked
- this.nodeConnectorContainerMap.remove(nc);
- } else {
- this.nodeConnectorContainerMap.put(nc, ncContainers);
- }
- }
- boolean nodeContainerUpdate = true;
- for (NodeConnector ncContainer : nodeConnectorContainerMap.keySet()) {
- if ((ncContainer.getNode().equals(node)) && (nodeConnectorContainerMap.get(ncContainer).contains(containerName))) {
- nodeContainerUpdate = false;
- break;
- }
- }
- if (nodeContainerUpdate) {
- nodeContainers.remove(containerName);
- notifyNodeUpdate = true;
- if (nodeContainers.isEmpty()) {
- this.nodeContainerMap.remove(node);
- } else {
- this.nodeContainerMap.put(node, nodeContainers);
- }
- }
- break;
- case CHANGED:
- break;
- }
-
- Set<Property> nodeProp = nodeProps.get(node);
- if (nodeProp == null) {
- return;
- }
- Set<Property> ncProp = nodeConnectorProps.get(nc);
- // notify InventoryService
- notifyInventoryShimInternalListener(containerName, nc, t, ncProp);
-
- if (notifyNodeUpdate) {
- notifyInventoryShimInternalListener(containerName, node, t, nodeProp);
- }
- }
-
- private void notifyInventoryShimExternalListener(Node node,
- UpdateType type, Set<Property> props) {
- for (IInventoryShimExternalListener s : this.inventoryShimExternalListeners) {
- s.updateNode(node, type, props);
- }
- }
-
- private void notifyInventoryShimExternalListener(
- NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- for (IInventoryShimExternalListener s : this.inventoryShimExternalListeners) {
- s.updateNodeConnector(nodeConnector, type, props);
- }
- }
-
- private void notifyInventoryShimInternalListener(String container,
- NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- IInventoryShimInternalListener inventoryShimInternalListener = inventoryShimInternalListeners
- .get(container);
- if (inventoryShimInternalListener != null) {
- inventoryShimInternalListener.updateNodeConnector(nodeConnector,
- type, props);
- logger.trace(
- "notifyInventoryShimInternalListener {} type {} for container {}",
- new Object[] { nodeConnector, type, container });
- }
- }
-
- /*
- * Notify all internal and external listeners
- */
- private void notifyInventoryShimListener(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- notifyGlobalInventoryShimInternalListener(nodeConnector, type, props);
- /*
- * isLocal is intentionally moved after the GlobalInventory listener call.
- * The above notification to GlobalInventory will make sure that the connectionOutService be ready
- * to reply to isLocal query.
- */
- if (!connectionOutService.isLocal(nodeConnector.getNode())) {
- logger.debug("Connection service dropped the inventory notification for {} {}", nodeConnector.toString(), type);
- return;
- } else {
- logger.debug("Connection service accepted the inventory notification for {} {}", nodeConnector.toString(), type);
- }
-
- // notify other containers
- Set<String> containers = (nodeConnectorContainerMap.get(nodeConnector) == null) ? new HashSet<String>()
- : new HashSet<String>(nodeConnectorContainerMap.get(nodeConnector));
- containers.add(GlobalConstants.DEFAULT.toString());
- for (String container : containers) {
- notifyInventoryShimInternalListener(container, nodeConnector, type, props);
- }
-
- // Notify DiscoveryService
- notifyInventoryShimExternalListener(nodeConnector, type, props);
- }
-
- /*
- * Notify all internal and external listeners
- */
- private void notifyInventoryShimListener(Node node, UpdateType type, Set<Property> props) {
- notifyGlobalInventoryShimInternalListener(node, type, props);
- /*
- * isLocal is intentionally moved after the GlobalInventory listener call.
- * The above notification to GlobalInventory will make sure that the connectionOutService be ready
- * to reply to isLocal query.
- */
- if (!connectionOutService.isLocal(node)) {
- logger.debug("Connection service dropped the inventory notification for {} {}", node.toString(), type);
- return;
- } else {
- logger.debug("Connection service accepted the inventory notification for {} {}", node.toString(), type);
- }
- // Now notify other containers
- Set<String> containers = (nodeContainerMap.get(node) == null) ? new HashSet<String>() : new HashSet<String>(
- nodeContainerMap.get(node));
- containers.add(GlobalConstants.DEFAULT.toString());
- for (String container : containers) {
- notifyInventoryShimInternalListener(container, node, type, props);
- }
-
- // Notify external listener
- notifyInventoryShimExternalListener(node, type, props);
- }
-
- private void notifyGlobalInventoryShimInternalListener(Node node, UpdateType type, Set<Property> props) {
- for (IInventoryShimInternalListener globalListener : globalInventoryShimInternalListeners) {
- globalListener.updateNode(node, type, props);
- logger.trace(
- "notifyGlobalInventoryShimInternalListener {} type {}",
- new Object[] { node, type });
- }
- }
-
- private void notifyGlobalInventoryShimInternalListener(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- for (IInventoryShimInternalListener globalListener : globalInventoryShimInternalListeners) {
- globalListener.updateNodeConnector(nodeConnector, type, props);
- logger.trace(
- "notifyGlobalInventoryShimInternalListener {} type {}",
- new Object[] { nodeConnector, type });
- }
- }
-
- private void notifyInventoryShimInternalListener(String container,
- Node node, UpdateType type, Set<Property> props) {
- IInventoryShimInternalListener inventoryShimInternalListener = inventoryShimInternalListeners
- .get(container);
- if (inventoryShimInternalListener != null) {
- inventoryShimInternalListener.updateNode(node, type, props);
- logger.trace(
- "notifyInventoryShimInternalListener {} type {} for container {}",
- new Object[] { node, type, container });
- }
- }
-
- private void addNode(ISwitch sw) {
- Node node = NodeCreator.createOFNode(sw.getId());
- UpdateType type = UpdateType.ADDED;
-
- Set<Property> props = new HashSet<Property>();
- Long sid = (Long) node.getID();
-
- Date connectedSince = controller.getSwitches().get(sid)
- .getConnectedDate();
- Long connectedSinceTime = (connectedSince == null) ? 0 : connectedSince
- .getTime();
- props.add(new TimeStamp(connectedSinceTime, "connectedSince"));
- props.add(new MacAddress(deriveMacAddress(sid)));
-
- byte tables = sw.getTables();
- Tables t = new Tables(tables);
- if (t != null) {
- props.add(t);
- }
- int cap = sw.getCapabilities();
- Capabilities c = new Capabilities(cap);
- if (c != null) {
- props.add(c);
- }
- int act = sw.getActions();
- Actions a = new Actions(act);
- if (a != null) {
- props.add(a);
- }
- int buffers = sw.getBuffers();
- Buffers b = new Buffers(buffers);
- if (b != null) {
- props.add(b);
- }
-
- nodeProps.put(node, props);
- // Notify all internal and external listeners
- notifyInventoryShimListener(node, type, props);
- }
-
- private void removeNode(ISwitch sw) {
- Node node = NodeCreator.createOFNode(sw.getId());
- if(node == null) {
- return;
- }
- removeNodeConnectorProps(node);
- nodeProps.remove(node);
- UpdateType type = UpdateType.REMOVED;
- // Notify all internal and external listeners
- notifyInventoryShimListener(node, type, null);
- }
-
- private void startService() {
- // Get a snapshot of all the existing switches
- Map<Long, ISwitch> switches = this.controller.getSwitches();
- for (ISwitch sw : switches.values()) {
- switchAdded(sw);
- }
- }
-
- private void removeNodeConnectorProps(Node node) {
- List<NodeConnector> ncList = new ArrayList<NodeConnector>();
- for (NodeConnector nc : nodeConnectorProps.keySet()) {
- if (nc.getNode().equals(node)) {
- ncList.add(nc);
- }
- }
- for (NodeConnector nc : ncList) {
- nodeConnectorProps.remove(nc);
- }
- }
-
- @Override
- public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> descriptionStats) {
- Node node = NodeCreator.createOFNode(switchId);
- Set<Property> properties = new HashSet<Property>(1);
- OFDescriptionStatistics ofDesc = (OFDescriptionStatistics) descriptionStats.get(0);
- Description desc = new Description(ofDesc.getDatapathDescription());
- properties.add(desc);
-
- // Notify all internal and external listeners
- notifyInventoryShimListener(node, UpdateType.CHANGED, properties);
- }
-
- private byte[] deriveMacAddress(long dpid) {
- byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- for (short i = 0; i < 6; i++) {
- mac[5 - i] = (byte) dpid;
- dpid >>= 8;
- }
-
- return mac;
- }
-
- @Override
- public void flowStatisticsRefreshed(Long switchId, List<OFStatistics> flows) {
- // Nothing to do
- }
-
- @Override
- public void portStatisticsRefreshed(Long switchId, List<OFStatistics> ports) {
- // Nothing to do
- }
-
- @Override
- public void tableStatisticsRefreshed(Long switchId, List<OFStatistics> tables) {
- // Nothing to do
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsManager;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6Match;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6StatsReply;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6StatsRequest;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.statistics.OFAggregateStatisticsRequest;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFFlowStatisticsRequest;
-import org.openflow.protocol.statistics.OFPortStatisticsReply;
-import org.openflow.protocol.statistics.OFPortStatisticsRequest;
-import org.openflow.protocol.statistics.OFQueueStatisticsRequest;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.openflow.protocol.statistics.OFStatisticsType;
-import org.openflow.protocol.statistics.OFTableStatistics;
-import org.openflow.protocol.statistics.OFVendorStatistics;
-import org.openflow.util.HexString;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * It periodically polls the different OF statistics from the OF switches and
- * caches them for quick retrieval for the above layers' modules It also
- * provides an API to directly query the switch about the statistics
- */
-public class OFStatisticsManager implements IOFStatisticsManager,
-IInventoryShimExternalListener, CommandProvider {
- private static final Logger log = LoggerFactory.getLogger(OFStatisticsManager.class);
- private static final int INITIAL_SIZE = 64;
- private static final long FLOW_STATS_PERIOD = 10000;
- private static final long DESC_STATS_PERIOD = 60000;
- private static final long PORT_STATS_PERIOD = 5000;
- private static final long TABLE_STATS_PERIOD = 10000;
- private static final long TICK = 1000;
- private static short statisticsTickNumber = (short) (FLOW_STATS_PERIOD / TICK);
- private static short descriptionTickNumber = (short) (DESC_STATS_PERIOD / TICK);
- private static short portTickNumber = (short) (PORT_STATS_PERIOD / TICK);
- private static short tableTickNumber = (short) (TABLE_STATS_PERIOD / TICK);
- private static short factoredSamples = (short) 2;
- private static short counter = 1;
- private IController controller = null;
- private ConcurrentMap<Long, List<OFStatistics>> flowStatistics;
- private ConcurrentMap<Long, List<OFStatistics>> descStatistics;
- private ConcurrentMap<Long, List<OFStatistics>> portStatistics;
- private ConcurrentMap<Long, List<OFStatistics>> tableStatistics;
- private List<OFStatistics> dummyList;
- private ConcurrentMap<Long, StatisticsTicks> statisticsTimerTicks;
- protected BlockingQueue<StatsRequest> pendingStatsRequests;
- protected BlockingQueue<Long> switchPortStatsUpdated;
- private Thread statisticsCollector;
- private Thread txRatesUpdater;
- private Timer statisticsTimer;
- private TimerTask statisticsTimerTask;
- private ConcurrentMap<Long, Boolean> switchSupportsVendorExtStats;
- // Per port sampled (every portStatsPeriod) transmit rate
- private Map<Long, Map<Short, TxRates>> txRates;
- private Set<IOFStatisticsListener> statisticsListeners;
-
- /**
- * The object containing the latest factoredSamples tx rate samples for a
- * given switch port
- */
- protected class TxRates {
- // contains the latest factoredSamples sampled transmitted bytes
- Deque<Long> sampledTxBytes;
-
- public TxRates() {
- sampledTxBytes = new LinkedBlockingDeque<Long>();
- }
-
- public void update(Long txBytes) {
- /*
- * Based on how many samples our average works on, we might have to
- * remove the oldest sample
- */
- if (sampledTxBytes.size() == factoredSamples) {
- sampledTxBytes.removeLast();
- }
-
- // Add the latest sample to the top of the queue
- sampledTxBytes.addFirst(txBytes);
- }
-
- /**
- * Returns the average transmit rate in bps
- *
- * @return the average transmit rate [bps]
- */
- public long getAverageTxRate() {
- long average = 0;
- /*
- * If we cannot provide the value for the time window length set
- */
- if (sampledTxBytes.size() < factoredSamples) {
- return average;
- }
- long increment = sampledTxBytes.getFirst() - sampledTxBytes
- .getLast();
- long timePeriod = factoredSamples * PORT_STATS_PERIOD / TICK;
- average = (8L * increment) / timePeriod;
- return average;
- }
- }
-
- public void setController(IController core) {
- this.controller = core;
- }
-
- public void unsetController(IController core) {
- if (this.controller == core) {
- this.controller = null;
- }
- }
-
- private short getStatsQueueSize() {
- String statsQueueSizeStr = System.getProperty("of.statsQueueSize");
- short statsQueueSize = INITIAL_SIZE;
- if (statsQueueSizeStr != null) {
- try {
- statsQueueSize = Short.parseShort(statsQueueSizeStr);
- if (statsQueueSize <= 0) {
- statsQueueSize = INITIAL_SIZE;
- }
- } catch (Exception e) {
- }
- }
- return statsQueueSize;
- }
-
- IPluginOutConnectionService connectionPluginOutService;
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionPluginOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionPluginOutService == s) {
- connectionPluginOutService = null;
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- flowStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
- descStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
- portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
- tableStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
- dummyList = new ArrayList<OFStatistics>(1);
- pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(getStatsQueueSize());
- statisticsTimerTicks = new ConcurrentHashMap<Long, StatisticsTicks>(INITIAL_SIZE);
- switchPortStatsUpdated = new LinkedBlockingQueue<Long>(INITIAL_SIZE);
- switchSupportsVendorExtStats = new ConcurrentHashMap<Long, Boolean>(INITIAL_SIZE);
- txRates = new HashMap<Long, Map<Short, TxRates>>(INITIAL_SIZE);
- statisticsListeners = new CopyOnWriteArraySet<IOFStatisticsListener>();
-
- configStatsPollIntervals();
-
- // Initialize managed timers
- statisticsTimer = new Timer();
- statisticsTimerTask = new TimerTask() {
- @Override
- public void run() {
- decrementTicks();
- }
- };
-
- // Initialize Statistics collector thread
- statisticsCollector = new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- try {
- StatsRequest req = pendingStatsRequests.take();
- queryStatisticsInternal(req.switchId, req.type);
- } catch (InterruptedException e) {
- log.warn("Flow Statistics Collector thread "
- + "interrupted", e);
- }
- }
- }
- }, "Statistics Collector");
-
- // Initialize Tx Rate Updater thread
- txRatesUpdater = new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- try {
- long switchId = switchPortStatsUpdated.take();
- updatePortsTxRate(switchId);
- } catch (InterruptedException e) {
- log.warn("TX Rate Updater thread interrupted", e);
- }
- }
- }
- }, "TX Rate Updater");
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- // Start managed timers
- statisticsTimer.scheduleAtFixedRate(statisticsTimerTask, 0, TICK);
-
- // Start statistics collector thread
- statisticsCollector.start();
-
- // Start bandwidth utilization computer thread
- txRatesUpdater.start();
-
- // OSGI console
- registerWithOSGIConsole();
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- // Stop managed timers
- statisticsTimer.cancel();
- }
-
- public void setStatisticsListener(IOFStatisticsListener s) {
- this.statisticsListeners.add(s);
- }
-
- public void unsetStatisticsListener(IOFStatisticsListener s) {
- if (s != null) {
- this.statisticsListeners.remove(s);
- }
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this, null);
- }
-
- private static class StatsRequest {
- protected Long switchId;
- protected OFStatisticsType type;
-
- public StatsRequest(Long d, OFStatisticsType t) {
- switchId = d;
- type = t;
- }
-
- @Override
- public String toString() {
- return "SReq = {switchId=" + switchId + ", type=" + type + "}";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((switchId == null) ? 0 : switchId.hashCode());
- result = prime * result + ((type == null) ? 0 : type.ordinal());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- StatsRequest other = (StatsRequest) obj;
- if (switchId == null) {
- if (other.switchId != null) {
- return false;
- }
- } else if (!switchId.equals(other.switchId)) {
- return false;
- }
- if (type != other.type) {
- return false;
- }
- return true;
- }
- }
-
- private void addStatisticsTicks(Long switchId) {
- switchSupportsVendorExtStats.put(switchId, Boolean.TRUE); // Assume
- // switch
- // supports
- // Vendor
- // extension
- // stats
- statisticsTimerTicks.put(switchId, new StatisticsTicks(true));
- log.debug("Added Switch {} to target pool",
- HexString.toHexString(switchId.longValue()));
- }
-
- protected static class StatisticsTicks {
- private short flowStatisticsTicks;
- private short descriptionTicks;
- private short portStatisticsTicks;
- private short tableStatisticsTicks;
-
- public StatisticsTicks(boolean scattered) {
- if (scattered) {
- // scatter bursts by statisticsTickPeriod
- if (++counter < 0) {
- counter = 0;
- } // being paranoid here
- flowStatisticsTicks = (short) (1 + counter
- % statisticsTickNumber);
- descriptionTicks = (short) (1 + counter % descriptionTickNumber);
- portStatisticsTicks = (short) (1 + counter % portTickNumber);
- tableStatisticsTicks = (short) (1 + counter % tableTickNumber);
- } else {
- flowStatisticsTicks = statisticsTickNumber;
- descriptionTicks = descriptionTickNumber;
- portStatisticsTicks = portTickNumber;
- tableStatisticsTicks = tableTickNumber;
- }
- }
-
- public boolean decrementFlowTicksIsZero() {
- // Please ensure no code is inserted between the if check and the
- // flowStatisticsTicks reset
- if (--flowStatisticsTicks == 0) {
- flowStatisticsTicks = statisticsTickNumber;
- return true;
- }
- return false;
- }
-
- public boolean decrementDescTicksIsZero() {
- // Please ensure no code is inserted between the if check and the
- // descriptionTicks reset
- if (--descriptionTicks == 0) {
- descriptionTicks = descriptionTickNumber;
- return true;
- }
- return false;
- }
-
- public boolean decrementPortTicksIsZero() {
- // Please ensure no code is inserted between the if check and the
- // descriptionTicks reset
- if (--portStatisticsTicks == 0) {
- portStatisticsTicks = portTickNumber;
- return true;
- }
- return false;
- }
-
- public boolean decrementTableTicksIsZero() {
- // Please ensure no code is inserted between the if check and the
- // descriptionTicks reset
- if(--tableStatisticsTicks == 0) {
- tableStatisticsTicks = tableTickNumber;
- return true;
- }
- return false;
- }
-
- @Override
- public String toString() {
- return "{fT=" + flowStatisticsTicks + ",dT=" + descriptionTicks
- + ",pT=" + portStatisticsTicks + ",tT=" + tableStatisticsTicks + "}";
- }
- }
-
- private void printInfoMessage(String type, StatsRequest request) {
- log.info("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
- new Object[] {type, HexString.toHexString(request.switchId), pendingStatsRequests.size(),
- statisticsCollector.getState().toString() });
- }
-
- protected void decrementTicks() {
- StatsRequest request = null;
- for (Map.Entry<Long, StatisticsTicks> entry : statisticsTimerTicks
- .entrySet()) {
- StatisticsTicks clock = entry.getValue();
- Long switchId = entry.getKey();
- if (clock.decrementFlowTicksIsZero()) {
- request = (switchSupportsVendorExtStats.get(switchId) == Boolean.TRUE) ?
- new StatsRequest(switchId, OFStatisticsType.VENDOR) :
- new StatsRequest(switchId, OFStatisticsType.FLOW);
- // If a request for this switch is already in the queue, skip to
- // add this new request
- if (!pendingStatsRequests.contains(request)
- && false == pendingStatsRequests.offer(request)) {
- printInfoMessage("Flow", request);
- }
- }
-
- if (clock.decrementDescTicksIsZero()) {
- request = new StatsRequest(switchId, OFStatisticsType.DESC);
- // If a request for this switch is already in the queue, skip to
- // add this new request
- if (!pendingStatsRequests.contains(request)
- && false == pendingStatsRequests.offer(request)) {
- printInfoMessage("Description", request);
- }
- }
-
- if (clock.decrementPortTicksIsZero()) {
- request = new StatsRequest(switchId, OFStatisticsType.PORT);
- // If a request for this switch is already in the queue, skip to
- // add this new request
- if (!pendingStatsRequests.contains(request)
- && false == pendingStatsRequests.offer(request)) {
- printInfoMessage("Port", request);
- }
- }
-
- if(clock.decrementTableTicksIsZero()) {
- request = new StatsRequest(switchId, OFStatisticsType.TABLE);
- // If a request for this switch is already in the queue, skip to
- // add this new request
- if (!pendingStatsRequests.contains(request)
- && false == pendingStatsRequests.offer(request)) {
- printInfoMessage("Table", request);
- }
- }
- }
- }
-
- private void removeStatsRequestTasks(Long switchId) {
- log.debug("Cleaning Statistics database for switch {}",
- HexEncode.longToHexString(switchId));
- // To be safe, let's attempt removal of both VENDOR and FLOW request. It
- // does not hurt
- pendingStatsRequests.remove(new StatsRequest(switchId,
- OFStatisticsType.VENDOR));
- pendingStatsRequests.remove(new StatsRequest(switchId,
- OFStatisticsType.FLOW));
- pendingStatsRequests.remove(new StatsRequest(switchId,
- OFStatisticsType.DESC));
- pendingStatsRequests.remove(new StatsRequest(switchId,
- OFStatisticsType.PORT));
- pendingStatsRequests.remove(new StatsRequest(switchId,
- OFStatisticsType.TABLE));
- // Take care of the TX rate databases
- switchPortStatsUpdated.remove(switchId);
- txRates.remove(switchId);
- }
-
- private void clearFlowStatsAndTicks(Long switchId) {
- statisticsTimerTicks.remove(switchId);
- removeStatsRequestTasks(switchId);
- flowStatistics.remove(switchId);
- log.debug("Statistics removed for switch {}",
- HexString.toHexString(switchId));
- }
-
- private void queryStatisticsInternal(Long switchId, OFStatisticsType statType) {
-
- // Query the switch on all matches
- List<OFStatistics> values = this.fetchStatisticsFromSwitch(switchId, statType, null);
-
- // If got a valid response update local cache and notify listeners
- if (values != null && !values.isEmpty()) {
- switch (statType) {
- case FLOW:
- case VENDOR:
- flowStatistics.put(switchId, values);
- notifyFlowUpdate(switchId, values);
- break;
- case DESC:
- // Overwrite cache
- descStatistics.put(switchId, values);
- // Notify who may be interested in a description change
- notifyDescriptionUpdate(switchId, values);
- break;
- case PORT:
- // Overwrite cache with new port statistics for this switch
- portStatistics.put(switchId, values);
-
- // Wake up the thread which maintains the TX byte counters for
- // each port
- switchPortStatsUpdated.offer(switchId);
- notifyPortUpdate(switchId, values);
- break;
- case TABLE:
- // Overwrite cache
- tableStatistics.put(switchId, values);
- notifyTableUpdate(switchId, values);
- break;
- default:
- }
- }
- }
-
- private void notifyDescriptionUpdate(Long switchId, List<OFStatistics> values) {
- for (IOFStatisticsListener l : this.statisticsListeners) {
- l.descriptionStatisticsRefreshed(switchId, values);
- }
- }
-
- private void notifyFlowUpdate(Long switchId, List<OFStatistics> values) {
- if (values.get(0) instanceof OFVendorStatistics) {
- values = this.v6StatsListToOFStatsList(values);
- }
-
- for (IOFStatisticsListener l : this.statisticsListeners) {
- l.flowStatisticsRefreshed(switchId, values);
- }
-
- }
-
- private void notifyPortUpdate(Long switchId, List<OFStatistics> values) {
- for (IOFStatisticsListener l : this.statisticsListeners) {
- l.portStatisticsRefreshed(switchId, values);
- }
- }
-
- private void notifyTableUpdate(Long switchId, List<OFStatistics> values) {
- for (IOFStatisticsListener l : this.statisticsListeners) {
- l.tableStatisticsRefreshed(switchId, values);
- }
- }
-
- /*
- * Generic function to get the statistics form an OF switch
- */
- @SuppressWarnings("unchecked")
- private List<OFStatistics> fetchStatisticsFromSwitch(Long switchId,
- OFStatisticsType statsType, Object target) {
- List<OFStatistics> values = null;
- String type = null;
- ISwitch sw = controller.getSwitch(switchId);
-
- if (sw != null) {
- OFStatisticsRequest req = new OFStatisticsRequest();
- req.setStatisticType(statsType);
- int requestLength = req.getLengthU();
-
- if (statsType == OFStatisticsType.FLOW) {
- OFMatch match = null;
- if (target == null) {
- // All flows request
- match = new OFMatch();
- match.setWildcards(0xffffffff);
- } else if (!(target instanceof OFMatch)) {
- // Malformed request
- log.warn("Invalid target type for Flow stats request: {}",
- target.getClass());
- return null;
- } else {
- // Specific flow request
- match = (OFMatch) target;
- }
- OFFlowStatisticsRequest specificReq = new OFFlowStatisticsRequest();
- specificReq.setMatch(match);
- specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
- specificReq.setTableId((byte) 0xff);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- type = "FLOW";
- } else if (statsType == OFStatisticsType.VENDOR) {
- V6StatsRequest specificReq = new V6StatsRequest();
- specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
- specificReq.setTableId((byte) 0xff);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- type = "VENDOR";
- } else if (statsType == OFStatisticsType.AGGREGATE) {
- OFAggregateStatisticsRequest specificReq = new OFAggregateStatisticsRequest();
- OFMatch match = new OFMatch();
- match.setWildcards(0xffffffff);
- specificReq.setMatch(match);
- specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
- specificReq.setTableId((byte) 0xff);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- type = "AGGREGATE";
- } else if (statsType == OFStatisticsType.PORT) {
- short targetPort;
- if (target == null) {
- // All ports request
- targetPort = OFPort.OFPP_NONE.getValue();
- } else if (!(target instanceof Short)) {
- // Malformed request
- log.warn("Invalid target type for Port stats request: {}",
- target.getClass());
- return null;
- } else {
- // Specific port request
- targetPort = (Short) target;
- }
- OFPortStatisticsRequest specificReq = new OFPortStatisticsRequest();
- specificReq.setPortNumber(targetPort);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- type = "PORT";
- } else if (statsType == OFStatisticsType.QUEUE) {
- OFQueueStatisticsRequest specificReq = new OFQueueStatisticsRequest();
- specificReq.setPortNumber(OFPort.OFPP_ALL.getValue());
- specificReq.setQueueId(0xffffffff);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- type = "QUEUE";
- } else if (statsType == OFStatisticsType.DESC) {
- type = "DESC";
- } else if (statsType == OFStatisticsType.TABLE) {
- if(target != null){
- if (!(target instanceof Byte)) {
- // Malformed request
- log.warn("Invalid table id for table stats request: {}",
- target.getClass());
- return null;
- }
- byte targetTable = (Byte) target;
- OFTableStatistics specificReq = new OFTableStatistics();
- specificReq.setTableId(targetTable);
- req.setStatistics(Collections
- .singletonList((OFStatistics) specificReq));
- requestLength += specificReq.getLength();
- }
- type = "TABLE";
- }
- req.setLengthU(requestLength);
- Object result = sw.getStatistics(req);
-
- if (result == null) {
- log.warn("Request Timed Out for ({}) from switch {}", type,
- HexString.toHexString(switchId));
- } else if (result instanceof OFError) {
- log.warn("Switch {} failed to handle ({}) stats request: {}",
- new Object[] { HexString.toHexString(switchId), type,
- Utils.getOFErrorString((OFError) result) });
- if (this.switchSupportsVendorExtStats.get(switchId) == Boolean.TRUE) {
- log.warn(
- "Switching back to regular Flow stats requests for switch {}",
- HexString.toHexString(switchId));
- this.switchSupportsVendorExtStats.put(switchId,
- Boolean.FALSE);
- }
- } else {
- values = (List<OFStatistics>) result;
- }
- }
- return values;
- }
-
- @Override
- public List<OFStatistics> getOFFlowStatistics(Long switchId) {
- List<OFStatistics> list = flowStatistics.get(switchId);
-
- /*
- * Check on emptiness as interference between add and get is still
- * possible on the inner list (the concurrentMap entry's value)
- */
- return (list == null || list.isEmpty()) ? this.dummyList
- : (list.get(0) instanceof OFVendorStatistics) ? this
- .v6StatsListToOFStatsList(list) : list;
- }
-
- @Override
- public List<OFStatistics> getOFFlowStatistics(Long switchId, OFMatch ofMatch, short priority) {
- List<OFStatistics> statsList = flowStatistics.get(switchId);
-
- /*
- * Check on emptiness as interference between add and get is still
- * possible on the inner list (the concurrentMap entry's value)
- */
- if (statsList == null || statsList.isEmpty()) {
- return this.dummyList;
- }
-
- if (statsList.get(0) instanceof OFVendorStatistics) {
- /*
- * Caller could provide regular OF match when we instead pull the
- * vendor statistics from this node Caller is not supposed to know
- * whether this switch supports vendor extensions statistics
- * requests
- */
- V6Match targetMatch = (ofMatch instanceof V6Match) ? (V6Match) ofMatch
- : new V6Match(ofMatch);
-
- List<OFStatistics> targetList = v6StatsListToOFStatsList(statsList);
- for (OFStatistics stats : targetList) {
- V6StatsReply v6Stats = (V6StatsReply) stats;
- V6Match v6Match = v6Stats.getMatch();
- if (v6Stats.getPriority() == priority && v6Match.equals(targetMatch)) {
- List<OFStatistics> list = new ArrayList<OFStatistics>();
- list.add(stats);
- return list;
- }
- }
- } else {
- for (OFStatistics stats : statsList) {
- OFFlowStatisticsReply flowStats = (OFFlowStatisticsReply) stats;
- if (flowStats.getPriority() == priority && flowStats.getMatch().equals(ofMatch)) {
- List<OFStatistics> list = new ArrayList<OFStatistics>();
- list.add(stats);
- return list;
- }
- }
- }
- return this.dummyList;
- }
-
- /*
- * Converts the v6 vendor statistics to the OFStatistics
- */
- private List<OFStatistics> v6StatsListToOFStatsList(
- List<OFStatistics> statistics) {
- List<OFStatistics> v6statistics = new ArrayList<OFStatistics>();
- if (statistics != null && !statistics.isEmpty()) {
- for (OFStatistics stats : statistics) {
- if (stats instanceof OFVendorStatistics) {
- List<OFStatistics> r = getV6ReplyStatistics((OFVendorStatistics) stats);
- if (r != null) {
- v6statistics.addAll(r);
- }
- }
- }
- }
- return v6statistics;
- }
-
- private static List<OFStatistics> getV6ReplyStatistics(
- OFVendorStatistics stat) {
- int length = stat.getLength();
- List<OFStatistics> results = new ArrayList<OFStatistics>();
- if (length < 12)
- return null; // Nicira Hdr is 12 bytes. We need atleast that much
- ByteBuffer data = ByteBuffer.allocate(length);
- stat.writeTo(data);
- data.rewind();
- if (log.isTraceEnabled()) {
- log.trace("getV6ReplyStatistics: Buffer BYTES ARE {}",
- HexString.toHexString(data.array()));
- }
-
- int vendor = data.getInt(); // first 4 bytes is vendor id.
- if (vendor != V6StatsRequest.NICIRA_VENDOR_ID) {
- log.warn("Unexpected vendor id: 0x{}", Integer.toHexString(vendor));
- return null;
- } else {
- // go ahead by 8 bytes which is 8 bytes of 0
- data.getLong(); // should be all 0's
- length -= 12; // 4 bytes Nicira Hdr + 8 bytes from above line have
- // been consumed
- }
-
- V6StatsReply v6statsreply;
- int min_len;
- while (length > 0) {
- v6statsreply = new V6StatsReply();
- min_len = v6statsreply.getLength();
- if (length < v6statsreply.getLength())
- break;
- v6statsreply.setActionFactory(stat.getActionFactory());
- v6statsreply.readFrom(data);
- if (v6statsreply.getLength() < min_len)
- break;
- v6statsreply.setVendorId(vendor);
- log.trace("V6StatsReply: {}", v6statsreply);
- length -= v6statsreply.getLength();
- results.add(v6statsreply);
- }
- return results;
- }
-
- @Override
- public List<OFStatistics> queryStatistics(Long switchId,
- OFStatisticsType statType, Object target) {
- /*
- * Caller does not know and it is not supposed to know whether this
- * switch supports vendor extension. We adjust the target for him
- */
- if (statType == OFStatisticsType.FLOW) {
- if (switchSupportsVendorExtStats.get(switchId) == Boolean.TRUE) {
- statType = OFStatisticsType.VENDOR;
- }
- }
-
- List<OFStatistics> list = this.fetchStatisticsFromSwitch(switchId, statType,
- target);
-
- return (list == null) ? null :
- (statType == OFStatisticsType.VENDOR) ? v6StatsListToOFStatsList(list) : list;
- }
-
- @Override
- public List<OFStatistics> getOFDescStatistics(Long switchId) {
- if (!descStatistics.containsKey(switchId))
- return this.dummyList;
-
- return descStatistics.get(switchId);
- }
-
- @Override
- public List<OFStatistics> getOFPortStatistics(Long switchId) {
- if (!portStatistics.containsKey(switchId)) {
- return this.dummyList;
- }
-
- return portStatistics.get(switchId);
- }
-
- @Override
- public List<OFStatistics> getOFPortStatistics(Long switchId, short portId) {
- if (!portStatistics.containsKey(switchId)) {
- return this.dummyList;
- }
- List<OFStatistics> list = new ArrayList<OFStatistics>(1);
- for (OFStatistics stats : portStatistics.get(switchId)) {
- if (((OFPortStatisticsReply) stats).getPortNumber() == portId) {
- list.add(stats);
- break;
- }
- }
- return list;
- }
-
- @Override
- public List<OFStatistics> getOFTableStatistics(Long switchId) {
- if (!tableStatistics.containsKey(switchId)) {
- return this.dummyList;
- }
-
- return tableStatistics.get(switchId);
- }
-
- @Override
- public List<OFStatistics> getOFTableStatistics(Long switchId, Byte tableId) {
- if (!tableStatistics.containsKey(switchId)) {
- return this.dummyList;
- }
-
- List<OFStatistics> list = new ArrayList<OFStatistics>(1);
- for (OFStatistics stats : tableStatistics.get(switchId)) {
- if (((OFTableStatistics) stats).getTableId() == tableId) {
- list.add(stats);
- break;
- }
- }
- return list;
- }
-
- @Override
- public int getFlowsNumber(long switchId) {
- return this.flowStatistics.get(switchId).size();
- }
-
- /*
- * InventoryShim replay for us all the switch addition which happened before
- * we were brought up
- */
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- Long switchId = (Long) node.getID();
- switch (type) {
- case ADDED:
- addStatisticsTicks(switchId);
- break;
- case REMOVED:
- clearFlowStatsAndTicks(switchId);
- default:
- }
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- // No action
- }
-
- /**
- * Update the cached port rates for this switch with the latest retrieved
- * port transmit byte count
- *
- * @param switchId
- */
- private synchronized void updatePortsTxRate(long switchId) {
- List<OFStatistics> newPortStatistics = this.portStatistics.get(switchId);
- if (newPortStatistics == null) {
- return;
- }
- Map<Short, TxRates> rates = this.txRates.get(switchId);
- if (rates == null) {
- // First time rates for this switch are added
- rates = new HashMap<Short, TxRates>();
- txRates.put(switchId, rates);
- }
- for (OFStatistics stats : newPortStatistics) {
- OFPortStatisticsReply newPortStat = (OFPortStatisticsReply) stats;
- short port = newPortStat.getPortNumber();
- TxRates portRatesHolder = rates.get(port);
- if (portRatesHolder == null) {
- // First time rates for this port are added
- portRatesHolder = new TxRates();
- rates.put(port, portRatesHolder);
- }
- // Get and store the number of transmitted bytes for this port
- // And handle the case where agent does not support the counter
- long transmitBytes = newPortStat.getTransmitBytes();
- long value = (transmitBytes < 0) ? 0 : transmitBytes;
- portRatesHolder.update(value);
- }
- }
-
- @Override
- public synchronized long getTransmitRate(Long switchId, Short port) {
- long average = 0;
- if (switchId == null || port == null) {
- return average;
- }
- Map<Short, TxRates> perSwitch = txRates.get(switchId);
- if (perSwitch == null) {
- return average;
- }
- TxRates portRates = perSwitch.get(port);
- if (portRates == null) {
- return average;
- }
- return portRates.getAverageTxRate();
- }
-
- /*
- * Manual switch name configuration code
- */
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("---OF Statistics Manager utilities---\n");
- help.append("\t ofdumpstatsmgr - "
- + "Print Internal Stats Mgr db\n");
- help.append("\t ofstatsmgrintervals <fP> <pP> <dP> <tP> (all in seconds) - "
- + "Set/Show flow/port/dedscription stats poll intervals\n");
- return help.toString();
- }
-
- private boolean isValidSwitchId(String switchId) {
- String regexDatapathID = "^([0-9a-fA-F]{1,2}[:-]){7}[0-9a-fA-F]{1,2}$";
- String regexDatapathIDLong = "^[0-9a-fA-F]{1,16}$";
-
- return (switchId != null && (switchId.matches(regexDatapathID) || switchId
- .matches(regexDatapathIDLong)));
- }
-
- public long getSwitchIDLong(String switchId) {
- int radix = 16;
- String switchString = "0";
-
- if (isValidSwitchId(switchId)) {
- if (switchId.contains(":")) {
- // Handle the 00:00:AA:BB:CC:DD:EE:FF notation
- switchString = switchId.replace(":", "");
- } else if (switchId.contains("-")) {
- // Handle the 00-00-AA-BB-CC-DD-EE-FF notation
- switchString = switchId.replace("-", "");
- } else {
- // Handle the 0123456789ABCDEF notation
- switchString = switchId;
- }
- }
- return Long.parseLong(switchString, radix);
- }
-
- /*
- * Internal information dump code
- */
- private String prettyPrintSwitchMap(ConcurrentMap<Long, StatisticsTicks> map) {
- StringBuffer buffer = new StringBuffer();
- buffer.append("{");
- for (Entry<Long, StatisticsTicks> entry : map.entrySet()) {
- buffer.append(HexString.toHexString(entry.getKey()) + "="
- + entry.getValue().toString() + " ");
- }
- buffer.append("}");
- return buffer.toString();
- }
-
- public void _ofdumpstatsmgr(CommandInterpreter ci) {
- ci.println("Global Counter: " + counter);
- ci.println("Timer Ticks: " + prettyPrintSwitchMap(statisticsTimerTicks));
- ci.println("PendingStatsQueue: " + pendingStatsRequests);
- ci.println("PendingStatsQueue size: " + pendingStatsRequests.size());
- ci.println("Stats Collector alive: " + statisticsCollector.isAlive());
- ci.println("Stats Collector State: "
- + statisticsCollector.getState().toString());
- ci.println("StatsTimer: " + statisticsTimer.toString());
- ci.println("Flow Stats Period: " + statisticsTickNumber + " s");
- ci.println("Desc Stats Period: " + descriptionTickNumber + " s");
- ci.println("Port Stats Period: " + portTickNumber + " s");
- ci.println("Table Stats Period: " + tableTickNumber + " s");
- }
-
- public void _resetSwitchCapability(CommandInterpreter ci) {
- String sidString = ci.nextArgument();
- Long sid = null;
- if (sidString == null) {
- ci.println("Insert the switch id (numeric value)");
- return;
- }
- try {
- sid = Long.valueOf(sidString);
- this.switchSupportsVendorExtStats.put(sid, Boolean.TRUE);
- ci.println("Vendor capability for switch " + sid + " set to "
- + this.switchSupportsVendorExtStats.get(sid));
- } catch (NumberFormatException e) {
- ci.println("Invalid switch id. Has to be numeric.");
- }
-
- }
-
- public void _ofbw(CommandInterpreter ci) {
- String sidString = ci.nextArgument();
- Long sid = null;
- if (sidString == null) {
- ci.println("Insert the switch id (numeric value)");
- return;
- }
- try {
- sid = Long.valueOf(sidString);
- } catch (NumberFormatException e) {
- ci.println("Invalid switch id. Has to be numeric.");
- }
- if (sid != null) {
- Map<Short, TxRates> thisSwitchRates = txRates.get(sid);
- ci.println("Bandwidth utilization (" + factoredSamples
- * portTickNumber + " sec average) for switch "
- + HexEncode.longToHexString(sid) + ":");
- if (thisSwitchRates == null) {
- ci.println("Not available");
- } else {
- for (Entry<Short, TxRates> entry : thisSwitchRates.entrySet()) {
- ci.println("Port: " + entry.getKey() + ": "
- + entry.getValue().getAverageTxRate() + " bps");
- }
- }
- }
- }
-
- public void _txratewindow(CommandInterpreter ci) {
- String averageWindow = ci.nextArgument();
- short seconds = 0;
- if (averageWindow == null) {
- ci.println("Insert the length in seconds of the median "
- + "window for tx rate");
- ci.println("Current: " + factoredSamples * portTickNumber + " secs");
- return;
- }
- try {
- seconds = Short.valueOf(averageWindow);
- } catch (NumberFormatException e) {
- ci.println("Invalid period.");
- }
- OFStatisticsManager.factoredSamples = (short) (seconds / portTickNumber);
- ci.println("New: " + factoredSamples * portTickNumber + " secs");
- }
-
- public void _ofstatsmgrintervals(CommandInterpreter ci) {
- String flowStatsInterv = ci.nextArgument();
- String portStatsInterv = ci.nextArgument();
- String descStatsInterv = ci.nextArgument();
- String tableStatsInterv = ci.nextArgument();
-
- if (flowStatsInterv == null || portStatsInterv == null
- || descStatsInterv == null) {
- ci.println("Usage: ofstatsmgrintervals <fP> <pP> <dP> <tP> (all in seconds)");
- ci.println("Current Values: fP=" + statisticsTickNumber + "sec pP="
- + portTickNumber + "sec dP=" + descriptionTickNumber + "sec tP=" + tableTickNumber + " sec");
- return;
- }
- Short fP, pP, dP, tP;
- try {
- fP = Short.parseShort(flowStatsInterv);
- pP = Short.parseShort(portStatsInterv);
- dP = Short.parseShort(descStatsInterv);
- tP = Short.parseShort(tableStatsInterv);
- } catch (Exception e) {
- ci.println("Invalid format values: " + e.getMessage());
- return;
- }
-
- if (pP <= 1 || fP <= 1 || dP <= 1 || tP <= 1) {
- ci.println("Invalid values. fP, pP, dP, tP have to be greater than 1.");
- return;
- }
-
- statisticsTickNumber = fP;
- portTickNumber = pP;
- descriptionTickNumber = dP;
- tableTickNumber = tP;
-
- ci.println("New Values: fP=" + statisticsTickNumber + "s pP="
- + portTickNumber + "s dP=" + descriptionTickNumber + "s tP="
- + tableTickNumber + "s");
- }
-
- /**
- * This method retrieves user configurations from config.ini and updates
- * statisticsTickNumber/portTickNumber/descriptionTickNumber accordingly.
- */
- private void configStatsPollIntervals() {
- String fsStr = System.getProperty("of.flowStatsPollInterval");
- String psStr = System.getProperty("of.portStatsPollInterval");
- String dsStr = System.getProperty("of.descStatsPollInterval");
- String tsStr = System.getProperty("of.tableStatsPollInterval");
- Short fs, ps, ds, ts;
-
- if (fsStr != null) {
- try {
- fs = Short.parseShort(fsStr);
- if (fs > 0) {
- statisticsTickNumber = fs;
- }
- } catch (Exception e) {
- }
- }
-
- if (psStr != null) {
- try {
- ps = Short.parseShort(psStr);
- if (ps > 0) {
- portTickNumber = ps;
- }
- } catch (Exception e) {
- }
- }
-
- if (dsStr != null) {
- try {
- ds = Short.parseShort(dsStr);
- if (ds > 0) {
- descriptionTickNumber = ds;
- }
- } catch (Exception e) {
- }
- }
-
- if (tsStr != null) {
- try{
- ts = Short.parseShort(tsStr);
- if (ts > 0) {
- tableTickNumber = ts;
- }
- } catch (Exception e) {
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.openflow.protocol.OFPort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract class which provides the utilities for converting the Openflow port
- * number to the equivalent NodeConnector and vice versa
- *
- *
- *
- */
-public abstract class PortConverter {
- private static final Logger log = LoggerFactory
- .getLogger(PortConverter.class);
- private static final int maxOFPhysicalPort = NetUtils
- .getUnsignedShort(OFPort.OFPP_MAX.getValue());
-
- /**
- * Converts the Openflow port number to the equivalent NodeConnector.
- */
- public static NodeConnector toNodeConnector(short ofPort, Node node) {
- // Restore original OF unsigned 16 bits value for the comparison
- int unsignedOFPort = NetUtils.getUnsignedShort(ofPort);
- log.trace("Openflow port number signed: {} unsigned: {}", ofPort,
- unsignedOFPort);
- if (unsignedOFPort > maxOFPhysicalPort) {
- if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
- return NodeConnectorCreator.createNodeConnector(
- NodeConnectorIDType.SWSTACK,
- NodeConnector.SPECIALNODECONNECTORID, node);
- } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
- return NodeConnectorCreator.createNodeConnector(
- NodeConnectorIDType.HWPATH,
- NodeConnector.SPECIALNODECONNECTORID, node);
- } else if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
- return NodeConnectorCreator.createNodeConnector(
- NodeConnectorIDType.CONTROLLER,
- NodeConnector.SPECIALNODECONNECTORID, node);
- }
- }
- return NodeConnectorCreator.createNodeConnector(ofPort, node);
- }
-
- /**
- * Converts the NodeConnector to the equivalent Openflow port number
- */
- public static short toOFPort(NodeConnector salPort) {
- log.trace("SAL Port", salPort);
- if (salPort.getType().equals(NodeConnectorIDType.SWSTACK)) {
- return OFPort.OFPP_LOCAL.getValue();
- } else if (salPort.getType().equals(NodeConnectorIDType.HWPATH)) {
- return OFPort.OFPP_NORMAL.getValue();
- } else if (salPort.getType().equals(NodeConnectorIDType.CONTROLLER)) {
- return OFPort.OFPP_CONTROLLER.getValue();
- }
- return (Short) salPort.getID();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.openflow.protocol.statistics.OFPortStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Converts an openflow list of port statistics in a SAL list of
- * NodeConnectorStatistics objects
- *
- *
- *
- */
-public class PortStatisticsConverter {
- private static final Logger log = LoggerFactory
- .getLogger(PortStatisticsConverter.class);
- private long switchId;
- private List<OFStatistics> ofStatsList;
- private List<NodeConnectorStatistics> ncStatsList;
-
- public PortStatisticsConverter(long switchId, List<OFStatistics> statsList) {
- this.switchId = switchId;
- if (statsList == null || statsList.isEmpty()) {
- this.ofStatsList = new ArrayList<OFStatistics>(1); // dummy list
- } else {
- this.ofStatsList = new ArrayList<OFStatistics>(statsList);
- }
- this.ncStatsList = null;
- }
-
- public List<NodeConnectorStatistics> getNodeConnectorStatsList() {
- if (this.ofStatsList != null && this.ncStatsList == null) {
- this.ncStatsList = new ArrayList<NodeConnectorStatistics>();
- OFPortStatisticsReply ofPortStat;
- Node node = NodeCreator.createOFNode(switchId);
- for (OFStatistics ofStat : this.ofStatsList) {
- ofPortStat = (OFPortStatisticsReply) ofStat;
- NodeConnectorStatistics NCStat = new NodeConnectorStatistics();
- NCStat.setNodeConnector(PortConverter.toNodeConnector(
- ofPortStat.getPortNumber(), node));
- NCStat.setReceivePacketCount(ofPortStat.getreceivePackets());
- NCStat.setTransmitPacketCount(ofPortStat.getTransmitPackets());
- NCStat.setReceiveByteCount(ofPortStat.getReceiveBytes());
- NCStat.setTransmitByteCount(ofPortStat.getTransmitBytes());
- NCStat.setReceiveDropCount(ofPortStat.getReceiveDropped());
- NCStat.setTransmitDropCount(ofPortStat.getTransmitDropped());
- NCStat.setReceiveErrorCount(ofPortStat.getreceiveErrors());
- NCStat.setTransmitErrorCount(ofPortStat.getTransmitErrors());
- NCStat.setReceiveFrameErrorCount(ofPortStat
- .getReceiveFrameErrors());
- NCStat.setReceiveOverRunErrorCount(ofPortStat
- .getReceiveOverrunErrors());
- NCStat.setReceiveCRCErrorCount(ofPortStat.getReceiveCRCErrors());
- NCStat.setCollisionCount(ofPortStat.getCollisions());
- this.ncStatsList.add(NCStat);
- }
- }
- log.trace("OFStatistics: {} NodeConnectorStatistics: {}", ofStatsList,
- ncStatsList);
- return this.ncStatsList;
- }
-
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.NodeTable;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.reader.FlowOnNode;
-import org.opendaylight.controller.sal.reader.IPluginInReadService;
-import org.opendaylight.controller.sal.reader.IPluginOutReadService;
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
-import org.opendaylight.controller.sal.reader.NodeDescription;
-import org.opendaylight.controller.sal.reader.NodeTableStatistics;
-import org.opendaylight.openflowplugin.openflow.IReadFilterInternalListener;
-import org.opendaylight.openflowplugin.openflow.IReadServiceFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Container Instance of IPluginInReadService implementation class
- */
-public class ReadService implements IPluginInReadService, IReadFilterInternalListener {
- private static final Logger logger = LoggerFactory
- .getLogger(ReadService.class);
- private IReadServiceFilter filter;
- private Set<IPluginOutReadService> pluginOutReadServices;
- private String containerName;
- private IPluginOutConnectionService connectionOutService;
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- @SuppressWarnings("unchecked")
- void init(Component c) {
- Dictionary<Object, Object> props = c.getServiceProperties();
- containerName = (props != null) ? (String) props.get("containerName")
- : null;
- pluginOutReadServices = new CopyOnWriteArraySet<IPluginOutReadService>();
- }
-
- /**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
- *
- */
- void destroy() {
- }
-
- /**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
- *
- */
- void start() {
- }
-
- /**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
- *
- */
- void stop() {
- }
-
- public void setService(IReadServiceFilter filter) {
- this.filter = filter;
- }
-
- public void unsetService(IReadServiceFilter filter) {
- this.filter = null;
- }
-
- public void setPluginOutReadServices(IPluginOutReadService service) {
- logger.trace("Got a service set request {}", service);
- if (this.pluginOutReadServices != null) {
- this.pluginOutReadServices.add(service);
- }
- }
-
- public void unsetPluginOutReadServices(
- IPluginOutReadService service) {
- logger.trace("Got a service UNset request");
- if (this.pluginOutReadServices != null) {
- this.pluginOutReadServices.remove(service);
- }
- }
- @Override
- public FlowOnNode readFlow(Node node, Flow flow, boolean cached) {
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for the node : " + node);
- return null;
- }
- return filter.readFlow(containerName, node, flow, cached);
- }
-
- @Override
- public List<FlowOnNode> readAllFlow(Node node, boolean cached) {
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for the node : " + node);
- return null;
- }
-
- return filter.readAllFlow(containerName, node, cached);
- }
-
- @Override
- public NodeDescription readDescription(Node node, boolean cached) {
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for the node : " + node);
- return null;
- }
-
- return filter.readDescription(node, cached);
- }
-
- @Override
- public NodeConnectorStatistics readNodeConnector(NodeConnector connector,
- boolean cached) {
- if (!connector.getNode().getType()
- .equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(connector.getNode())) {
- logger.debug("This Controller is not the master for connector : "+connector);
- return null;
- }
-
- return filter.readNodeConnector(containerName, connector, cached);
- }
-
- @Override
- public List<NodeConnectorStatistics> readAllNodeConnector(Node node,
- boolean cached) {
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return null;
- }
-
- return filter.readAllNodeConnector(containerName, node, cached);
- }
-
- @Override
- public long getTransmitRate(NodeConnector connector) {
- if (!connector.getNode().getType()
- .equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return 0;
- }
-
- if (!connectionOutService.isLocal(connector.getNode())) {
- logger.debug("This Controller is not the master for connector : "+connector);
- return 0;
- }
-
- return filter.getTransmitRate(containerName, connector);
- }
-
- @Override
- public NodeTableStatistics readNodeTable(NodeTable table, boolean cached) {
- if (!table.getNode().getType()
- .equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(table.getNode())) {
- logger.debug("This Controller is not the master for connector : "+table);
- return null;
- }
-
- return filter.readNodeTable(containerName, table, cached);
- }
-
- @Override
- public List<NodeTableStatistics> readAllNodeTable(Node node, boolean cached) {
- if (!node.getType().equals(NodeIDType.OPENFLOW)) {
- logger.error("Invalid node type");
- return null;
- }
-
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return null;
- }
-
- return filter.readAllNodeTable(containerName, node, cached);
- }
-
- @Override
- public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return;
- }
- for (IPluginOutReadService service : pluginOutReadServices) {
- service.nodeFlowStatisticsUpdated(node, flowStatsList);
- }
- }
-
- @Override
- public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return;
- }
- for (IPluginOutReadService service : pluginOutReadServices) {
- service.nodeConnectorStatisticsUpdated(node, ncStatsList);
- }
- }
-
- @Override
- public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return;
- }
- for (IPluginOutReadService service : pluginOutReadServices) {
- service.nodeTableStatisticsUpdated(node, tableStatsList);
- }
- }
-
- @Override
- public void nodeDescriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
- if (!connectionOutService.isLocal(node)) {
- logger.debug("This Controller is not the master for node : " + node);
- return;
- }
- for (IPluginOutReadService service : pluginOutReadServices) {
- service.descriptionStatisticsUpdated(node, nodeDescription);
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.sal.action.Action;
-import org.opendaylight.controller.sal.action.ActionType;
-import org.opendaylight.controller.sal.action.Output;
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.NodeTable;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.match.Match;
-import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.reader.FlowOnNode;
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
-import org.opendaylight.controller.sal.reader.NodeDescription;
-import org.opendaylight.controller.sal.reader.NodeTableStatistics;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.sal.utils.NodeTableCreator;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsManager;
-import org.opendaylight.openflowplugin.openflow.IReadFilterInternalListener;
-import org.opendaylight.openflowplugin.openflow.IReadServiceFilter;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFPortStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.openflow.protocol.statistics.OFStatisticsType;
-import org.openflow.protocol.statistics.OFTableStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-/**
- * Read Service shim layer which is in charge of filtering the flow statistics
- * based on container. It is a Global instance.
- */
-public class ReadServiceFilter implements IReadServiceFilter, IContainerListener, IOFStatisticsListener {
- private static final Logger logger = LoggerFactory
- .getLogger(ReadServiceFilter.class);
- private IController controller = null;
- private IOFStatisticsManager statsMgr = null;
- private ConcurrentMap<String, Set<NodeConnector>> containerToNc;
- private ConcurrentMap<String, Set<Node>> containerToNode;
- private ConcurrentMap<String, Set<NodeTable>> containerToNt;
- private ConcurrentMap<String, Set<ContainerFlow>> containerFlows;
- private ConcurrentMap<String, IReadFilterInternalListener> readFilterInternalListeners;
-
- public void setController(IController core) {
- this.controller = core;
- }
-
- public void unsetController(IController core) {
- if (this.controller == core) {
- this.controller = null;
- }
- }
-
- public void setReadFilterInternalListener(Map<?, ?> props, IReadFilterInternalListener s) {
- if (props == null) {
- logger.error("Failed setting Read Filter Listener, property map is null.");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("Failed setting Read Filter Listener, container name not supplied.");
- return;
- }
- if ((this.readFilterInternalListeners != null) && !this.readFilterInternalListeners.containsValue(s)) {
- this.readFilterInternalListeners.put(containerName, s);
- logger.trace("Added Read Filter Listener for container {}", containerName);
- }
- }
-
- public void unsetReadFilterInternalListener(Map<?, ?> props, IReadFilterInternalListener s) {
- if (props == null) {
- logger.error("Failed unsetting Read Filter Listener, property map is null.");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("Failed unsetting Read Filter Listener, containerName not supplied");
- return;
- }
- if ((this.readFilterInternalListeners != null) && this.readFilterInternalListeners.get(containerName) != null
- && this.readFilterInternalListeners.get(containerName).equals(s)) {
- this.readFilterInternalListeners.remove(containerName);
- logger.trace("Removed Read Filter Listener for container {}", containerName);
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- containerToNc = new ConcurrentHashMap<String, Set<NodeConnector>>();
- containerToNt = new ConcurrentHashMap<String, Set<NodeTable>>();
- containerToNode = new ConcurrentHashMap<String, Set<Node>>();
- containerFlows = new ConcurrentHashMap<String, Set<ContainerFlow>>();
- readFilterInternalListeners = new ConcurrentHashMap<String, IReadFilterInternalListener>();
- }
-
- /**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
- *
- */
- void destroy() {
- }
-
- /**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
- *
- */
- void start() {
- }
-
- /**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
- *
- */
- void stop() {
- }
-
- public void setService(IOFStatisticsManager service) {
- this.statsMgr = service;
- }
-
- public void unsetService(IOFStatisticsManager service) {
- this.statsMgr = null;
- }
-
- IPluginOutConnectionService connectionPluginOutService;
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionPluginOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionPluginOutService == s) {
- connectionPluginOutService = null;
- }
- }
-
- @Override
- public FlowOnNode readFlow(String container, Node node, Flow flow, boolean cached) {
-
- if (controller == null) {
- // Avoid to provide cached statistics if controller went down.
- // They are not valid anymore anyway
- logger.error("Internal plugin error");
- return null;
- }
-
- long sid = (Long) node.getID();
- OFMatch ofMatch = new FlowConverter(flow).getOFMatch();
- List<OFStatistics> ofList;
- if (cached == true){
- ofList = statsMgr.getOFFlowStatistics(sid, ofMatch, flow.getPriority());
- } else {
- ofList = statsMgr.queryStatistics(sid, OFStatisticsType.FLOW, ofMatch);
- for (OFStatistics ofStat : ofList) {
- if (((OFFlowStatisticsReply)ofStat).getPriority() == flow.getPriority()){
- ofList = new ArrayList<OFStatistics>(1);
- ofList.add(ofStat);
- break;
- }
- }
- }
-
- // Convert and filter the statistics per container
- List<FlowOnNode> flowOnNodeList = new FlowStatisticsConverter(ofList).getFlowOnNodeList(node);
- List<FlowOnNode> filteredList = filterFlowListPerContainer(container, node, flowOnNodeList);
-
- return (filteredList == null || filteredList.isEmpty()) ? null : filteredList.get(0);
- }
-
- @Override
- public List<FlowOnNode> readAllFlow(String container, Node node,
- boolean cached) {
-
- long sid = (Long) node.getID();
- List<OFStatistics> ofList = (cached == true) ? statsMgr
- .getOFFlowStatistics(sid) : statsMgr.queryStatistics(sid,
- OFStatisticsType.FLOW, null);
-
- // Convert and filter the statistics per container
- List<FlowOnNode> flowOnNodeList = new FlowStatisticsConverter(ofList).getFlowOnNodeList(node);
- List<FlowOnNode> filteredList = filterFlowListPerContainer(container, node, flowOnNodeList);
-
- return (filteredList == null) ? null : filteredList;
-
- }
-
- @Override
- public NodeDescription readDescription(Node node, boolean cached) {
-
- if (controller == null) {
- logger.error("Internal plugin error");
- return null;
- }
-
- long sid = (Long) node.getID();
- List<OFStatistics> ofList = (cached == true) ? statsMgr
- .getOFDescStatistics(sid) : statsMgr.queryStatistics(sid,
- OFStatisticsType.DESC, null);
-
- return new DescStatisticsConverter(ofList).getHwDescription();
- }
-
- /**
- * Filters a list of FlowOnNode elements based on the container
- *
- * @param container
- * @param nodeId
- * @param list
- * @return
- */
- public List<FlowOnNode> filterFlowListPerContainer(String container,
- Node nodeId, List<FlowOnNode> list) {
- if (list == null) {
- return null;
- }
-
- // Create new filtered list of flows
- List<FlowOnNode> newList = new ArrayList<FlowOnNode>();
-
- for (FlowOnNode target : list) {
- // Check whether the described flow (match + actions) belongs to this container
- if (flowBelongToContainer(container, nodeId, target.getFlow())) {
- newList.add(target);
- }
- }
-
- return newList;
- }
-
- /**
- * Filters a list of OFStatistics elements based on the container
- *
- * @param container
- * @param nodeId
- * @param list
- * @return
- */
- public List<OFStatistics> filterPortListPerContainer(String container, long switchId, List<OFStatistics> list) {
- if (list == null) {
- return null;
- }
-
- // Create new filtered list of flows
- List<OFStatistics> newList = new ArrayList<OFStatistics>();
-
- for (OFStatistics stat : list) {
- OFPortStatisticsReply target = (OFPortStatisticsReply) stat;
- NodeConnector nc = NodeConnectorCreator.createOFNodeConnector(
- target.getPortNumber(), NodeCreator.createOFNode(switchId));
- if (containerOwnsNodeConnector(container, nc)) {
- newList.add(target);
- }
- }
-
- return newList;
- }
-
-
- public List<OFStatistics> filterTableListPerContainer(
- String container, long switchId, List<OFStatistics> list) {
- if (list == null) {
- return null;
- }
-
- // Create new filtered list of node tables
- List<OFStatistics> newList = new ArrayList<OFStatistics>();
-
- for (OFStatistics stat : list) {
- OFTableStatistics target = (OFTableStatistics) stat;
- NodeTable nt = NodeTableCreator.createOFNodeTable(target.getTableId(), NodeCreator.createOFNode(switchId));
- if (containerOwnsNodeTable(container, nt)) {
- newList.add(target);
- }
- }
-
- return newList;
- }
-
- /**
- * Returns whether the specified flow (flow match + actions)
- * belongs to the container
- *
- * @param container
- * @param node
- * @param flow
- * @return true if it belongs
- */
- public boolean flowBelongToContainer(String container, Node node, Flow flow) {
- // All flows belong to the default container
- if (container.equals(GlobalConstants.DEFAULT.toString())) {
- return true;
- }
- return (flowPortsBelongToContainer(container, node, flow) &&
- flowVlanBelongsToContainer(container, node, flow) &&
- isFlowAllowedByContainer(container, flow));
- }
-
- /**
- * Returns whether the passed NodeConnector belongs to the container
- *
- * @param container container name
- * @param p node connector to test
- * @return true if belongs false otherwise
- */
- public boolean containerOwnsNodeConnector(String container, NodeConnector p) {
- // All node connectors belong to the default container
- if (container.equals(GlobalConstants.DEFAULT.toString())) {
- return true;
- }
- Set<NodeConnector> portSet = containerToNc.get(container);
- return (portSet == null) ? false : portSet.contains(p);
- }
-
- /**
- * Returns whether the passed NodeConnector belongs to the container
- *
- * @param container container name
- * @param table node table to test
- * @return true if belongs false otherwise
- */
- public boolean containerOwnsNodeTable(String container, NodeTable table) {
- // All node table belong to the default container
- if (container.equals(GlobalConstants.DEFAULT.toString())) {
- return true;
- }
- Set<NodeTable> tableSet = containerToNt.get(container);
- return (tableSet == null) ? false : tableSet.contains(table);
- }
-
- /**
- * Returns whether the container flows allow the passed flow
- *
- * @param container
- * @param match
- * @return
- */
- private boolean isFlowAllowedByContainer(String container, Flow flow) {
- Set<ContainerFlow> cFlowSet = this.containerFlows.get(container);
- if (cFlowSet == null || cFlowSet.isEmpty()) {
- return true;
- }
- for (ContainerFlow cFlow : cFlowSet) {
- if (cFlow.allowsFlow(flow)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Check whether the vlan field in the flow match is the same
- * of the static vlan configured for the container
- *
- * @param container
- * @param node
- * @param flow
- * @return
- */
- private boolean flowVlanBelongsToContainer(String container, Node node, Flow flow) {
- return true; // Always true for now
- }
-
- /**
- * Check whether the ports in the flow match and flow actions for
- * the specified node belong to the container
- *
- * @param container
- * @param node
- * @param flow
- * @return
- */
- private boolean flowPortsBelongToContainer(String container, Node node,
- Flow flow) {
- Match m = flow.getMatch();
- if (m.isPresent(MatchType.IN_PORT)) {
- NodeConnector inPort = (NodeConnector) m.getField(MatchType.IN_PORT).getValue();
- // If the incoming port is specified, check if it belongs to
- if (!containerOwnsNodeConnector(container, inPort)) {
- return false;
- }
- }
-
- // If an outgoing port is specified, it must belong to this container
- for (Action action : flow.getActions()) {
- if (action.getType() == ActionType.OUTPUT) {
- NodeConnector outPort = ((Output) action).getPort();
- if (!containerOwnsNodeConnector(container, outPort)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- public void containerFlowUpdated(String containerName, ContainerFlow previousFlow,
- ContainerFlow currentFlow, UpdateType t) {
- Set<ContainerFlow> cFlowSet = containerFlows.get(containerName);
- switch (t) {
- case ADDED:
- if (cFlowSet == null) {
- cFlowSet = new HashSet<ContainerFlow>();
- containerFlows.put(containerName, cFlowSet);
- }
- cFlowSet.add(currentFlow);
- case CHANGED:
- break;
- case REMOVED:
- if (cFlowSet != null) {
- cFlowSet.remove(currentFlow);
- }
- break;
- default:
- break;
- }
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType type) {
-
- switch (type) {
- case ADDED:
- if (!containerToNc.containsKey(containerName)) {
- containerToNc.put(containerName,
- Collections.newSetFromMap(new ConcurrentHashMap<NodeConnector,Boolean>()));
- }
- containerToNc.get(containerName).add(p);
- if (!containerToNode.containsKey(containerName)) {
- containerToNode.put(containerName, new HashSet<Node>());
- }
- containerToNode.get(containerName).add(p.getNode());
- break;
- case REMOVED:
- Set<NodeConnector> ncSet = containerToNc.get(containerName);
- if (ncSet != null) {
- //remove this nc from container map
- ncSet.remove(p);
-
- //check if there are still ports of this node in this container
- //and if not, remove its mapping
- boolean nodeInContainer = false;
- Node node = p.getNode();
- for (NodeConnector nodeConnector : ncSet) {
- if (nodeConnector.getNode().equals(node)){
- nodeInContainer = true;
- break;
- }
- }
- if (! nodeInContainer) {
- Set<Node> nodeSet = containerToNode.get(containerName);
- if (nodeSet != null) {
- nodeSet.remove(node);
- }
- }
- }
- break;
- case CHANGED:
- default:
- }
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) {
- // Not interested in this event
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // Not interested in this event
- }
-
- @Override
- public NodeConnectorStatistics readNodeConnector(String containerName, NodeConnector connector, boolean cached) {
- if (!containerOwnsNodeConnector(containerName, connector)) {
- return null;
- }
- Node node = connector.getNode();
- long sid = (Long) node.getID();
- short portId = (Short) connector.getID();
- List<OFStatistics> ofList = (cached == true) ? statsMgr
- .getOFPortStatistics(sid, portId) : statsMgr.queryStatistics(
- sid, OFStatisticsType.PORT, portId);
-
- List<NodeConnectorStatistics> ncStatistics = new PortStatisticsConverter(sid, ofList)
- .getNodeConnectorStatsList();
- return (ncStatistics.isEmpty()) ? new NodeConnectorStatistics() : ncStatistics.get(0);
- }
-
- @Override
- public List<NodeConnectorStatistics> readAllNodeConnector(String containerName, Node node, boolean cached) {
-
- long sid = (Long) node.getID();
- List<OFStatistics> ofList = (cached == true) ? statsMgr
- .getOFPortStatistics(sid) : statsMgr.queryStatistics(sid,
- OFStatisticsType.FLOW, null);
-
- List<OFStatistics> filteredList = filterPortListPerContainer(containerName, sid, ofList);
-
- return new PortStatisticsConverter(sid, filteredList).getNodeConnectorStatsList();
- }
-
- @Override
- public long getTransmitRate(String containerName, NodeConnector connector) {
- if (!containerOwnsNodeConnector(containerName, connector)) {
- return 0;
- }
-
- long switchId = (Long) connector.getNode().getID();
- short port = (Short) connector.getID();
-
- return statsMgr.getTransmitRate(switchId, port);
- }
-
- @Override
- public NodeTableStatistics readNodeTable(String containerName,
- NodeTable table, boolean cached) {
- if (!containerOwnsNodeTable(containerName, table)) {
- return null;
- }
- Node node = table.getNode();
- long sid = (Long) node.getID();
- Byte tableId = (Byte) table.getID();
- List<OFStatistics> ofList = (cached == true) ? statsMgr.getOFTableStatistics(sid, tableId) :
- statsMgr.queryStatistics(sid, OFStatisticsType.TABLE, tableId);
-
- List<NodeTableStatistics> ntStatistics = new TableStatisticsConverter(sid, ofList).getNodeTableStatsList();
-
- return (ntStatistics.isEmpty()) ? new NodeTableStatistics() : ntStatistics.get(0);
- }
-
- @Override
- public List<NodeTableStatistics> readAllNodeTable(String containerName, Node node, boolean cached) {
- long sid = (Long) node.getID();
- List<OFStatistics> ofList = (cached == true) ?
- statsMgr.getOFTableStatistics(sid) : statsMgr.queryStatistics(sid, OFStatisticsType.FLOW, null);
-
- List<OFStatistics> filteredList = filterTableListPerContainer(containerName, sid, ofList);
-
- return new TableStatisticsConverter(sid, filteredList).getNodeTableStatsList();
- }
-
- @Override
- public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> description) {
- String container;
- IReadFilterInternalListener listener;
- Node node = NodeCreator.createOFNode(switchId);
- NodeDescription nodeDescription = new DescStatisticsConverter(description).getHwDescription();
- for (Map.Entry<String, IReadFilterInternalListener> l : readFilterInternalListeners.entrySet()) {
- container = l.getKey();
- listener = l.getValue();
- if (container == GlobalConstants.DEFAULT.toString()
- || (containerToNode.containsKey(container) && containerToNode.get(container).contains(node))) {
- listener.nodeDescriptionStatisticsUpdated(node, nodeDescription);
- }
- }
- }
-
- @Override
- public void flowStatisticsRefreshed(Long switchId, List<OFStatistics> flows) {
- String container;
- IReadFilterInternalListener listener;
- Node node = NodeCreator.createOFNode(switchId);
- for (Map.Entry<String, IReadFilterInternalListener> l : readFilterInternalListeners.entrySet()) {
- container = l.getKey();
- listener = l.getValue();
-
- // Convert and filter the statistics per container
- List<FlowOnNode> flowOnNodeList = new FlowStatisticsConverter(flows).getFlowOnNodeList(node);
- flowOnNodeList = filterFlowListPerContainer(container, node, flowOnNodeList);
-
- // notify listeners
- listener.nodeFlowStatisticsUpdated(node, flowOnNodeList);
- }
- }
-
- @Override
- public void portStatisticsRefreshed(Long switchId, List<OFStatistics> ports) {
- String container;
- IReadFilterInternalListener listener;
- Node node = NodeCreator.createOFNode(switchId);
- for (Map.Entry<String, IReadFilterInternalListener> l : readFilterInternalListeners.entrySet()) {
- container = l.getKey();
- listener = l.getValue();
-
- // Convert and filter the statistics per container
- List<OFStatistics> filteredPorts = filterPortListPerContainer(container, switchId, ports);
- List<NodeConnectorStatistics> ncStatsList = new PortStatisticsConverter(switchId, filteredPorts)
- .getNodeConnectorStatsList();
-
- // notify listeners
- listener.nodeConnectorStatisticsUpdated(node, ncStatsList);
- }
- }
-
- @Override
- public void tableStatisticsRefreshed(Long switchId, List<OFStatistics> tables) {
- String container;
- Node node = NodeCreator.createOFNode(switchId);
- for (Map.Entry<String, IReadFilterInternalListener> l : readFilterInternalListeners.entrySet()) {
- container = l.getKey();
-
- // Convert and filter the statistics per container
- List<OFStatistics> filteredList = filterTableListPerContainer(container, switchId, tables);
- List<NodeTableStatistics> tableStatsList = new TableStatisticsConverter(switchId, filteredList)
- .getNodeTableStatsList();
-
- // notify listeners
- l.getValue().nodeTableStatisticsUpdated(node, tableStatsList);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Big Switch Networks, Inc. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeTable;
-import org.opendaylight.controller.sal.utils.NodeTableCreator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TableConverter {
- private static final Logger log = LoggerFactory
- .getLogger(TableConverter.class);
-
- public static NodeTable toNodeTable(byte tableId, Node node) {
- log.trace("Openflow table ID: {}", Byte.toString(tableId));
- return NodeTableCreator.createNodeTable(tableId, node);
- }
-
- public static byte toOFTable(NodeTable salTable) {
- log.trace("SAL Table: {}", salTable);
- return (Byte) salTable.getID();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Big Switch Networks, Inc. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.reader.NodeTableStatistics;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.openflow.protocol.statistics.OFTableStatistics;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Converts an openflow list of table statistics in a SAL list of
- * NodeTableStatistics objects
- */
-public class TableStatisticsConverter {
- private static final Logger log = LoggerFactory
- .getLogger(TableStatisticsConverter.class);
-
- private final long switchId;
- private List<OFStatistics> ofStatsList;
- private List<NodeTableStatistics> ntStatsList;
-
- public TableStatisticsConverter(long switchId, List<OFStatistics> statsList) {
- this.switchId = switchId;
- if (statsList == null || statsList.isEmpty()) {
- this.ofStatsList = new ArrayList<OFStatistics>(1); // dummy list
- } else {
- this.ofStatsList = new ArrayList<OFStatistics>(statsList);
- }
- this.ntStatsList = null;
- }
-
- public List<NodeTableStatistics> getNodeTableStatsList() {
- if (this.ofStatsList != null && this.ntStatsList == null) {
- this.ntStatsList = new ArrayList<NodeTableStatistics>();
- OFTableStatistics ofTableStat;
- Node node = NodeCreator.createOFNode(switchId);
- for (OFStatistics ofStat : this.ofStatsList) {
- ofTableStat = (OFTableStatistics) ofStat;
- NodeTableStatistics ntStat = new NodeTableStatistics();
- ntStat.setNodeTable(TableConverter.toNodeTable(
- ofTableStat.getTableId(), node));
- ntStat.setActiveCount(ofTableStat.getActiveCount());
- ntStat.setLookupCount(ofTableStat.getLookupCount());
- ntStat.setMatchedCount(ofTableStat.getMatchedCount());
- this.ntStatsList.add(ntStat);
- }
- }
- log.trace("OFStatistics: {} NodeTableStatistics: {}", ofStatsList,
- ntStatsList);
- return this.ntStatsList;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Bandwidth;
-import org.opendaylight.controller.sal.core.Config;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.State;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.openflowplugin.openflow.IDiscoveryListener;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.IOFStatisticsManager;
-import org.opendaylight.openflowplugin.openflow.IRefreshInternalProvider;
-import org.opendaylight.openflowplugin.openflow.ITopologyServiceShimListener;
-
-/**
- * The class describes a shim layer that relays the topology events from
- * OpenFlow core to various listeners. The notifications are filtered based on
- * container configurations.
- */
-public class TopologyServiceShim implements IDiscoveryListener,
- IContainerListener, CommandProvider, IRefreshInternalProvider,
- IInventoryShimExternalListener {
- protected static final Logger logger = LoggerFactory
- .getLogger(TopologyServiceShim.class);
- private ConcurrentMap<String, ITopologyServiceShimListener> topologyServiceShimListeners = new ConcurrentHashMap<String, ITopologyServiceShimListener>();
- private ConcurrentMap<NodeConnector, List<String>> containerMap = new ConcurrentHashMap<NodeConnector, List<String>>();
- private ConcurrentMap<String, ConcurrentMap<NodeConnector, Pair<Edge, Set<Property>>>> edgeMap = new ConcurrentHashMap<String, ConcurrentMap<NodeConnector, Pair<Edge, Set<Property>>>>();
-
- private BlockingQueue<NotifyEntry> notifyQ;
- private Thread notifyThread;
- private BlockingQueue<String> bulkNotifyQ;
- private Thread ofPluginTopoBulkUpdate;
- private volatile Boolean shuttingDown = false;
- private IOFStatisticsManager statsMgr;
- private Timer pollTimer;
- private TimerTask txRatePoller;
- private Thread bwUtilNotifyThread;
- private BlockingQueue<UtilizationUpdate> bwUtilNotifyQ;
- private List<NodeConnector> connectorsOverUtilized;
- private float bwThresholdFactor = (float) 0.8; // Threshold = 80% of link
- // bandwidth
-
- class NotifyEntry {
- String container;
- List<TopoEdgeUpdate> teuList;
-
- public NotifyEntry(String container, TopoEdgeUpdate teu) {
- this.container = container;
- this.teuList = new ArrayList<TopoEdgeUpdate>();
- if (teu != null) {
- this.teuList.add(teu);
- }
- }
-
- public NotifyEntry(String container, List<TopoEdgeUpdate> teuList) {
- this.container = container;
- this.teuList = new ArrayList<TopoEdgeUpdate>();
- if (teuList != null) {
- this.teuList.addAll(teuList);
- }
- }
- }
-
- class TopologyNotify implements Runnable {
- private final BlockingQueue<NotifyEntry> notifyQ;
- private NotifyEntry entry;
- private Map<String, List<TopoEdgeUpdate>> teuMap = new HashMap<String, List<TopoEdgeUpdate>>();
- private List<TopoEdgeUpdate> teuList;
- private boolean notifyListeners;
-
- TopologyNotify(BlockingQueue<NotifyEntry> notifyQ) {
- this.notifyQ = notifyQ;
- }
-
- public void run() {
- while (true) {
- try {
- teuMap.clear();
- notifyListeners = false;
- while (!notifyQ.isEmpty()) {
- entry = notifyQ.take();
- teuList = teuMap.get(entry.container);
- if (teuList == null) {
- teuList = new ArrayList<TopoEdgeUpdate>();
- }
- // group all the updates together
- teuList.addAll(entry.teuList);
- teuMap.put(entry.container, teuList);
- notifyListeners = true;
- }
-
- if (notifyListeners) {
- for (String container : teuMap.keySet()) {
- // notify the listener
- topologyServiceShimListeners.get(container)
- .edgeUpdate(teuMap.get(container));
- }
- }
-
- Thread.sleep(100);
- } catch (InterruptedException e1) {
- logger.warn("TopologyNotify interrupted {}",
- e1.getMessage());
- if (shuttingDown) {
- return;
- }
- } catch (Exception e2) {
- logger.error("", e2);
- }
- }
- }
- }
-
- class UtilizationUpdate {
- NodeConnector connector;
- UpdateType type;
-
- UtilizationUpdate(NodeConnector connector, UpdateType type) {
- this.connector = connector;
- this.type = type;
- }
- }
-
- class BwUtilizationNotify implements Runnable {
- private final BlockingQueue<UtilizationUpdate> notifyQ;
-
- BwUtilizationNotify(BlockingQueue<UtilizationUpdate> notifyQ) {
- this.notifyQ = notifyQ;
- }
-
- public void run() {
- while (true) {
- try {
- UtilizationUpdate update = notifyQ.take();
- NodeConnector connector = update.connector;
- Set<String> containerList = edgeMap.keySet();
- for (String container : containerList) {
- Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
- .get(container);
- Edge edge = edgePropsMap.get(connector).getLeft();
- if (edge.getTailNodeConnector().equals(connector)) {
- ITopologyServiceShimListener topologServiceShimListener = topologyServiceShimListeners
- .get(container);
- if (update.type == UpdateType.ADDED) {
- topologServiceShimListener
- .edgeOverUtilized(edge);
- } else {
- topologServiceShimListener
- .edgeUtilBackToNormal(edge);
- }
- }
- }
- } catch (InterruptedException e1) {
- logger.warn(
- "Edge Bandwidth Utilization Notify Thread interrupted {}",
- e1.getMessage());
- if (shuttingDown) {
- return;
- }
- } catch (Exception e2) {
- logger.error("", e2);
- }
- }
- }
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- logger.trace("Init called");
- connectorsOverUtilized = new ArrayList<NodeConnector>();
- notifyQ = new LinkedBlockingQueue<NotifyEntry>();
- notifyThread = new Thread(new TopologyNotify(notifyQ));
- bwUtilNotifyQ = new LinkedBlockingQueue<UtilizationUpdate>();
- bwUtilNotifyThread = new Thread(new BwUtilizationNotify(bwUtilNotifyQ));
- bulkNotifyQ = new LinkedBlockingQueue<String>();
- ofPluginTopoBulkUpdate = new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- try {
- String containerName = bulkNotifyQ.take();
- logger.debug("Bulk Notify container:{}", containerName);
- TopologyBulkUpdate(containerName);
- } catch (InterruptedException e) {
- logger.warn("Topology Bulk update thread interrupted");
- if (shuttingDown) {
- return;
- }
- }
- }
- }
- }, "Topology Bulk Update");
-
- // Initialize node connector tx bit rate poller timer
- pollTimer = new Timer();
- txRatePoller = new TimerTask() {
- @Override
- public void run() {
- pollTxBitRates();
- }
- };
-
- registerWithOSGIConsole();
- }
-
- /**
- * Continuously polls the transmit bit rate for all the node connectors from
- * statistics manager and trigger the warning notification upward when the
- * transmit rate is above a threshold which is a percentage of the edge
- * bandwidth
- */
- protected void pollTxBitRates() {
- Map<NodeConnector, Pair<Edge, Set<Property>>> globalContainerEdges = edgeMap
- .get(GlobalConstants.DEFAULT.toString());
- if (globalContainerEdges == null) {
- return;
- }
-
- for (NodeConnector connector : globalContainerEdges.keySet()) {
- // Skip if node connector belongs to production switch
- if (connector.getType().equals(
- NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- continue;
- }
-
- // Get edge for which this node connector is head
- Pair<Edge, Set<Property>> props = this.edgeMap.get(
- GlobalConstants.DEFAULT.toString()).get(connector);
- // On switch mgr restart the props get reset
- if (props == null) {
- continue;
- }
- Set<Property> propSet = props.getRight();
- if (propSet == null) {
- continue;
- }
-
- float bw = 0;
- for (Property prop : propSet) {
- if (prop instanceof Bandwidth) {
- bw = ((Bandwidth) prop).getValue();
- break;
- }
- }
-
- // Skip if agent did not provide a bandwidth info for the edge
- if (bw == 0) {
- continue;
- }
-
- // Compare bandwidth usage
- Long switchId = (Long) connector.getNode().getID();
- Short port = (Short) connector.getID();
- float rate = statsMgr.getTransmitRate(switchId, port);
- if (rate > bwThresholdFactor * bw) {
- if (!connectorsOverUtilized.contains(connector)) {
- connectorsOverUtilized.add(connector);
- this.bwUtilNotifyQ.add(new UtilizationUpdate(connector,
- UpdateType.ADDED));
- }
- } else {
- if (connectorsOverUtilized.contains(connector)) {
- connectorsOverUtilized.remove(connector);
- this.bwUtilNotifyQ.add(new UtilizationUpdate(connector,
- UpdateType.REMOVED));
- }
- }
- }
-
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- logger.trace("DESTROY called!");
- notifyQ = null;
- notifyThread = null;
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- logger.trace("START called!");
- notifyThread.start();
- bwUtilNotifyThread.start();
- ofPluginTopoBulkUpdate.start();
- pollTimer.scheduleAtFixedRate(txRatePoller, 10000, 5000);
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- logger.trace("STOP called!");
- shuttingDown = true;
- notifyThread.interrupt();
- }
-
- void setTopologyServiceShimListener(Map<?, ?> props,
- ITopologyServiceShimListener s) {
- if (props == null) {
- logger.error("Didn't receive the service properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("containerName not supplied");
- return;
- }
- if ((this.topologyServiceShimListeners != null)
- && !this.topologyServiceShimListeners
- .containsKey(containerName)) {
- this.topologyServiceShimListeners.put(containerName, s);
- logger.trace("Added topologyServiceShimListener for container: {}",
- containerName);
- }
- }
-
- void unsetTopologyServiceShimListener(Map<?, ?> props,
- ITopologyServiceShimListener s) {
- if (props == null) {
- logger.error("Didn't receive the service properties");
- return;
- }
- String containerName = (String) props.get("containerName");
- if (containerName == null) {
- logger.error("containerName not supplied");
- return;
- }
- if ((this.topologyServiceShimListeners != null)
- && this.topologyServiceShimListeners.containsKey(containerName)
- && this.topologyServiceShimListeners.get(containerName).equals(
- s)) {
- this.topologyServiceShimListeners.remove(containerName);
- logger.trace(
- "Removed topologyServiceShimListener for container: {}",
- containerName);
- }
- }
-
- void setStatisticsManager(IOFStatisticsManager s) {
- this.statsMgr = s;
- }
-
- void unsetStatisticsManager(IOFStatisticsManager s) {
- if (this.statsMgr == s) {
- this.statsMgr = null;
- }
- }
-
- IPluginOutConnectionService connectionPluginOutService;
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionPluginOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionPluginOutService == s) {
- connectionPluginOutService = null;
- }
- }
-
- private void removeNodeConnector(String container,
- NodeConnector nodeConnector) {
- List<TopoEdgeUpdate> teuList = new ArrayList<TopoEdgeUpdate>();
- Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
- .get(container);
- if (edgePropsMap == null) {
- return;
- }
-
- // Remove edge in one direction
- Pair<Edge, Set<Property>> edgeProps = edgePropsMap.get(nodeConnector);
- if (edgeProps == null) {
- return;
- }
- teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null,
- UpdateType.REMOVED));
-
- // Remove edge in another direction
- edgeProps = edgePropsMap
- .get(edgeProps.getLeft().getHeadNodeConnector());
- if (edgeProps == null) {
- return;
- }
- teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null,
- UpdateType.REMOVED));
-
- // Update in one shot
- notifyEdge(container, teuList);
- }
-
- /**
- * Update local cache and return true if it needs to notify upper layer
- * Topology listeners.
- *
- * @param container
- * The network container
- * @param edge
- * The edge
- * @param type
- * The update type
- * @param props
- * The edge properties
- * @return true if it needs to notify upper layer Topology listeners
- */
- private boolean updateLocalEdgeMap(String container, Edge edge,
- UpdateType type, Set<Property> props) {
- ConcurrentMap<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
- .get(container);
- NodeConnector src = edge.getTailNodeConnector();
- Pair<Edge, Set<Property>> edgeProps = new ImmutablePair<Edge, Set<Property>>(
- edge, props);
- boolean rv = false;
-
- switch (type) {
- case ADDED:
- case CHANGED:
- if (edgePropsMap == null) {
- edgePropsMap = new ConcurrentHashMap<NodeConnector, Pair<Edge, Set<Property>>>();
- rv = true;
- } else {
- if (edgePropsMap.containsKey(src)
- && edgePropsMap.get(src).equals(edgeProps)) {
- // Entry already exists. No update.
- rv = false;
- } else {
- rv = true;
- }
- }
- if (rv) {
- edgePropsMap.put(src, edgeProps);
- edgeMap.put(container, edgePropsMap);
- }
- break;
- case REMOVED:
- if ((edgePropsMap != null) && edgePropsMap.containsKey(src)) {
- edgePropsMap.remove(src);
- if (edgePropsMap.isEmpty()) {
- edgeMap.remove(container);
- } else {
- edgeMap.put(container, edgePropsMap);
- }
- rv = true;
- }
- break;
- default:
- logger.debug(
- "notifyLocalEdgeMap: invalid {} for Edge {} in container {}",
- new Object[] { type.getName(), edge, container });
- }
-
- if (rv) {
- logger.debug(
- "notifyLocalEdgeMap: {} for Edge {} in container {}",
- new Object[] { type.getName(), edge, container });
- }
-
- return rv;
- }
-
- private void notifyEdge(String container, Edge edge, UpdateType type,
- Set<Property> props) {
- boolean notifyListeners;
-
- // Update local cache
- notifyListeners = updateLocalEdgeMap(container, edge, type, props);
-
- // Prepare to update TopologyService
- if (notifyListeners) {
- notifyQ.add(new NotifyEntry(container, new TopoEdgeUpdate(edge, props,
- type)));
- logger.debug("notifyEdge: {} Edge {} in container {}",
- new Object[] { type.getName(), edge, container });
- }
- }
-
- private void notifyEdge(String container, List<TopoEdgeUpdate> etuList) {
- if (etuList == null) {
- return;
- }
-
- Edge edge;
- UpdateType type;
- List<TopoEdgeUpdate> etuNotifyList = new ArrayList<TopoEdgeUpdate>();
- boolean notifyListeners = false, rv;
-
- for (TopoEdgeUpdate etu : etuList) {
- edge = etu.getEdge();
- type = etu.getUpdateType();
-
- // Update local cache
- rv = updateLocalEdgeMap(container, edge, type, etu.getProperty());
- if (rv) {
- if (!notifyListeners) {
- notifyListeners = true;
- }
- etuNotifyList.add(etu);
- logger.debug(
- "notifyEdge(TopoEdgeUpdate): {} Edge {} in container {}",
- new Object[] { type.getName(), edge, container });
- }
- }
-
- // Prepare to update TopologyService
- if (notifyListeners) {
- notifyQ.add(new NotifyEntry(container, etuNotifyList));
- logger.debug("notifyEdge(TopoEdgeUpdate): add notifyQ");
- }
- }
-
- @Override
- public void notifyEdge(Edge edge, UpdateType type, Set<Property> props) {
- if ((edge == null) || (type == null)) {
- return;
- }
-
- // Notify default container
- notifyEdge(GlobalConstants.DEFAULT.toString(), edge, type, props);
-
- // Notify the corresponding containers
- List<String> containers = getEdgeContainers(edge);
- if (containers != null) {
- for (String container : containers) {
- notifyEdge(container, edge, type, props);
- }
- }
- }
-
- /*
- * Return a list of containers the edge associated with
- */
- private List<String> getEdgeContainers(Edge edge) {
- NodeConnector src = edge.getTailNodeConnector(), dst = edge
- .getHeadNodeConnector();
-
- if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- /* Find the common containers for both ends */
- List<String> srcContainers = this.containerMap.get(src), dstContainers = this.containerMap
- .get(dst), cmnContainers = null;
- if ((srcContainers != null) && (dstContainers != null)) {
- cmnContainers = new ArrayList<String>(srcContainers);
- cmnContainers.retainAll(dstContainers);
- }
- return cmnContainers;
- } else {
- /*
- * If the neighbor is part of a monitored production network, get
- * the containers that the edge port belongs to
- */
- return this.containerMap.get(dst);
- }
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag,
- short newTag, UpdateType t) {
- }
-
- @Override
- public void containerFlowUpdated(String containerName,
- ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t) {
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p,
- UpdateType t) {
- if (this.containerMap == null) {
- logger.error("containerMap is NULL");
- return;
- }
- List<String> containers = this.containerMap.get(p);
- if (containers == null) {
- containers = new CopyOnWriteArrayList<String>();
- }
- boolean updateMap = false;
- switch (t) {
- case ADDED:
- if (!containers.contains(containerName)) {
- containers.add(containerName);
- updateMap = true;
- }
- break;
- case REMOVED:
- if (containers.contains(containerName)) {
- containers.remove(containerName);
- updateMap = true;
- removeNodeConnector(containerName, p);
- }
- break;
- case CHANGED:
- break;
- }
- if (updateMap) {
- if (containers.isEmpty()) {
- // Do cleanup to reduce memory footprint if no
- // elements to be tracked
- this.containerMap.remove(p);
- } else {
- this.containerMap.put(p, containers);
- }
- }
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // do nothing
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
- .getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this,
- null);
- }
-
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("---Topology Service Shim---\n");
- help.append("\t pem [container] - Print edgeMap entries");
- help.append(" for a given container\n");
- return help.toString();
- }
-
- public void _pem(CommandInterpreter ci) {
- String container = ci.nextArgument();
- if (container == null) {
- container = GlobalConstants.DEFAULT.toString();
- }
-
- ci.println("Container: " + container);
- ci.println(" Edge Bandwidth");
-
- Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
- .get(container);
- if (edgePropsMap == null) {
- return;
- }
- int count = 0;
- for (Pair<Edge, Set<Property>> edgeProps : edgePropsMap.values()) {
- if (edgeProps == null) {
- continue;
- }
-
- long bw = 0;
- Set<Property> props = edgeProps.getRight();
- if (props != null) {
- for (Property prop : props) {
- if (prop.getName().equals(Bandwidth.BandwidthPropName)) {
- bw = ((Bandwidth) prop).getValue();
- }
- }
- }
- count++;
- ci.println(edgeProps.getLeft() + " " + bw);
- }
- ci.println("Total number of Edges: " + count);
- }
-
- public void _bwfactor(CommandInterpreter ci) {
- String factorString = ci.nextArgument();
- if (factorString == null) {
- ci.println("Bw threshold: " + this.bwThresholdFactor);
- ci.println("Insert a non null bw threshold");
- return;
- }
- bwThresholdFactor = Float.parseFloat(factorString);
- ci.println("New Bw threshold: " + this.bwThresholdFactor);
- }
-
- /**
- * This method will trigger topology updates to be sent toward SAL. SAL then
- * pushes the updates to ALL the applications that have registered as
- * listeners for this service. SAL has no way of knowing which application
- * requested for the refresh.
- *
- * As an example of this case, is stopping and starting the Topology
- * Manager. When the topology Manager is stopped, and restarted, it will no
- * longer have the latest topology. Hence, a request is sent here.
- *
- * @param containerName
- * @return void
- */
- @Override
- public void requestRefresh(String containerName) {
- // wake up a bulk update thread and exit
- // the thread will execute the bulkUpdate()
- bulkNotifyQ.add(containerName);
- }
-
- /**
- * Reading the current topology database, the method will replay all the
- * edge updates for the ITopologyServiceShimListener instance in the given
- * container, which will in turn publish them toward SAL.
- *
- * @param containerName
- */
- private void TopologyBulkUpdate(String containerName) {
- Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropMap = null;
-
- logger.debug("Try bulk update for container:{}", containerName);
- edgePropMap = edgeMap.get(containerName);
- if (edgePropMap == null) {
- logger.debug("No edges known for container:{}", containerName);
- return;
- }
- ITopologyServiceShimListener topologServiceShimListener = topologyServiceShimListeners
- .get(containerName);
- if (topologServiceShimListener == null) {
- logger.debug("No topology service shim listener for container:{}",
- containerName);
- return;
- }
- int i = 0;
- List<TopoEdgeUpdate> teuList = new ArrayList<TopoEdgeUpdate>();
- for (Pair<Edge, Set<Property>> edgeProps : edgePropMap.values()) {
- if (edgeProps != null) {
- i++;
- teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), edgeProps
- .getRight(), UpdateType.ADDED));
- logger.trace("Add edge {}", edgeProps.getLeft());
- }
- }
- if (i > 0) {
- topologServiceShimListener.edgeUpdate(teuList);
- }
- logger.debug("Sent {} updates", i);
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- List<String> containers = new ArrayList<String>();
- List<String> conList = this.containerMap.get(nodeConnector);
-
- containers.add(GlobalConstants.DEFAULT.toString());
- if (conList != null) {
- containers.addAll(conList);
- }
-
- switch (type) {
- case ADDED:
- break;
- case CHANGED:
- if (props == null) {
- break;
- }
-
- boolean rmEdge = false;
- for (Property prop : props) {
- if (((prop instanceof Config) && (((Config) prop).getValue() != Config.ADMIN_UP))
- || ((prop instanceof State) && (((State) prop)
- .getValue() != State.EDGE_UP))) {
- /*
- * If port admin down or link down, remove the edges
- * associated with the port
- */
- rmEdge = true;
- break;
- }
- }
-
- if (rmEdge) {
- for (String cName : containers) {
- removeNodeConnector(cName, nodeConnector);
- }
- }
- break;
- case REMOVED:
- for (String cName : containers) {
- removeNodeConnector(cName, nodeConnector);
- }
- break;
- default:
- break;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.util.Dictionary;
-import java.util.List;
-import org.apache.felix.dm.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.topology.IPluginInTopologyService;
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
-import org.opendaylight.openflowplugin.openflow.IRefreshInternalProvider;
-import org.opendaylight.openflowplugin.openflow.ITopologyServiceShimListener;
-
-public class TopologyServices implements ITopologyServiceShimListener,
- IPluginInTopologyService {
- protected static final Logger logger = LoggerFactory
- .getLogger(TopologyServices.class);
- private IPluginOutTopologyService salTopoService = null;
- private IRefreshInternalProvider topoRefreshService = null;
- private IPluginOutConnectionService connectionOutService;
- private String containerName;
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- @SuppressWarnings("unchecked")
- void init(Component c) {
- logger.trace("INIT called!");
- Dictionary<Object, Object> props = c.getServiceProperties();
- containerName = (props != null) ? (String) props.get("containerName")
- : null;
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- logger.trace("DESTROY called!");
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- logger.trace("START called!");
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- logger.trace("STOP called!");
- }
-
- /**
- * Retrieve SAL service IPluginOutTopologyService
- *
- * @param s
- * Called by Dependency Manager as soon as the SAL service is
- * available
- */
- public void setPluginOutTopologyService(IPluginOutTopologyService s) {
- logger.trace("Setting IPluginOutTopologyService to: {}", s);
- this.salTopoService = s;
- }
-
- /**
- * called when SAL service IPluginOutTopologyService is no longer available
- *
- * @param s
- * Called by Dependency Manager as soon as the SAL service is
- * unavailable
- */
- public void unsetPluginOutTopologyService(IPluginOutTopologyService s) {
- if (this.salTopoService == s) {
- logger.trace("UNSetting IPluginOutTopologyService from: {}", s);
- this.salTopoService = null;
- }
- }
-
- /**
- * Retrieve OF protocol_plugin service IRefreshInternalProvider
- *
- * @param s
- * Called by Dependency Manager as soon as the SAL service is
- * available
- */
- public void setRefreshInternalProvider(IRefreshInternalProvider s) {
- logger.trace("Setting IRefreshInternalProvider to: {}", s);
- this.topoRefreshService = s;
- }
-
- /**
- * called when OF protocol_plugin service IRefreshInternalProvider is no
- * longer available
- *
- * @param s
- * Called by Dependency Manager as soon as the SAL service is
- * unavailable
- */
- public void unsetRefreshInternalProvider(IRefreshInternalProvider s) {
- if (this.topoRefreshService == s) {
- logger.trace("UNSetting IRefreshInternalProvider from: {}", s);
- this.topoRefreshService = null;
- }
- }
-
- @Override
- public void edgeUpdate(List<TopoEdgeUpdate> topoedgeupdateList) {
- if (this.salTopoService != null) {
- this.salTopoService.edgeUpdate(topoedgeupdateList);
- }
- }
-
- @Override
- public void sollicitRefresh() {
- logger.debug("Got a request to refresh topology");
- topoRefreshService.requestRefresh(containerName);
- }
-
- @Override
- public void edgeOverUtilized(Edge edge) {
- if (this.salTopoService != null) {
- this.salTopoService.edgeOverUtilized(edge);
- }
- }
-
- @Override
- public void edgeUtilBackToNormal(Edge edge) {
- if (this.salTopoService != null) {
- this.salTopoService.edgeUtilBackToNormal(edge);
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.internal;
-
-import java.nio.ByteBuffer;
-
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6Error;
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFError.OFBadActionCode;
-import org.openflow.protocol.OFError.OFBadRequestCode;
-import org.openflow.protocol.OFError.OFErrorType;
-import org.openflow.protocol.OFError.OFFlowModFailedCode;
-import org.openflow.protocol.OFError.OFHelloFailedCode;
-import org.openflow.protocol.OFError.OFPortModFailedCode;
-import org.openflow.protocol.OFError.OFQueueOpFailedCode;
-
-public final class Utils {
-
- private Utils() { //prevent instantiation
- throw new AssertionError();
- }
- static String getOFErrorString(OFError error) {
- // Handle VENDOR extension errors here
- if (error.getErrorType() == V6Error.NICIRA_VENDOR_ERRORTYPE) {
- V6Error er = new V6Error(error);
- byte[] b = error.getError();
- ByteBuffer bb = ByteBuffer.allocate(b.length);
- bb.put(b);
- bb.rewind();
- er.readFrom(bb);
- return er.toString();
- }
-
- // Handle OF1.0 errors here
- OFErrorType et = OFErrorType.values()[0xffff & error.getErrorType()];
- String errorStr = "Error : " + et.toString();
- switch (et) {
- case OFPET_HELLO_FAILED:
- OFHelloFailedCode hfc = OFHelloFailedCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + hfc.toString();
- break;
- case OFPET_BAD_REQUEST:
- OFBadRequestCode brc = OFBadRequestCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + brc.toString();
- break;
- case OFPET_BAD_ACTION:
- OFBadActionCode bac = OFBadActionCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + bac.toString();
- break;
- case OFPET_FLOW_MOD_FAILED:
- OFFlowModFailedCode fmfc = OFFlowModFailedCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + fmfc.toString();
- break;
- case OFPET_PORT_MOD_FAILED:
- OFPortModFailedCode pmfc = OFPortModFailedCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + pmfc.toString();
- break;
- case OFPET_QUEUE_OP_FAILED:
- OFQueueOpFailedCode qofc = OFQueueOpFailedCode.values()[0xffff & error
- .getErrorCode()];
- errorStr += " " + qofc.toString();
- break;
- default:
- break;
- }
- return errorStr;
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.openflow.md;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.MDController;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Openflow protocol plugin Activator
+ */
+public class Activator extends ComponentActivatorAbstractBase {
+ protected static final Logger logger = LoggerFactory.getLogger(Activator.class);
+
+ private OpenflowPluginProvider pluginProvider = new OpenflowPluginProvider();
+
+ /**
+ * Function called when the activator starts just after some initializations
+ * are done by the ComponentActivatorAbstractBase.
+ *
+ */
+ public void init() {
+ }
+
+ /**
+ * Function called when the activator stops just before the cleanup done by
+ * ComponentActivatorAbstractBase
+ *
+ */
+ public void destroy() {
+ }
+
+ @Override
+ public void start(BundleContext arg0) {
+ super.start(arg0);
+ pluginProvider.setContext(arg0);
+ }
+
+ /**
+ * Function that is used to communicate to dependency manager the list of
+ * known implementations for services inside a container
+ *
+ *
+ * @return An array containing all the CLASS objects that will be
+ * instantiated in order to get an fully working implementation
+ * Object
+ */
+ public Object[] getImplementations() {
+ Object[] res = {};
+ return res;
+ }
+
+ /**
+ * Function that is called when configuration of the dependencies is
+ * required.
+ *
+ * @param c
+ * dependency manager Component object, used for configuring the
+ * dependencies exported and imported
+ * @param imp
+ * Implementation class that is being configured, needed as long
+ * as the same routine can configure multiple implementations
+ * @param containerName
+ * The containerName being configured, this allow also optional
+ * per-container different behavior if needed, usually should not
+ * be the case though.
+ */
+ public void configureInstance(Component c, Object imp, String containerName) {
+
+ }
+
+ /**
+ * Function that is used to communicate to dependency manager the list of
+ * known implementations for services that are container independent.
+ *
+ *
+ * @return An array containing all the CLASS objects that will be
+ * instantiated in order to get an fully working implementation
+ * Object
+ */
+ public Object[] getGlobalImplementations() {
+ Object[] res = { MDController.class, pluginProvider };
+ return res;
+ }
+
+ /**
+ * Function that is called when configuration of the dependencies is
+ * required.
+ *
+ * @param c
+ * dependency manager Component object, used for configuring the
+ * dependencies exported and imported
+ * @param imp
+ * Implementation class that is being configured, needed as long
+ * as the same routine can configure multiple implementations
+ */
+ public void configureGlobalInstance(Component c, Object imp) {
+
+ if (imp == pluginProvider) {
+ // c.setInterface(new String[] { IDiscoveryListener.class.getName(),
+ // IContainerListener.class.getName(),
+ // IRefreshInternalProvider.class.getName(),
+ // IInventoryShimExternalListener.class.getName() }, null);
+ c.add(createServiceDependency().setService(BindingAwareBroker.class)
+ .setCallbacks("setBroker", "unsetBroker").setRequired(true));
+ c.add(createServiceDependency().setService(SwitchConnectionProvider.class)
+ .setCallbacks("setSwitchConnectionProvider", "unsetSwitchConnectionProvider").setRequired(true));
+ logger.debug("configuring Binding Aware Provider");
+ }
+ }
+
+}
--- /dev/null
+package org.opendaylight.openflowplugin.openflow.md;
+
+public class OFConstants {
+
+ public static final short OFPP_NORMAL = ((short)0xfffa);
+ public static final short OFPP_ALL = ((short)0xfffc);
+ public static final short OFPP_LOCAL = ((short)0xfffe);
+
+}
import java.util.List;
import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.openflowplugin.openflow.md.OFConstants;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValuesV10;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.openflow.protocol.OFPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Uri uri = outputAction.getOutputNodeConnector();
if (uri.getValue() == NodeConnectorIDType.ALL)
- portAction.setPort(new PortNumber((long) OFPort.OFPP_ALL.getValue()));
+ portAction.setPort(new PortNumber((long) OFConstants.OFPP_ALL));
if (uri.getValue() == NodeConnectorIDType.SWSTACK)
- portAction.setPort(new PortNumber((long) OFPort.OFPP_LOCAL.getValue()));
+ portAction.setPort(new PortNumber((long) OFConstants.OFPP_LOCAL));
if ((uri.getValue() == NodeConnectorIDType.HWPATH)
|| (uri.getValue() == NodeConnectorIDType.ONEPK)
|| (uri.getValue() == NodeConnectorIDType.PCEP2ONEPK)
|| (uri.getValue() == NodeConnectorIDType.PCEP2OPENFLOW)
|| (uri.getValue() == NodeConnectorIDType.PRODUCTION)) {
- portAction.setPort(new PortNumber((long) OFPort.OFPP_NORMAL.getValue()));
+ portAction.setPort(new PortNumber((long) OFConstants.OFPP_NORMAL));
}
if (uri.getValue() == NodeConnectorIDType.CONTROLLER) {
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.md.discovery;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.eclipse.osgi.framework.console.CommandInterpreter;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.openflow.protocol.OFPhysicalPort;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
-import org.opendaylight.controller.sal.core.Config;
-import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainerListener;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.State;
-import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.packet.Ethernet;
-import org.opendaylight.controller.sal.packet.LLDP;
-import org.opendaylight.controller.sal.packet.LLDPTLV;
-import org.opendaylight.controller.sal.packet.LinkEncap;
-import org.opendaylight.controller.sal.packet.PacketResult;
-import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.utils.EtherTypes;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.openflowplugin.openflow.IDataPacketListen;
-import org.opendaylight.openflowplugin.openflow.IDataPacketMux;
-import org.opendaylight.openflowplugin.openflow.IDiscoveryListener;
-import org.opendaylight.openflowplugin.openflow.IInventoryProvider;
-import org.opendaylight.openflowplugin.openflow.IInventoryShimExternalListener;
-import org.opendaylight.openflowplugin.openflow.core.IController;
-import org.opendaylight.openflowplugin.openflow.core.ISwitch;
-
-/**
- * The class describes neighbor discovery service for an OpenFlow network.
- */
-public class DiscoveryService implements IInventoryShimExternalListener, IDataPacketListen, IContainerListener,
- CommandProvider {
- private static Logger logger = LoggerFactory.getLogger(DiscoveryService.class);
- private IController controller = null;
- private IDiscoveryListener discoveryListener = null;
- private IInventoryProvider inventoryProvider = null;
- private IDataPacketMux iDataPacketMux = null;
- // High priority list containing newly added ports which will be served first
- private List<NodeConnector> readyListHi = null;
- // List containing all the ports which will be served periodically
- private List<NodeConnector> readyListLo = null;
- // Staging area during quiet period
- private List<NodeConnector> stagingList = null;
- // Wait for next discovery packet. The map contains the time elapsed since
- // the last received LLDP frame on each node connector
- private ConcurrentMap<NodeConnector, Integer> holdTime = null;
- // Allow one more retry for newly added ports. This map contains the time
- // period elapsed since last discovery pkt transmission on the port.
- private ConcurrentMap<NodeConnector, Integer> elapsedTime = null;
- // OpenFlow edges keyed by head connector
- private ConcurrentMap<NodeConnector, Edge> edgeMap = null;
- // The map contains aging entry keyed by head connector of Production edge
- private ConcurrentMap<NodeConnector, Integer> agingMap = null;
- // Production edges keyed by head connector
- private ConcurrentMap<NodeConnector, Edge> prodMap = null;
-
- private Timer discoveryTimer;
- private DiscoveryTimerTask discoveryTimerTask;
- private final static long discoveryTimerTick = 2L * 1000; // per tick in msec
- private int discoveryTimerTickCount = 0; // main tick counter
- // Max # of ports handled in one batch
- private int discoveryBatchMaxPorts;
- // Periodically restart batching process
- private int discoveryBatchRestartTicks;
- private int discoveryBatchPausePeriod = 2;
- // Pause after this point
- private int discoveryBatchPauseTicks;
- private int discoveryTimeoutTicks;
- private int discoveryThresholdTicks;
- private int discoveryAgeoutTicks;
- // multiple of discoveryBatchRestartTicks
- private int discoveryConsistencyCheckMultiple = 2;
- // CC tick counter
- private int discoveryConsistencyCheckTickCount;
- // # of times CC gets called
- private int discoveryConsistencyCheckCallingTimes = 0;
- // # of cases CC corrected
- private int discoveryConsistencyCheckCorrected = 0;
- // Enable or disable CC
- private boolean discoveryConsistencyCheckEnabled = true;
- // Enable or disable aging
- private boolean discoveryAgingEnabled = true;
- // Global flag to enable or disable LLDP snooping
- private boolean discoverySnoopingEnabled = true;
- // The list of ports that will not do LLDP snooping
- private List<NodeConnector> discoverySnoopingDisableList;
- private BlockingQueue<NodeConnector> transmitQ;
- private Thread transmitThread;
- private Boolean throttling = false; // if true, no more batching.
- private volatile Boolean shuttingDown = false;
-
- private LLDPTLV chassisIdTlv, portIdTlv, ttlTlv, customTlv;
- private IPluginOutConnectionService connectionOutService;
-
- class DiscoveryTransmit implements Runnable {
- private final BlockingQueue<NodeConnector> transmitQ;
-
- DiscoveryTransmit(BlockingQueue<NodeConnector> transmitQ) {
- this.transmitQ = transmitQ;
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- NodeConnector nodeConnector = transmitQ.take();
- RawPacket outPkt = createDiscoveryPacket(nodeConnector);
- sendDiscoveryPacket(nodeConnector, outPkt);
- nodeConnector = null;
- } catch (InterruptedException e1) {
- logger.warn("DiscoveryTransmit interupted", e1.getMessage());
- if (shuttingDown) {
- return;
- }
- } catch (Exception e2) {
- logger.error("", e2);
- }
- }
- }
- }
-
- class DiscoveryTimerTask extends TimerTask {
- @Override
- public void run() {
- checkTimeout();
- checkAging();
- doConsistencyCheck();
- doDiscovery();
- }
- }
-
- public enum DiscoveryPeriod {
- INTERVAL (300),
- AGEOUT (120),
- THRESHOLD (30);
-
- private int time; // sec
- private int tick; // tick
-
- DiscoveryPeriod(int time) {
- this.time = time;
- this.tick = time2Tick(time);
- }
-
- public int getTime() {
- return time;
- }
-
- public void setTime(int time) {
- this.time = time;
- this.tick = time2Tick(time);
- }
-
- public int getTick() {
- return tick;
- }
-
- public void setTick(int tick) {
- this.time = tick2Time(tick);
- this.tick = tick;
- }
-
- private int time2Tick(int time) {
- return (int) (time / (discoveryTimerTick / 1000));
- }
-
- private int tick2Time(int tick) {
- return (int) (tick * (discoveryTimerTick / 1000));
- }
- }
-
- private RawPacket createDiscoveryPacket(NodeConnector nodeConnector) {
- String nodeId = HexEncode.longToHexString((Long) nodeConnector.getNode().getID());
-
- // Create LLDP ChassisID TLV
- byte[] cidValue = LLDPTLV.createChassisIDTLVValue(nodeId);
- chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue()).setLength((short) cidValue.length)
- .setValue(cidValue);
-
- // Create LLDP PortID TLV
- String portId = nodeConnector.getNodeConnectorIDString();
- byte[] pidValue = LLDPTLV.createPortIDTLVValue(portId);
- portIdTlv.setType(LLDPTLV.TLVType.PortID.getValue()).setLength((short) pidValue.length).setValue(pidValue);
-
- // Create LLDP Custom TLV
- byte[] customValue = LLDPTLV.createCustomTLVValue(nodeConnector.toString());
- customTlv.setType(LLDPTLV.TLVType.Custom.getValue()).setLength((short) customValue.length)
- .setValue(customValue);
-
- // Create LLDP Custom Option list
- List<LLDPTLV> customList = new ArrayList<LLDPTLV>();
- customList.add(customTlv);
-
- // Create discovery pkt
- LLDP discoveryPkt = new LLDP();
- discoveryPkt.setChassisId(chassisIdTlv).setPortId(portIdTlv).setTtl(ttlTlv).setOptionalTLVList(customList);
-
- RawPacket rawPkt = null;
- try {
- // Create ethernet pkt
- byte[] sourceMac = getSourceMACFromNodeID(nodeId);
- Ethernet ethPkt = new Ethernet();
- ethPkt.setSourceMACAddress(sourceMac).setDestinationMACAddress(LLDP.LLDPMulticastMac)
- .setEtherType(EtherTypes.LLDP.shortValue()).setPayload(discoveryPkt);
-
- byte[] data = ethPkt.serialize();
- rawPkt = new RawPacket(data);
- rawPkt.setOutgoingNodeConnector(nodeConnector);
- } catch (ConstructionException cex) {
- logger.warn("RawPacket creation caught exception {}", cex.getMessage());
- } catch (Exception e) {
- logger.error("Failed to serialize the LLDP packet: " + e);
- }
-
- return rawPkt;
- }
-
- private void sendDiscoveryPacket(NodeConnector nodeConnector, RawPacket outPkt) {
- if (nodeConnector == null) {
- logger.debug("Can not send discovery packet out since nodeConnector is null");
- return;
- }
-
- if (!connectionOutService.isLocal(nodeConnector.getNode())) {
- logger.debug("Discoery packets will not be sent to {} in a non-master controller", nodeConnector.toString());
- return;
- }
-
- if (outPkt == null) {
- logger.debug("Can not send discovery packet out since outPkt is null");
- return;
- }
-
- long sid = (Long) nodeConnector.getNode().getID();
- ISwitch sw = controller.getSwitches().get(sid);
-
- if (sw == null) {
- logger.debug("Can not send discovery packet out since switch {} is null", sid);
- return;
- }
-
- if (!sw.isOperational()) {
- logger.debug("Can not send discovery packet out since switch {} is not operational", sw);
- return;
- }
-
- if (this.iDataPacketMux == null) {
- logger.debug("Can not send discovery packet out since DataPacket service is not available");
- return;
- }
-
- logger.trace("Sending topology discovery pkt thru {}", nodeConnector);
- this.iDataPacketMux.transmitDataPacket(outPkt);
- }
-
- @Override
- public PacketResult receiveDataPacket(RawPacket inPkt) {
- if (inPkt == null) {
- logger.debug("Ignoring null packet");
- return PacketResult.IGNORED;
- }
-
- byte[] data = inPkt.getPacketData();
- if (data.length <= 0) {
- logger.trace("Ignoring zero length packet");
- return PacketResult.IGNORED;
- }
-
- if (!inPkt.getEncap().equals(LinkEncap.ETHERNET)) {
- logger.trace("Ignoring non ethernet packet");
- return PacketResult.IGNORED;
- }
-
- NodeConnector nodeConnector = inPkt.getIncomingNodeConnector();
- if (((Short) nodeConnector.getID()).equals(NodeConnector.SPECIALNODECONNECTORID)) {
- logger.trace("Ignoring ethernet packet received on special port: "
- + inPkt.getIncomingNodeConnector().toString());
- return PacketResult.IGNORED;
- }
-
- if (!connectionOutService.isLocal(nodeConnector.getNode())) {
- logger.debug("Discoery packets will not be processed from {} in a non-master controller", nodeConnector.toString());
- return PacketResult.IGNORED;
- }
-
- Ethernet ethPkt = new Ethernet();
- try {
- ethPkt.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
- } catch (Exception e) {
- logger.warn("Failed to decode LLDP packet from {}: {}", inPkt.getIncomingNodeConnector(), e);
- return PacketResult.IGNORED;
- }
-
- if (ethPkt.getPayload() instanceof LLDP) {
- NodeConnector dst = inPkt.getIncomingNodeConnector();
- if (isEnabled(dst)) {
- if (!processDiscoveryPacket(dst, ethPkt)) {
- // Snoop the discovery pkt if not generated from us
- snoopDiscoveryPacket(dst, ethPkt);
- }
- return PacketResult.CONSUME;
- }
- }
- return PacketResult.IGNORED;
- }
-
- /*
- * Snoop incoming discovery frames generated by the production network
- * neighbor switch
- */
- private void snoopDiscoveryPacket(NodeConnector dstNodeConnector, Ethernet ethPkt) {
- if (!this.discoverySnoopingEnabled || discoverySnoopingDisableList.contains(dstNodeConnector)) {
- logger.trace("Discarded received discovery packet on {} since snooping is turned off", dstNodeConnector);
- return;
- }
-
- if ((dstNodeConnector == null) || (ethPkt == null)) {
- logger.trace("Quit snooping discovery packet: Null node connector or packet");
- return;
- }
-
- LLDP lldp = (LLDP) ethPkt.getPayload();
-
- try {
- String nodeId = LLDPTLV.getHexStringValue(lldp.getChassisId().getValue(), lldp.getChassisId().getLength());
- String portId = LLDPTLV.getStringValue(lldp.getPortId().getValue(), lldp.getPortId().getLength());
- byte[] systemNameBytes = null;
- // get system name if present in the LLDP pkt
- for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
- if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
- systemNameBytes = lldptlv.getValue();
- break;
- }
- }
- String nodeName = (systemNameBytes == null) ? nodeId
- : new String(systemNameBytes, Charset.defaultCharset());
- Node srcNode = new Node(Node.NodeIDType.PRODUCTION, nodeName);
- NodeConnector srcNodeConnector = NodeConnectorCreator.createNodeConnector(
- NodeConnector.NodeConnectorIDType.PRODUCTION, portId, srcNode);
-
- Edge edge = null;
- Set<Property> props = null;
- edge = new Edge(srcNodeConnector, dstNodeConnector);
- props = getProps(dstNodeConnector);
-
- updateProdEdge(edge, props);
- } catch (Exception e) {
- logger.warn("Caught exception ", e);
- }
- }
-
- /*
- * Handle discovery frames generated by our controller
- *
- * @return true if it's a success
- */
- private boolean processDiscoveryPacket(NodeConnector dstNodeConnector, Ethernet ethPkt) {
- if ((dstNodeConnector == null) || (ethPkt == null)) {
- logger.trace("Ignoring processing of discovery packet: Null node connector or packet");
- return false;
- }
-
- logger.trace("Handle discovery packet {} from {}", ethPkt, dstNodeConnector);
-
- LLDP lldp = (LLDP) ethPkt.getPayload();
-
- List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
- if (optionalTLVList == null) {
- logger.info("The discovery packet with null custom option from {}", dstNodeConnector);
- return false;
- }
-
- Node srcNode = null;
- NodeConnector srcNodeConnector = null;
- for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
- if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
- String ncString = LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength());
- srcNodeConnector = NodeConnector.fromString(ncString);
- if (srcNodeConnector != null) {
- srcNode = srcNodeConnector.getNode();
- }
- }
- }
-
- if ((srcNode == null) || (srcNodeConnector == null)) {
- logger.trace("Received non-controller generated discovery packet from {}", dstNodeConnector);
- return false;
- }
-
- // push it out to Topology
- Edge edge = null;
- Set<Property> props = null;
- try {
- edge = new Edge(srcNodeConnector, dstNodeConnector);
- props = getProps(dstNodeConnector);
- } catch (ConstructionException e) {
- logger.error("Caught exception ", e);
- }
- addEdge(edge, props);
-
- logger.trace("Received discovery packet for Edge {}", edge);
-
- return true;
- }
-
- public Map<String, Property> getPropMap(NodeConnector nodeConnector) {
- if (nodeConnector == null) {
- return null;
- }
-
- if (inventoryProvider == null) {
- return null;
- }
-
- Map<NodeConnector, Map<String, Property>> props = inventoryProvider.getNodeConnectorProps(false);
- if (props == null) {
- return null;
- }
-
- return props.get(nodeConnector);
- }
-
- public Property getProp(NodeConnector nodeConnector, String propName) {
- Map<String, Property> propMap = getPropMap(nodeConnector);
- if (propMap == null) {
- return null;
- }
-
- Property prop = propMap.get(propName);
- return prop;
- }
-
- public Set<Property> getProps(NodeConnector nodeConnector) {
- Map<String, Property> propMap = getPropMap(nodeConnector);
- if (propMap == null) {
- return null;
- }
-
- Set<Property> props = new HashSet<Property>(propMap.values());
- return props;
- }
-
- private boolean isEnabled(NodeConnector nodeConnector) {
- if (nodeConnector == null) {
- return false;
- }
-
- Config config = (Config) getProp(nodeConnector, Config.ConfigPropName);
- State state = (State) getProp(nodeConnector, State.StatePropName);
- return ((config != null) && (config.getValue() == Config.ADMIN_UP) && (state != null) && (state.getValue() == State.EDGE_UP));
- }
-
- private boolean isTracked(NodeConnector nodeConnector) {
- if (readyListHi.contains(nodeConnector)) {
- return true;
- }
-
- if (readyListLo.contains(nodeConnector)) {
- return true;
- }
-
- if (holdTime.keySet().contains(nodeConnector)) {
- return true;
- }
-
- if (stagingList.contains(nodeConnector)) {
- return true;
- }
-
- return false;
- }
-
- private Set<NodeConnector> getWorkingSet() {
- Set<NodeConnector> workingSet = new HashSet<NodeConnector>();
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
-
- for (NodeConnector nodeConnector : readyListHi) {
- if (isOverLimit(workingSet.size())) {
- break;
- }
-
- workingSet.add(nodeConnector);
- removeSet.add(nodeConnector);
-
- // Put it in the map and start the timer. It may need retry.
- elapsedTime.put(nodeConnector, 0);
- }
- readyListHi.removeAll(removeSet);
-
- removeSet.clear();
- for (NodeConnector nodeConnector : readyListLo) {
- if (isOverLimit(workingSet.size())) {
- break;
- }
-
- workingSet.add(nodeConnector);
- removeSet.add(nodeConnector);
- }
- readyListLo.removeAll(removeSet);
-
- return workingSet;
- }
-
- private Boolean isOverLimit(int size) {
- return ((size >= discoveryBatchMaxPorts) && !throttling);
- }
-
- private void addDiscovery() {
- Map<Long, ISwitch> switches = controller.getSwitches();
- Set<Long> sidSet = switches.keySet();
- if (sidSet == null) {
- return;
- }
- for (Long sid : sidSet) {
- Node node = NodeCreator.createOFNode(sid);
- addDiscovery(node);
- }
- }
-
- private void addDiscovery(Node node) {
- Map<Long, ISwitch> switches = controller.getSwitches();
- ISwitch sw = switches.get(node.getID());
- List<OFPhysicalPort> ports = sw.getEnabledPorts();
- if (ports == null) {
- return;
- }
- for (OFPhysicalPort port : ports) {
- NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
- if (!readyListHi.contains(nodeConnector)) {
- readyListHi.add(nodeConnector);
- }
- }
- }
-
- private void addDiscovery(NodeConnector nodeConnector) {
- if (isTracked(nodeConnector)) {
- return;
- }
-
- readyListHi.add(nodeConnector);
- }
-
- private Set<NodeConnector> getRemoveSet(Collection<NodeConnector> c, Node node) {
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- if (c == null) {
- return removeSet;
- }
- for (NodeConnector nodeConnector : c) {
- if (node.equals(nodeConnector.getNode())) {
- Edge edge1 = edgeMap.get(nodeConnector);
- if (edge1 != null) {
- removeSet.add(nodeConnector);
-
- // check reverse direction
- Edge edge2 = edgeMap.get(edge1.getTailNodeConnector());
- if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) {
- removeSet.add(edge2.getHeadNodeConnector());
- }
- }
- }
- }
- return removeSet;
- }
-
- private void removeDiscovery(Node node) {
- Set<NodeConnector> removeSet;
-
- removeSet = getRemoveSet(readyListHi, node);
- readyListHi.removeAll(removeSet);
-
- removeSet = getRemoveSet(readyListLo, node);
- readyListLo.removeAll(removeSet);
-
- removeSet = getRemoveSet(stagingList, node);
- stagingList.removeAll(removeSet);
-
- removeSet = getRemoveSet(holdTime.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- holdTime.remove(nodeConnector);
- }
-
- removeSet = getRemoveSet(edgeMap.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector, false);
- }
-
- removeSet = getRemoveSet(prodMap.keySet(), node);
- for (NodeConnector nodeConnector : removeSet) {
- removeProdEdge(nodeConnector);
- }
- }
-
- private void removeDiscovery(NodeConnector nodeConnector) {
- readyListHi.remove(nodeConnector);
- readyListLo.remove(nodeConnector);
- stagingList.remove(nodeConnector);
- holdTime.remove(nodeConnector);
- removeEdge(nodeConnector, false);
- removeProdEdge(nodeConnector);
- }
-
- private void checkTimeout() {
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- int ticks;
-
- Set<NodeConnector> monitorSet = holdTime.keySet();
- if (monitorSet != null) {
- for (NodeConnector nodeConnector : monitorSet) {
- ticks = holdTime.get(nodeConnector);
- holdTime.put(nodeConnector, ++ticks);
- if (ticks >= discoveryTimeoutTicks) {
- // timeout the edge
- removeSet.add(nodeConnector);
- logger.trace("Discovery timeout {}", nodeConnector);
- }
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector);
- }
-
- Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
- Set<NodeConnector> ncSet = elapsedTime.keySet();
- if ((ncSet != null) && (ncSet.size() > 0)) {
- for (NodeConnector nodeConnector : ncSet) {
- ticks = elapsedTime.get(nodeConnector);
- elapsedTime.put(nodeConnector, ++ticks);
- if (ticks >= discoveryThresholdTicks) {
- retrySet.add(nodeConnector);
- }
- }
-
- for (NodeConnector nodeConnector : retrySet) {
- // Allow one more retry
- readyListLo.add(nodeConnector);
- elapsedTime.remove(nodeConnector);
- if (connectionOutService.isLocal(nodeConnector.getNode())) {
- transmitQ.add(nodeConnector);
- }
- }
- }
- }
-
- private void checkAging() {
- if (!discoveryAgingEnabled) {
- return;
- }
-
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- int ticks;
-
- Set<NodeConnector> agingSet = agingMap.keySet();
- if (agingSet != null) {
- for (NodeConnector nodeConnector : agingSet) {
- ticks = agingMap.get(nodeConnector);
- agingMap.put(nodeConnector, ++ticks);
- if (ticks > discoveryAgeoutTicks) {
- // age out the edge
- removeSet.add(nodeConnector);
- logger.trace("Discovery age out {}", nodeConnector);
- }
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeProdEdge(nodeConnector);
- }
- }
-
- private void doDiscovery() {
- if (++discoveryTimerTickCount <= discoveryBatchPauseTicks) {
- for (NodeConnector nodeConnector : getWorkingSet()) {
- if (connectionOutService.isLocal(nodeConnector.getNode())) {
- transmitQ.add(nodeConnector);
- // Move to staging area after it's served
- if (!stagingList.contains(nodeConnector)) {
- stagingList.add(nodeConnector);
- }
- }
- }
- } else if (discoveryTimerTickCount >= discoveryBatchRestartTicks) {
- discoveryTimerTickCount = 0;
- for (NodeConnector nodeConnector : stagingList) {
- if (!readyListLo.contains(nodeConnector)) {
- readyListLo.add(nodeConnector);
- }
- }
- stagingList.removeAll(readyListLo);
- }
- }
-
- private void doConsistencyCheck() {
- if (!discoveryConsistencyCheckEnabled) {
- return;
- }
-
- if (++discoveryConsistencyCheckTickCount % getDiscoveryConsistencyCheckInterval() != 0) {
- return;
- }
-
- discoveryConsistencyCheckCallingTimes++;
-
- Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- Set<NodeConnector> ncSet = edgeMap.keySet();
- if (ncSet == null) {
- return;
- }
- for (NodeConnector nodeConnector : ncSet) {
- if (!isEnabled(nodeConnector)) {
- removeSet.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
- continue;
- }
-
- if (!isTracked(nodeConnector)) {
- stagingList.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
- continue;
- }
- }
-
- for (NodeConnector nodeConnector : removeSet) {
- removeEdge(nodeConnector, false);
- }
-
- // remove stale entries
- removeSet.clear();
- for (NodeConnector nodeConnector : stagingList) {
- if (!isEnabled(nodeConnector)) {
- removeSet.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
- }
- }
- stagingList.removeAll(removeSet);
-
- // Get a snapshot of all the existing switches
- Map<Long, ISwitch> switches = this.controller.getSwitches();
- for (ISwitch sw : switches.values()) {
- for (OFPhysicalPort port : sw.getEnabledPorts()) {
- Node node = NodeCreator.createOFNode(sw.getId());
- NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
- if (!isTracked(nodeConnector)) {
- stagingList.add(nodeConnector);
- discoveryConsistencyCheckCorrected++;
- logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
- }
- }
- }
- }
-
- private void addEdge(Edge edge, Set<Property> props) {
- if (edge == null) {
- return;
- }
-
- NodeConnector src = edge.getTailNodeConnector();
- NodeConnector dst = edge.getHeadNodeConnector();
- if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- holdTime.put(dst, 0);
- } else {
- agingMap.put(dst, 0);
- }
- elapsedTime.remove(src);
-
- // notify
- updateEdge(edge, UpdateType.ADDED, props);
- logger.trace("Add edge {}", edge);
- }
-
- /**
- * Update Production Edge
- *
- * @param edge
- * The Production Edge
- * @param props
- * Properties associated with the edge
- */
- private void updateProdEdge(Edge edge, Set<Property> props) {
- NodeConnector edgePort = edge.getHeadNodeConnector();
-
- /* Do not update in case there is an existing OpenFlow link */
- if (edgeMap.get(edgePort) != null) {
- logger.trace("Discarded edge {} since there is an existing OF link {}", edge, edgeMap.get(edgePort));
- return;
- }
-
- /* Look for any existing Production Edge */
- Edge oldEdge = prodMap.get(edgePort);
- if (oldEdge == null) {
- /* Let's add a new one */
- addEdge(edge, props);
- } else if (!edge.equals(oldEdge)) {
- /* Remove the old one first */
- removeProdEdge(oldEdge.getHeadNodeConnector());
- /* Then add the new one */
- addEdge(edge, props);
- } else {
- /* o/w, just reset the aging timer */
- NodeConnector dst = edge.getHeadNodeConnector();
- agingMap.put(dst, 0);
- }
- }
-
- /**
- * Remove Production Edge for a given edge port
- *
- * @param edgePort
- * The OF edge port
- */
- private void removeProdEdge(NodeConnector edgePort) {
- agingMap.remove(edgePort);
-
- Edge edge = null;
- Set<NodeConnector> prodKeySet = prodMap.keySet();
- if ((prodKeySet != null) && (prodKeySet.contains(edgePort))) {
- edge = prodMap.get(edgePort);
- prodMap.remove(edgePort);
- }
-
- // notify Topology
- if (this.discoveryListener != null) {
- this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
- }
- logger.trace("Remove edge {}", edge);
- }
-
- /*
- * Remove OpenFlow edge
- */
- private void removeEdge(NodeConnector nodeConnector, boolean stillEnabled) {
- holdTime.remove(nodeConnector);
- readyListLo.remove(nodeConnector);
- readyListHi.remove(nodeConnector);
-
- if (stillEnabled) {
- // keep discovering
- if (!stagingList.contains(nodeConnector)) {
- stagingList.add(nodeConnector);
- }
- } else {
- // stop it
- stagingList.remove(nodeConnector);
- }
-
- Edge edge = null;
- Set<NodeConnector> edgeKeySet = edgeMap.keySet();
- if ((edgeKeySet != null) && (edgeKeySet.contains(nodeConnector))) {
- edge = edgeMap.get(nodeConnector);
- edgeMap.remove(nodeConnector);
- }
-
- // notify Topology
- if (this.discoveryListener != null) {
- this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
- }
- logger.trace("Remove {}", nodeConnector);
- }
-
- private void removeEdge(NodeConnector nodeConnector) {
- removeEdge(nodeConnector, isEnabled(nodeConnector));
- }
-
- private void updateEdge(Edge edge, UpdateType type, Set<Property> props) {
- if (discoveryListener == null) {
- return;
- }
-
- this.discoveryListener.notifyEdge(edge, type, props);
-
- NodeConnector src = edge.getTailNodeConnector(), dst = edge.getHeadNodeConnector();
- if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- if (type == UpdateType.ADDED) {
- edgeMap.put(dst, edge);
- } else {
- edgeMap.remove(dst);
- }
- } else {
- /*
- * Save Production edge into different DB keyed by the Edge port
- */
- if (type == UpdateType.ADDED) {
- prodMap.put(dst, edge);
- } else {
- prodMap.remove(dst);
- }
- }
- }
-
- private void moveToReadyListHi(NodeConnector nodeConnector) {
- if (readyListLo.contains(nodeConnector)) {
- readyListLo.remove(nodeConnector);
- } else if (stagingList.contains(nodeConnector)) {
- stagingList.remove(nodeConnector);
- }
- readyListHi.add(nodeConnector);
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this, null);
- }
-
- private int getDiscoveryConsistencyCheckInterval() {
- return discoveryConsistencyCheckMultiple * discoveryBatchRestartTicks;
- }
-
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- help.append("---Topology Discovery---\n");
- help.append("\t prlh - Print readyListHi entries\n");
- help.append("\t prll - Print readyListLo entries\n");
- help.append("\t psl - Print stagingList entries\n");
- help.append("\t pht - Print hold time\n");
- help.append("\t pet - Print elapsed time\n");
- help.append("\t ptick - Print tick time in msec\n");
- help.append("\t pcc - Print CC info\n");
- help.append("\t psize - Print sizes of all the lists\n");
- help.append("\t ptm - Print timeout info\n");
- help.append("\t ecc - Enable CC\n");
- help.append("\t dcc - Disable CC\n");
- help.append("\t scc [multiple] - Set/show CC multiple and interval\n");
- help.append("\t sports [ports] - Set/show max ports per batch\n");
- help.append("\t spause [ticks] - Set/show pause period\n");
- help.append("\t sdi [ticks] - Set/show discovery interval in ticks\n");
- help.append("\t addsw <swid> - Add a switch\n");
- help.append("\t remsw <swid> - Remove a switch\n");
- help.append("\t page - Print aging info\n");
- help.append("\t sage - Set/Show aging time limit\n");
- help.append("\t eage - Enable aging\n");
- help.append("\t dage - Disable aging\n");
- help.append("\t pthrot - Print throttling\n");
- help.append("\t ethrot - Enable throttling\n");
- help.append("\t dthrot - Disable throttling\n");
- help.append("\t psnp - Print LLDP snooping\n");
- help.append("\t esnp <all|nodeConnector> - Enable LLDP snooping\n");
- help.append("\t dsnp <all|nodeConnector> - Disable LLDP snooping\n");
- return help.toString();
- }
-
- private List<NodeConnector> sortList(Collection<NodeConnector> ncs) {
- List<String> ncStrArray = new ArrayList<String>();
- for (NodeConnector nc : ncs) {
- ncStrArray.add(nc.toString());
- }
- Collections.sort(ncStrArray);
-
- List<NodeConnector> sortedNodeConnectors = new ArrayList<NodeConnector>();
- for (String ncStr : ncStrArray) {
- sortedNodeConnectors.add(NodeConnector.fromString(ncStr));
- }
-
- return sortedNodeConnectors;
- }
-
- public void _prlh(CommandInterpreter ci) {
- ci.println("readyListHi\n");
- for (NodeConnector nodeConnector : sortList(readyListHi)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + readyListHi.size());
- }
-
- public void _prll(CommandInterpreter ci) {
- ci.println("readyListLo\n");
- for (NodeConnector nodeConnector : sortList(readyListLo)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + readyListLo.size());
- }
-
- public void _psl(CommandInterpreter ci) {
- ci.println("stagingList\n");
- for (NodeConnector nodeConnector : sortList(stagingList)) {
- if (nodeConnector == null) {
- continue;
- }
- ci.println(nodeConnector);
- }
- ci.println("Total number of Node Connectors: " + stagingList.size());
- }
-
- public void _pht(CommandInterpreter ci) {
- ci.println(" NodeConnector Last rx LLDP (sec)");
- for (ConcurrentMap.Entry<NodeConnector, Integer> entry: holdTime.entrySet()) {
- ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
- }
- ci.println("\nSize: " + holdTime.size() + "\tTimeout: " + discoveryTimeoutTicks * (discoveryTimerTick / 1000)
- + " sec");
- }
-
- public void _pet(CommandInterpreter ci) {
- ci.println(" NodeConnector Elapsed Time (sec)");
- for (ConcurrentMap.Entry<NodeConnector, Integer> entry: elapsedTime.entrySet()) {
- ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
- }
- ci.println("\nSize: " + elapsedTime.size() + "\tThreshold: " + DiscoveryPeriod.THRESHOLD.getTime() + " sec");
- }
-
- public void _ptick(CommandInterpreter ci) {
- ci.println("Current timer is " + discoveryTimerTick + " msec per tick");
- }
-
- public void _pcc(CommandInterpreter ci) {
- if (discoveryConsistencyCheckEnabled) {
- ci.println("ConsistencyChecker is currently enabled");
- } else {
- ci.println("ConsistencyChecker is currently disabled");
- }
- ci.println("Interval " + getDiscoveryConsistencyCheckInterval());
- ci.println("Multiple " + discoveryConsistencyCheckMultiple);
- ci.println("Number of times called " + discoveryConsistencyCheckCallingTimes);
- ci.println("Corrected count " + discoveryConsistencyCheckCorrected);
- }
-
- public void _ptm(CommandInterpreter ci) {
- ci.println("Timeout " + discoveryTimeoutTicks + " ticks, " + discoveryTimerTick / 1000 + " sec per tick.");
- }
-
- public void _psize(CommandInterpreter ci) {
- ci.println("readyListLo size " + readyListLo.size() + "\n" + "readyListHi size " + readyListHi.size() + "\n"
- + "stagingList size " + stagingList.size() + "\n" + "holdTime size " + holdTime.size() + "\n"
- + "edgeMap size " + edgeMap.size() + "\n" + "prodMap size " + prodMap.size() + "\n" + "agingMap size "
- + agingMap.size() + "\n" + "elapsedTime size " + elapsedTime.size());
- }
-
- public void _page(CommandInterpreter ci) {
- if (this.discoveryAgingEnabled) {
- ci.println("Aging is enabled");
- } else {
- ci.println("Aging is disabled");
- }
- ci.println("Current aging time limit " + this.discoveryAgeoutTicks);
- ci.println("\n");
- ci.println(" Edge Aging ");
- Collection<Edge> prodSet = prodMap.values();
- if (prodSet == null) {
- return;
- }
- for (Edge edge : prodSet) {
- Integer aging = agingMap.get(edge.getHeadNodeConnector());
- if (aging != null) {
- ci.println(edge + " " + aging);
- }
- }
- ci.println("\n");
- ci.println(" NodeConnector Edge ");
- Set<NodeConnector> keySet = prodMap.keySet();
- if (keySet == null) {
- return;
- }
- for (NodeConnector nc : keySet) {
- ci.println(nc + " " + prodMap.get(nc));
- }
- return;
- }
-
- public void _sage(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter aging time limit. Current value " + this.discoveryAgeoutTicks);
- return;
- }
- try {
- this.discoveryAgeoutTicks = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _eage(CommandInterpreter ci) {
- this.discoveryAgingEnabled = true;
- ci.println("Aging is enabled");
- return;
- }
-
- public void _dage(CommandInterpreter ci) {
- this.discoveryAgingEnabled = false;
- ci.println("Aging is disabled");
- return;
- }
-
- public void _scc(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter CC multiple. Current multiple " + discoveryConsistencyCheckMultiple
- + " (interval " + getDiscoveryConsistencyCheckInterval() + ") calling times "
- + discoveryConsistencyCheckCallingTimes);
- return;
- }
- try {
- discoveryConsistencyCheckMultiple = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _ecc(CommandInterpreter ci) {
- this.discoveryConsistencyCheckEnabled = true;
- ci.println("ConsistencyChecker is enabled");
- return;
- }
-
- public void _dcc(CommandInterpreter ci) {
- this.discoveryConsistencyCheckEnabled = false;
- ci.println("ConsistencyChecker is disabled");
- return;
- }
-
- public void _psnp(CommandInterpreter ci) {
- if (this.discoverySnoopingEnabled) {
- ci.println("Discovery snooping is globally enabled");
- } else {
- ci.println("Discovery snooping is globally disabled");
- }
-
- ci.println("\nDiscovery snooping is locally disabled on these ports");
- for (NodeConnector nodeConnector : discoverySnoopingDisableList) {
- ci.println(nodeConnector);
- }
- return;
- }
-
- public void _esnp(CommandInterpreter ci) {
- String val = ci.nextArgument();
-
- if (val == null) {
- ci.println("Usage: esnp <all|nodeConnector>");
- } else if (val.equalsIgnoreCase("all")) {
- this.discoverySnoopingEnabled = true;
- ci.println("Discovery snooping is globally enabled");
- } else {
- NodeConnector nodeConnector = NodeConnector.fromString(val);
- if (nodeConnector != null) {
- discoverySnoopingDisableList.remove(nodeConnector);
- ci.println("Discovery snooping is locally enabled on port " + nodeConnector);
- } else {
- ci.println("Entered invalid NodeConnector " + val);
- }
- }
- return;
- }
-
- public void _dsnp(CommandInterpreter ci) {
- String val = ci.nextArgument();
-
- if (val == null) {
- ci.println("Usage: dsnp <all|nodeConnector>");
- } else if (val.equalsIgnoreCase("all")) {
- this.discoverySnoopingEnabled = false;
- ci.println("Discovery snooping is globally disabled");
- } else {
- NodeConnector nodeConnector = NodeConnector.fromString(val);
- if (nodeConnector != null) {
- discoverySnoopingDisableList.add(nodeConnector);
- ci.println("Discovery snooping is locally disabled on port " + nodeConnector);
- } else {
- ci.println("Entered invalid NodeConnector " + val);
- }
- }
- return;
- }
-
- public void _spause(CommandInterpreter ci) {
- String val = ci.nextArgument();
- String out = "Please enter pause period less than " + discoveryBatchRestartTicks + ". Current pause period is "
- + discoveryBatchPausePeriod + " ticks, pause at " + discoveryBatchPauseTicks + " ticks, "
- + discoveryTimerTick / 1000 + " sec per tick.";
-
- if (val != null) {
- try {
- int pause = Integer.parseInt(val);
- if (pause < discoveryBatchRestartTicks) {
- discoveryBatchPausePeriod = pause;
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- return;
- }
- } catch (Exception e) {
- }
- }
-
- ci.println(out);
- }
-
- public void _sdi(CommandInterpreter ci) {
- String val = ci.nextArgument();
- String out = "Please enter discovery interval in ticks. Current value is " + discoveryBatchRestartTicks + " ticks, "
- + discoveryTimerTick / 1000 + " sec per tick.";
-
- if (val != null) {
- try {
- int ticks = Integer.parseInt(val);
- DiscoveryPeriod.INTERVAL.setTick(ticks);
- discoveryBatchRestartTicks = getDiscoveryInterval();
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- discoveryTimeoutTicks = getDiscoveryTimeout();
- return;
- } catch (Exception e) {
- }
- }
- ci.println(out);
- }
-
- public void _sports(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter max ports per batch. Current value is " + discoveryBatchMaxPorts);
- return;
- }
- try {
- discoveryBatchMaxPorts = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _addsw(CommandInterpreter ci) {
- String val = ci.nextArgument();
- Long sid;
- try {
- sid = Long.parseLong(val);
- Node node = NodeCreator.createOFNode(sid);
- addDiscovery(node);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _remsw(CommandInterpreter ci) {
- String val = ci.nextArgument();
- Long sid;
- try {
- sid = Long.parseLong(val);
- Node node = NodeCreator.createOFNode(sid);
- removeDiscovery(node);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _pthrot(CommandInterpreter ci) {
- if (this.throttling) {
- ci.println("Throttling is enabled");
- } else {
- ci.println("Throttling is disabled");
- }
- }
-
- public void _ethrot(CommandInterpreter ci) {
- this.throttling = true;
- ci.println("Throttling is enabled");
- return;
- }
-
- public void _dthrot(CommandInterpreter ci) {
- this.throttling = false;
- ci.println("Throttling is disabled");
- return;
- }
-
- @Override
- public void updateNode(Node node, UpdateType type, Set<Property> props) {
- switch (type) {
- case ADDED:
- addNode(node, props);
- break;
- case REMOVED:
- removeNode(node);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void updateNodeConnector(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
- Config config = null;
- State state = null;
- boolean enabled = false;
-
- for (Property prop : props) {
- if (prop.getName().equals(Config.ConfigPropName)) {
- config = (Config) prop;
- } else if (prop.getName().equals(State.StatePropName)) {
- state = (State) prop;
- }
- }
- enabled = ((config != null) && (config.getValue() == Config.ADMIN_UP) && (state != null) && (state.getValue() == State.EDGE_UP));
-
- switch (type) {
- case ADDED:
- if (enabled) {
- addDiscovery(nodeConnector);
- logger.trace("ADDED enabled {}", nodeConnector);
- } else {
- logger.trace("ADDED disabled {}", nodeConnector);
- }
- break;
- case CHANGED:
- if (enabled) {
- addDiscovery(nodeConnector);
- logger.trace("CHANGED enabled {}", nodeConnector);
- } else {
- removeDiscovery(nodeConnector);
- logger.trace("CHANGED disabled {}", nodeConnector);
- }
- break;
- case REMOVED:
- removeDiscovery(nodeConnector);
- logger.trace("REMOVED enabled {}", nodeConnector);
- break;
- default:
- return;
- }
- }
-
- public void addNode(Node node, Set<Property> props) {
- if (node == null) {
- return;
- }
-
- addDiscovery(node);
- }
-
- public void removeNode(Node node) {
- if (node == null) {
- return;
- }
-
- removeDiscovery(node);
- }
-
- void setController(IController s) {
- this.controller = s;
- }
-
- void unsetController(IController s) {
- if (this.controller == s) {
- this.controller = null;
- }
- }
-
- public void setInventoryProvider(IInventoryProvider service) {
- this.inventoryProvider = service;
- }
-
- public void unsetInventoryProvider(IInventoryProvider service) {
- this.inventoryProvider = null;
- }
-
- public void setIDataPacketMux(IDataPacketMux service) {
- this.iDataPacketMux = service;
- }
-
- public void unsetIDataPacketMux(IDataPacketMux service) {
- if (this.iDataPacketMux == service) {
- this.iDataPacketMux = null;
- }
- }
-
- void setDiscoveryListener(IDiscoveryListener s) {
- this.discoveryListener = s;
- }
-
- void unsetDiscoveryListener(IDiscoveryListener s) {
- if (this.discoveryListener == s) {
- this.discoveryListener = null;
- }
- }
-
- void setIPluginOutConnectionService(IPluginOutConnectionService s) {
- connectionOutService = s;
- }
-
- void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
- if (connectionOutService == s) {
- connectionOutService = null;
- }
- }
-
- private void initDiscoveryPacket() {
- // Create LLDP ChassisID TLV
- chassisIdTlv = new LLDPTLV();
- chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue());
-
- // Create LLDP PortID TLV
- portIdTlv = new LLDPTLV();
- portIdTlv.setType(LLDPTLV.TLVType.PortID.getValue());
-
- // Create LLDP TTL TLV
- byte[] ttl = new byte[] { (byte) 0, (byte) 120 };
- ttlTlv = new LLDPTLV();
- ttlTlv.setType(LLDPTLV.TLVType.TTL.getValue()).setLength((short) ttl.length).setValue(ttl);
-
- customTlv = new LLDPTLV();
- }
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- *
- */
- void init() {
- logger.trace("Init called");
-
- transmitQ = new LinkedBlockingQueue<NodeConnector>();
-
- readyListHi = new CopyOnWriteArrayList<NodeConnector>();
- readyListLo = new CopyOnWriteArrayList<NodeConnector>();
- stagingList = new CopyOnWriteArrayList<NodeConnector>();
- holdTime = new ConcurrentHashMap<NodeConnector, Integer>();
- elapsedTime = new ConcurrentHashMap<NodeConnector, Integer>();
- edgeMap = new ConcurrentHashMap<NodeConnector, Edge>();
- agingMap = new ConcurrentHashMap<NodeConnector, Integer>();
- prodMap = new ConcurrentHashMap<NodeConnector, Edge>();
- discoverySnoopingDisableList = new CopyOnWriteArrayList<NodeConnector>();
-
- discoveryBatchRestartTicks = getDiscoveryInterval();
- discoveryBatchPauseTicks = getDiscoveryPauseInterval();
- discoveryTimeoutTicks = getDiscoveryTimeout();
- discoveryThresholdTicks = getDiscoveryThreshold();
- discoveryAgeoutTicks = getDiscoveryAgeout();
- discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
- discoveryBatchMaxPorts = getDiscoveryBatchMaxPorts();
-
- discoveryTimer = new Timer("DiscoveryService");
- discoveryTimerTask = new DiscoveryTimerTask();
-
- transmitThread = new Thread(new DiscoveryTransmit(transmitQ));
-
- initDiscoveryPacket();
-
- registerWithOSGIConsole();
- }
-
- /**
- * Function called by the dependency manager when at least one dependency
- * become unsatisfied or when the component is shutting down because for
- * example bundle is being stopped.
- *
- */
- void destroy() {
- transmitQ = null;
- readyListHi = null;
- readyListLo = null;
- stagingList = null;
- holdTime = null;
- edgeMap = null;
- agingMap = null;
- prodMap = null;
- discoveryTimer = null;
- discoveryTimerTask = null;
- transmitThread = null;
- }
-
- /**
- * Function called by dependency manager after "init ()" is called and after
- * the services provided by the class are registered in the service registry
- *
- */
- void start() {
- discoveryTimer.schedule(discoveryTimerTask, discoveryTimerTick, discoveryTimerTick);
- transmitThread.start();
- }
-
- /**
- * Function called after registering the service in OSGi service registry.
- */
- void started() {
- /* get a snapshot of all the existing switches */
- addDiscovery();
- }
-
- /**
- * Function called by the dependency manager before the services exported by
- * the component are unregistered, this will be followed by a "destroy ()"
- * calls
- *
- */
- void stop() {
- shuttingDown = true;
- discoveryTimer.cancel();
- transmitThread.interrupt();
- }
-
- @Override
- public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) {
- }
-
- @Override
- public void containerFlowUpdated(String containerName, ContainerFlow previousFlow, ContainerFlow currentFlow,
- UpdateType t) {
- }
-
- @Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType t) {
- switch (t) {
- case ADDED:
- moveToReadyListHi(p);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void containerModeUpdated(UpdateType t) {
- // do nothing
- }
-
- private byte[] getSourceMACFromNodeID(String nodeId) {
- byte[] cid = HexEncode.bytesFromHexString(nodeId);
- byte[] sourceMac = new byte[6];
- int pos = cid.length - sourceMac.length;
-
- if (pos >= 0) {
- System.arraycopy(cid, pos, sourceMac, 0, sourceMac.length);
- }
-
- return sourceMac;
- }
-
- private int getDiscoveryTicks(DiscoveryPeriod dp, String val) {
- if (dp == null) {
- return 0;
- }
-
- if (val != null) {
- try {
- dp.setTime(Integer.parseInt(val));
- } catch (Exception e) {
- }
- }
-
- return dp.getTick();
- }
-
- /**
- * This method returns the interval which determines how often the discovery
- * packets will be sent.
- *
- * @return The discovery interval in ticks
- */
- private int getDiscoveryInterval() {
- String intvl = System.getProperty("of.discoveryInterval");
- return getDiscoveryTicks(DiscoveryPeriod.INTERVAL, intvl);
- }
-
- /**
- * This method returns the timeout value in receiving subsequent discovery packets on a port.
- *
- * @return The discovery timeout in ticks
- */
- private int getDiscoveryTimeout() {
- String val = System.getProperty("of.discoveryTimeoutMultiple");
- int multiple = 2;
-
- if (val != null) {
- try {
- multiple = Integer.parseInt(val);
- } catch (Exception e) {
- }
- }
- return getDiscoveryInterval() * multiple + 3;
- }
-
- /**
- * This method returns the user configurable threshold value
- *
- * @return The discovery threshold value in ticks
- */
- private int getDiscoveryThreshold() {
- String val = System.getProperty("of.discoveryThreshold");
- return getDiscoveryTicks(DiscoveryPeriod.THRESHOLD, val);
- }
-
- /**
- * This method returns the discovery entry aging time in ticks.
- *
- * @return The aging time in ticks
- */
- private int getDiscoveryAgeout() {
- return getDiscoveryTicks(DiscoveryPeriod.AGEOUT, null);
- }
-
- /**
- * This method returns the pause interval
- *
- * @return The pause interval in ticks
- */
- private int getDiscoveryPauseInterval() {
- if (discoveryBatchRestartTicks > discoveryBatchPausePeriod) {
- return discoveryBatchRestartTicks - discoveryBatchPausePeriod;
- } else {
- return discoveryBatchRestartTicks - 1;
- }
- }
-
- /**
- * This method returns the user configurable maximum number of ports handled
- * in one discovery batch.
- *
- * @return The maximum number of ports
- */
- private int getDiscoveryBatchMaxPorts() {
- String val = System.getProperty("of.discoveryBatchMaxPorts");
- int ports = 1024;
-
- if (val != null) {
- try {
- ports = Integer.parseInt(val);
- } catch (Exception e) {
- }
- }
- return ports;
- }
-}
+++ /dev/null
-package org.opendaylight.openflowplugin.openflow.vendorextension.v6extension;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import org.openflow.protocol.OFError;
-
-public class V6Error extends OFError {
- private static final long serialVersionUID = 1L;
- public static int MINIMUM_LENGTH = 20;//OfHdr(8) + NXET_VENDOR(2) + NXEC_VENDOR_ERROR(2) + struct nx_vendor_error(8)
- public static final short NICIRA_VENDOR_ERRORTYPE = (short)0xb0c2;
- protected int V6VendorId;
- protected short V6VendorErrorType;
- protected short V6VendorErrorCode;
- protected byte[] V6ErrorData;
-
- public V6Error(OFError e) {
- this.length = (short)e.getLengthU();
- this.errorType = e.getErrorType();
- this.errorCode = e.getErrorCode();
- this.xid = e.getXid();
- }
-
- @Override
- public void readFrom(ByteBuffer data) {
- this.V6VendorId = data.getInt();
- this.V6VendorErrorType = data.getShort();
- this.V6VendorErrorCode = data.getShort();
- int dataLength = this.getLengthU() - MINIMUM_LENGTH;
- if (dataLength > 0) {
- this.V6ErrorData = new byte[dataLength];
- data.get(this.V6ErrorData);
- }
- }
-
- /**
- * @return the V6VendorId
- */
- public int getVendorId() {
- return V6VendorId;
- }
-
- /**
- * @return the V6VendorErrorType
- */
- public short getVendorErrorType() {
- return V6VendorErrorType;
- }
-
- /**
- * @return the VendorErrorType
- */
- public short getVendorErrorCode() {
- return V6VendorErrorCode;
- }
-
- /**
- * @return the Error Bytes
- */
- public byte[] getError() {
- return V6ErrorData;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + Arrays.hashCode(V6ErrorData);
- result = prime * result + V6VendorErrorCode;
- result = prime * result + V6VendorErrorType;
- result = prime * result + V6VendorId;
- return result;
- }
-
- @Override
- public String toString() {
- return "V6Error [V6VendorId=" + V6VendorId + ", V6VendorErrorType="
- + V6VendorErrorType + ", V6VendorErrorCode="
- + V6VendorErrorCode + ", V6ErrorData="
- + Arrays.toString(V6ErrorData) + ", errorType=" + errorType
- + ", errorCode=" + errorCode + ", factory=" + factory
- + ", error=" + Arrays.toString(error) + ", errorIsAscii="
- + errorIsAscii + ", version=" + version + ", type=" + type
- + ", length=" + length + ", xid=" + xid + "]";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (getClass() != obj.getClass())
- return false;
- V6Error other = (V6Error) obj;
- if (!Arrays.equals(V6ErrorData, other.V6ErrorData))
- return false;
- if (V6VendorErrorCode != other.V6VendorErrorCode)
- return false;
- if (V6VendorErrorType != other.V6VendorErrorType)
- return false;
- if (V6VendorId != other.V6VendorId)
- return false;
- return true;
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.vendorextension.v6extension;
-
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFVendor;
-import org.openflow.protocol.action.OFAction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class is used to create IPv6 Vendor Extension messages. Specfically, It
- * defines the methods used in creation of Vendor specific IPv6 Flow Mod message.
- *
- *
- */
-public class V6FlowMod extends OFVendor implements Cloneable {
- private static final Logger logger = LoggerFactory
- .getLogger(V6FlowMod.class);
- private static final long serialVersionUID = 1L;
- protected V6Match match;
- protected long cookie;
- protected short command;
- protected short idleTimeout;
- protected short hardTimeout;
- protected short priority;
- protected int bufferId;
- protected short outPort;
- protected short flags;
- protected List<OFAction> actions;
- short match_len;
- short actions_len;
- short pad_size;
-
- private static int IPV6EXT_ADD_FLOW_MSG_TYPE = 13;
- private static int IPV6_EXT_MIN_HDR_LEN = 36;
-
- /**
- * Constructor for the V6FlowMod class. Initializes OFVendor (parent class)
- * fields by calling the parent class' constructor.
- */
- public V6FlowMod() {
- super();
- }
-
- /**
- * This method sets the match fields of V6FlowMod object
- * @param match V6Match object for this V6FlowMod message
- */
- public void setMatch(V6Match match) {
- this.match = match;
- }
-
- /**
- * Sets the list of actions V6FlowMod message
- * @param actions a list of ordered OFAction objects
- */
- public void setActions(List<OFAction> actions) {
- this.actions = actions;
- }
-
- /**
- * Sets the priority field of V6FlowMod message
- * @param priority Priority of the message
- */
- public void setPriority(short priority) {
- this.priority = priority;
- }
-
- /**
- * Sets the cookie field of V6FlowMod message
- * @param cookie Cookie of the message
- */
- public void setCookie(long cookie) {
- this.cookie = cookie;
- }
-
- /**
- * Sets the command field of V6FlowMod message
- * @param command Command type of the message (ADD or DELETE)
- */
- public V6FlowMod setCommand(short command) {
- this.command = command;
- return this;
- }
-
- /**
- * Sets the outPort field of V6FlowMod message
- * @param outPort outPort of the message
- */
- public V6FlowMod setOutPort(OFPort port) {
- this.outPort = port.getValue();
- return this;
- }
-
- /**
- * Sets the idle_timeout of V6FlowMod message
- * @param idleTimeout idle timeout for this message
- */
- public void setIdleTimeout(short idleTimeout) {
- this.idleTimeout = idleTimeout;
- }
-
- /**
- * Sets the hardTimeout field of V6FlowMod message
- * @param hardTimeout hard timeout of the message
- */
- public void setHardTimeout(short hardTimeout) {
- this.hardTimeout = hardTimeout;
- }
-
- /**
- * Returns the Flow Mod message subtype for V6FlowMod message
- * @return message subtype
- */
- private int getIPv6ExtensionFlowModAddSubType() {
- return IPV6EXT_ADD_FLOW_MSG_TYPE;
- }
-
- /**
- * Returns the minimum header size for V6Flow Message type
- * @return minimum header size
- */
-
- public int getV6FlowModMinHdrSize() {
- return IPV6_EXT_MIN_HDR_LEN;
- }
-
- /**
- * Sets the Vendor type in OFVendor message
- */
-
- public void setVendor() {
- super.setVendor(V6StatsRequest.NICIRA_VENDOR_ID);
- }
-
- /**
- * Get flags
- * @return
- */
- public short getFlags() {
- return flags;
- }
-
- /**
- * Set flags
- * @param flags
- */
- public void setFlags(short flags) {
- this.flags = flags;
- }
-
- /**
- * This method forms the Vendor extension IPv6 Flow Mod message.It uses the
- * fields in V6FlowMod class, and writes the data according to vendor
- * extension format. The fields include flow properties (cookie, timeout,
- * priority, etc), flow match, and action list. It also takes care of
- * required padding.
- */
-
- @Override
- public void writeTo(ByteBuffer data) {
- super.writeTo(data);
- data.putInt(getIPv6ExtensionFlowModAddSubType());
- data.putLong(this.cookie);
- data.putShort(command); /* should be OFPFC_ADD, OFPFC_DELETE_STRICT, etc*/
- data.putShort(this.idleTimeout);
- data.putShort(this.hardTimeout);
- data.putShort(this.priority);
- data.putInt(OFPacketOut.BUFFER_ID_NONE);
- data.putShort(outPort); /* output_port */
- data.putShort(flags); /* flags */
- match_len = this.match.getIPv6MatchLen();
- data.putShort(match_len);
- byte[] pad = new byte[6];
- data.put(pad);
- this.match.writeTo(data);
-
- pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
-
- /*
- * action list should be preceded by a padding of 0 to 7 bytes based upon
- * above formula.
- */
-
- byte[] pad2 = new byte[pad_size];
- data.put(pad2);
- if (actions != null) {
- for (OFAction action : actions) {
- actions_len += action.getLength();
- action.writeTo(data);
- }
- }
- logger.trace("{}", this);
- }
-
- /**
- * Forms the clone of V6FlowMod Object. If Object is returned
- * successfully, then returns the cloned object. Throws an
- * exception if cloning is not supported.
- */
- @Override
- public V6FlowMod clone() {
- try {
- V6Match neoMatch = match.clone();
- V6FlowMod v6flowMod = (V6FlowMod) super.clone();
- v6flowMod.setMatch(neoMatch);
- List<OFAction> neoActions = new LinkedList<OFAction>();
- for (OFAction action : this.actions)
- neoActions.add((OFAction) action.clone());
- v6flowMod.setActions(neoActions);
- return v6flowMod;
- } catch (CloneNotSupportedException e) {
- // Won't happen
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String toString() {
- return "V6FlowMod [match=" + match + ", cookie=" + cookie
- + ", command=" + command + ", idleTimeout=" + idleTimeout
- + ", hardTimeout=" + hardTimeout + ", priority=" + priority
- + ", bufferId=" + bufferId + ", outPort=" + outPort
- + ", flags=" + flags + ", actions=" + actions + ", match_len="
- + match_len + ", actions_len=" + actions_len + ", pad_size="
- + pad_size + "]";
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.vendorextension.v6extension;
-
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.openflow.protocol.OFMatch;
-import org.openflow.util.U16;
-import org.openflow.util.U8;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This Class forms the vendor specific IPv6 Flow Match messages as well as
- * processes the vendor specific IPv6 Stats Reply message.
- *
- * For message creation, it parses the user entered IPv6 match fields, creates a
- * sub-message for each field which are later used to form the complete message.
- *
- * For message processing, it parses the incoming message and reads each field
- * of the message and stores in appropriate field of V6Match object.
- *
- *
- */
-public class V6Match extends OFMatch implements Cloneable {
- private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
- private static final long serialVersionUID = 1L;
- protected Inet6Address nwSrc;
- protected Inet6Address nwDst;
- protected short inputPortMask;
- protected byte[] dataLayerSourceMask;
- protected byte[] dataLayerDestinationMask;
- protected int dataLayerVirtualLanTCIMask;
- protected short dataLayerTypeMask;
- protected byte networkTypeOfServiceMask;
- protected byte networkProtocolMask;
- protected short transportSourceMask;
- protected short transportDestinationMask;
- protected short srcIPv6SubnetMaskbits;
- protected short dstIPv6SubnetMaskbits;
-
- protected MatchFieldState inputPortState;
- protected MatchFieldState dlSourceState;
- protected MatchFieldState dlDestState;
- protected MatchFieldState dlVlanIDState;
- protected MatchFieldState dlVlanPCPState;
- protected MatchFieldState dlVlanTCIState;
- protected MatchFieldState ethTypeState;
- protected MatchFieldState nwTosState;
- protected MatchFieldState nwProtoState;
- protected MatchFieldState nwSrcState;
- protected MatchFieldState nwDstState;
- protected MatchFieldState tpSrcState;
- protected MatchFieldState tpDstState;
- protected short match_len = 0;
- protected short pad_size = 0;
-
- private static int IPV6_EXT_MIN_HDR_LEN = 36;
-
- private enum MatchFieldState {
- MATCH_ABSENT, MATCH_FIELD_ONLY, MATCH_FIELD_WITH_MASK
- }
-
- private enum OF_Match_Types {
- MATCH_OF_IN_PORT(0), MATCH_OF_ETH_DST(1), MATCH_OF_ETH_SRC(2), MATCH_OF_ETH_TYPE(
- 3), MATCH_OF_VLAN_TCI(4), MATCH_OF_IP_TOS(5), MATCH_OF_IP_PROTO(
- 6), MATCH_OF_IP_SRC(7), MATCH_OF_IP_DST(8), MATCH_OF_TCP_SRC(9), MATCH_OF_TCP_DST(
- 10), MATCH_OF_UDP_SRC(11), MATCH_OF_UDP_DST(12), MATCH_OF_ICMTP_TYPE(
- 13), MATCH_OF_ICMP_CODE(14), MATCH_OF_ARP_OP(15);
-
- private int value;
-
- private OF_Match_Types(int value) {
- this.value = value;
- }
-
- public int getValue() {
- return this.value;
- }
- }
-
- private enum IPv6Extension_Match_Types {
- MATCH_IPV6EXT_TUN_ID(16), MATCH_IPV6EXT_ARP_SHA(17), MATCH_IPV6EXT_ARP_THA(
- 18), MATCH_IPV6EXT_IPV6_SRC(19), MATCH_IPV6EXT_IPV6_DST(20);
-
- private int value;
-
- private IPv6Extension_Match_Types(int value) {
- this.value = value;
- }
-
- public int getValue() {
- return value;
- }
- }
-
- public enum Extension_Types {
- OF_10(0), IPV6EXT(1);
-
- protected int value;
-
- private Extension_Types(int value) {
- this.value = value;
- }
-
- public int getValue() {
- return value;
- }
- }
-
- public V6Match() {
- super();
-
- this.nwSrc = null;
- this.nwDst = null;
-
- this.inputPortMask = 0;
- this.dataLayerSourceMask = null;
- this.dataLayerDestinationMask = null;
- this.dataLayerTypeMask = 0;
- this.dataLayerVirtualLanTCIMask = 0;
- this.networkTypeOfServiceMask = 0;
- this.networkProtocolMask = 0;
- this.transportSourceMask = 0;
- this.transportDestinationMask = 0;
-
- this.inputPortState = MatchFieldState.MATCH_ABSENT;
- this.dlSourceState = MatchFieldState.MATCH_ABSENT;
- this.dlDestState = MatchFieldState.MATCH_ABSENT;
- this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
- this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
- this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
- this.ethTypeState = MatchFieldState.MATCH_ABSENT;
- this.nwTosState = MatchFieldState.MATCH_ABSENT;
- this.nwProtoState = MatchFieldState.MATCH_ABSENT;
- this.nwSrcState = MatchFieldState.MATCH_ABSENT;
- this.nwDstState = MatchFieldState.MATCH_ABSENT;
- this.tpSrcState = MatchFieldState.MATCH_ABSENT;
- this.tpDstState = MatchFieldState.MATCH_ABSENT;
-
- this.match_len = 0;
- this.pad_size = 0;
- }
-
- public V6Match(OFMatch match) {
- super();
- this.match_len = 0;
- this.pad_size = 0;
-
- if (match.getNetworkSource() != 0) {
- InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
- InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
- this.setNetworkSource(address, mask);
- } else {
- this.nwSrcState = MatchFieldState.MATCH_ABSENT;
- }
-
- if (match.getNetworkDestination() != 0) {
- InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination());
- InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false);
- this.setNetworkDestination(address, mask);
- } else {
- this.nwDstState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.inputPortMask = 0;
- if (match.getInputPort() != 0) {
- this.setInputPort(match.getInputPort(), (short) 0);
- } else {
- this.inputPortMask = 0;
- this.inputPortState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.dataLayerSourceMask = null;
- if (match.getDataLayerSource() != null
- && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
- this.setDataLayerSource(match.getDataLayerSource(), null);
- } else {
- this.dlSourceState = MatchFieldState.MATCH_ABSENT;
- }
- this.dataLayerDestinationMask = null;
- if (match.getDataLayerDestination() != null
- && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
- this.setDataLayerDestination(match.getDataLayerDestination(), null);
- } else {
- this.dlDestState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.dataLayerTypeMask = 0;
- if (match.getDataLayerType() != 0) {
- this.setDataLayerType(match.getDataLayerType(), (short) 0);
- } else {
- this.dataLayerType = 0;
- this.ethTypeState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.dataLayerVirtualLanTCIMask = 0;
- this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
- if (match.getDataLayerVirtualLan() != 0) {
- this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
- (short) 0);
- } else {
- this.dataLayerVirtualLan = 0;
- this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
- }
-
- if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
- this.setDataLayerVirtualLanPriorityCodePoint(
- match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
- } else {
- this.dataLayerVirtualLanPriorityCodePoint = 0;
- this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.networkProtocolMask = 0;
- if (match.getNetworkProtocol() != 0) {
- this.setNetworkProtocol(
- this.networkProtocol = match.getNetworkProtocol(), (byte) 0);
- } else {
- this.networkProtocol = 0;
- this.nwProtoState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.networkTypeOfServiceMask = 0;
- if (match.getNetworkTypeOfService() != 0) {
- this.setNetworkTypeOfService(
- this.networkTypeOfService = match.getNetworkTypeOfService(),
- (byte) 0);
- } else {
- this.networkTypeOfService = match.getNetworkTypeOfService();
- this.nwTosState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.transportSourceMask = 0;
- if (match.getTransportSource() != 0) {
- this.setTransportSource(match.getTransportSource(), (short) 0);
- } else {
- this.transportSource = 0;
- this.tpSrcState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.transportDestinationMask = 0;
- if (match.getTransportDestination() != 0) {
- this.setTransportDestination(match.getTransportDestination(),
- (short) 0);
- } else {
- this.transportDestination = 0;
- this.tpDstState = MatchFieldState.MATCH_ABSENT;
- }
-
- this.setWildcards(match.getWildcards());
- }
-
- private enum IPProtocols {
- ICMP(1), TCP(6), UDP(17), ICMPV6(58);
-
- private int protocol;
-
- private IPProtocols(int value) {
- this.protocol = value;
- }
-
- private byte getValue() {
- return (byte) this.protocol;
- }
- }
-
- public short getIPv6MatchLen() {
- return match_len;
- }
-
- public int getIPv6ExtMinHdrLen() {
- return IPV6_EXT_MIN_HDR_LEN;
- }
-
- public short getPadSize() {
- return (short) (((match_len + 7) / 8) * 8 - match_len);
- }
-
- private int getIPv6ExtensionMatchHeader(Extension_Types extType, int field,
- int has_mask, int length) {
- return (((extType.getValue() & 0x0000ffff) << 16)
- | ((field & 0x0000007f) << 9) | ((has_mask & 0x00000001) << 8) | (length & 0x000000ff));
- }
-
- private byte[] getIPv6ExtensionPortMatchMsg(short port) {
- ByteBuffer ipv6ext_port_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_IN_PORT.getValue(), 0, 2);
- ipv6ext_port_msg.putInt(nxm_header);
- ipv6ext_port_msg.putShort(port);
- return (ipv6ext_port_msg.array());
- }
-
- private byte[] getIPv6ExtensionDestMacMatchMsg(byte[] destMac) {
- ByteBuffer ipv6ext_destmac_msg = ByteBuffer.allocate(10);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_ETH_DST.getValue(), 0, 6);
- ipv6ext_destmac_msg.putInt(nxm_header);
- ipv6ext_destmac_msg.put(destMac);
- return (ipv6ext_destmac_msg.array());
- }
-
- private byte[] getIPv6ExtensionSrcMacMatchMsg(byte[] srcMac) {
- ByteBuffer ipv6ext_srcmac_msg = ByteBuffer.allocate(10);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_ETH_SRC.getValue(), 0, 6);
- ipv6ext_srcmac_msg.putInt(nxm_header);
- ipv6ext_srcmac_msg.put(srcMac);
- return (ipv6ext_srcmac_msg.array());
- }
-
- private byte[] getIPv6ExtensionEtherTypeMatchMsg(short EtherType) {
- ByteBuffer ipv6ext_etype_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_ETH_TYPE.getValue(), 0, 2);
- ipv6ext_etype_msg.putInt(nxm_header);
- ipv6ext_etype_msg.putShort(EtherType);
- return (ipv6ext_etype_msg.array());
- }
-
- private byte[] getVlanTCI(short dataLayerVirtualLanID,
- byte dataLayerVirtualLanPriorityCodePoint) {
- ByteBuffer vlan_tci = ByteBuffer.allocate(2);
- int cfi = 1 << 12; // the cfi bit is in position 12
- int pcp = dataLayerVirtualLanPriorityCodePoint << 13; // the pcp fields
- // have to move by
- // 13
- int vlan_tci_int = pcp + cfi + dataLayerVirtualLanID;
- vlan_tci.put((byte) (vlan_tci_int >> 8)); // bits 8 to 15
- vlan_tci.put((byte) vlan_tci_int); // bits 0 to 7
- return vlan_tci.array();
- }
-
- private byte[] getIPv6ExtensionVlanTCIMatchMsg(short dataLayerVirtualLanID,
- byte dataLayerVirtualLanPriorityCodePoint) {
- ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
- ipv6ext_vlan_tci_msg.putInt(nxm_header);
- ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLanID,
- dataLayerVirtualLanPriorityCodePoint));
- return (ipv6ext_vlan_tci_msg.array());
- }
-
- private byte[] getIPv6ExtensionVlanTCIMatchWithMaskMsg(
- short dataLayerVirtualLan,
- byte dataLayerVirtualLanPriorityCodePoint,
- int dataLayerVirtualLanTCIMask) {
- ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(8);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 1, 4);
- ipv6ext_vlan_tci_msg.putInt(nxm_header);
- ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLan,
- dataLayerVirtualLanPriorityCodePoint));
- ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask >> 8)); // bits
- // 8
- // to
- // 15
- ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask)); // bits 0
- // to 7
- return (ipv6ext_vlan_tci_msg.array());
- }
-
- private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
- ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
- IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 0,
- 16);
- ipv6ext_ipv6_msg.putInt(nxm_header);
- ipv6ext_ipv6_msg.put(srcIpv6);
- return (ipv6ext_ipv6_msg.array());
- }
-
- private byte[] getIPv6ExtensionSrcIPv6MatchwithMaskMsg(byte[] srcIpv6,
- short masklen) {
- ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
- IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 1,
- 32);
- ipv6ext_ipv6_msg.putInt(nxm_header);
- ipv6ext_ipv6_msg.put(srcIpv6);
- byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
- ipv6ext_ipv6_msg.put(ipv6_mask);
- return (ipv6ext_ipv6_msg.array());
- }
-
- private byte[] getIPv6ExtensionDstIPv6MatchMsg(byte[] dstIpv6) {
- ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
- IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 0,
- 16);
- ipv6ext_ipv6_msg.putInt(nxm_header);
- ipv6ext_ipv6_msg.put(dstIpv6);
- return (ipv6ext_ipv6_msg.array());
- }
-
- private byte[] getIPv6ExtensionDstIPv6MatchwithMaskMsg(byte[] dstIpv6,
- short masklen) {
- ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
- IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 1,
- 32);
- ipv6ext_ipv6_msg.putInt(nxm_header);
- ipv6ext_ipv6_msg.put(dstIpv6);
- byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
- ipv6ext_ipv6_msg.put(ipv6_mask);
- return (ipv6ext_ipv6_msg.array());
- }
-
- private byte[] getIPv6ExtensionProtocolMatchMsg(byte protocol) {
- ByteBuffer ipv6ext_proto_msg = ByteBuffer.allocate(5);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_IP_PROTO.getValue(), 0, 1);
- if (protocol == 0) {
- return null;
- }
- ipv6ext_proto_msg.putInt(nxm_header);
- if (protocol == IPProtocols.ICMP.getValue()) {
- /*
- * The front end passes the same protocol type values for IPv4 and
- * IPv6 flows. For the Protocol types we allow in our GUI (ICMP,
- * TCP, UDP), ICMP is the only one which is different for IPv6. It
- * is 1 for v4 and 58 for v6 Therefore, we overwrite it here.
- */
- protocol = IPProtocols.ICMPV6.getValue();
- }
- ipv6ext_proto_msg.put(protocol);
- return (ipv6ext_proto_msg.array());
- }
-
- private byte[] getIPv6ExtensionTOSMatchMsg(byte tos) {
- ByteBuffer ipv6ext_tos_msg = ByteBuffer.allocate(5);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_IP_TOS.getValue(), 0, 1);
- ipv6ext_tos_msg.putInt(nxm_header);
- ipv6ext_tos_msg.put(tos);
- return (ipv6ext_tos_msg.array());
- }
-
- private byte[] getIPv6ExtensionTCPSrcPortMatchMsg(short src_port) {
- ByteBuffer ipv6ext_tcp_srcport_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_TCP_SRC.getValue(), 0, 2);
- ipv6ext_tcp_srcport_msg.putInt(nxm_header);
- ipv6ext_tcp_srcport_msg.putShort(src_port);
- return (ipv6ext_tcp_srcport_msg.array());
- }
-
- private byte[] getIPv6ExtensionTCPDstPortMatchMsg(short dst_port) {
- ByteBuffer ipv6ext_tcp_dstport_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_TCP_DST.getValue(), 0, 2);
- ipv6ext_tcp_dstport_msg.putInt(nxm_header);
- ipv6ext_tcp_dstport_msg.putShort(dst_port);
- return (ipv6ext_tcp_dstport_msg.array());
- }
-
- private byte[] getIPv6ExtensionUDPSrcPortMatchMsg(short src_port) {
- ByteBuffer ipv6ext_udp_srcport_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_UDP_SRC.getValue(), 0, 2);
- ipv6ext_udp_srcport_msg.putInt(nxm_header);
- ipv6ext_udp_srcport_msg.putShort(src_port);
- return (ipv6ext_udp_srcport_msg.array());
- }
-
- private byte[] getIPv6ExtensionUDPDstPortMatchMsg(short dst_port) {
- ByteBuffer ipv6ext_udp_dstport_msg = ByteBuffer.allocate(6);
- int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
- OF_Match_Types.MATCH_OF_UDP_DST.getValue(), 0, 2);
- ipv6ext_udp_dstport_msg.putInt(nxm_header);
- ipv6ext_udp_dstport_msg.putShort(dst_port);
- return (ipv6ext_udp_dstport_msg.array());
- }
-
- /**
- * Sets this (V6Match) object's member variables based on a comma-separated
- * key=value pair similar to OFMatch's fromString.
- *
- * @param match
- * a key=value comma separated string.
- */
- @Override
- public void fromString(String match) throws IllegalArgumentException {
- if (match.equals("") || match.equalsIgnoreCase("any")
- || match.equalsIgnoreCase("all") || match.equals("[]")) {
- match = "OFMatch[]";
- }
- String[] tokens = match.split("[\\[,\\]]");
- String[] values;
- int initArg = 0;
- if (tokens[0].equals("OFMatch")) {
- initArg = 1;
- }
- this.wildcards = OFPFW_ALL;
- int i;
- for (i = initArg; i < tokens.length; i++) {
- values = tokens[i].split("=");
- if (values.length != 2) {
- throw new IllegalArgumentException("Token " + tokens[i]
- + " does not have form 'key=value' parsing " + match);
- }
- values[0] = values[0].toLowerCase(); // try to make this case insens
- if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
- this.inputPort = U16.t(Integer.valueOf(values[1]));
- inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
- } else if (values[0].equals(STR_DL_DST)
- || values[0].equals("eth_dst")) {
- this.dataLayerDestination = HexEncode
- .bytesFromHexString(values[1]);
- dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 10;
- } else if (values[0].equals(STR_DL_SRC)
- || values[0].equals("eth_src")) {
- this.dataLayerSource = HexEncode.bytesFromHexString(values[1]);
- dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 10;
- this.wildcards &= ~OFPFW_DL_SRC;
- } else if (values[0].equals(STR_DL_TYPE)
- || values[0].equals("eth_type")) {
- if (values[1].startsWith("0x")) {
- this.dataLayerType = U16.t(Integer.valueOf(values[1]
- .replaceFirst("0x", ""), 16));
- } else {
-
- this.dataLayerType = U16.t(Integer.valueOf(values[1]));
- }
- ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
- } else if (values[0].equals(STR_DL_VLAN)) {
- this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
- this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
- // the variable dlVlanIDState is not really used as a flag
- // for serializing and deserializing. Rather it is used as a
- // flag
- // to check if the vlan id is being set so that we can set the
- // dlVlanTCIState appropriately.
- if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len -= 2;
- } else {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.dataLayerVirtualLanTCIMask = 0x1fff;
- match_len += 8;
- }
- this.wildcards &= ~OFPFW_DL_VLAN;
- } else if (values[0].equals(STR_DL_VLAN_PCP)) {
- this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
- .valueOf(values[1]));
- this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
- // the variable dlVlanPCPState is not really used as a flag
- // for serializing and deserializing. Rather it is used as a
- // flag
- // to check if the vlan pcp is being set so that we can set the
- // dlVlanTCIState appropriately.
- if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len -= 2;
- } else {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.dataLayerVirtualLanTCIMask = 0xf000;
- match_len += 8;
- }
- this.wildcards &= ~OFPFW_DL_VLAN_PCP;
- } else if (values[0].equals(STR_NW_DST)
- || values[0].equals("ip_dst")) {
- try {
- InetAddress address = null;
- InetAddress mask = null;
- if (values[1].contains("/")) {
- String addressString[] = values[1].split("/");
- address = InetAddress.getByName(addressString[0]);
- int masklen = Integer.valueOf(addressString[1]);
- mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
- } else {
- address = InetAddress.getByName(values[1]);
- }
- this.setNetworkDestination(address, mask);
- } catch (UnknownHostException e) {
- logger.error("", e);
- }
- } else if (values[0].equals(STR_NW_SRC)
- || values[0].equals("ip_src")) {
- try {
- InetAddress address = null;
- InetAddress mask = null;
- if (values[1].contains("/")) {
- String addressString[] = values[1].split("/");
- address = InetAddress.getByName(addressString[0]);
- int masklen = Integer.valueOf(addressString[1]);
- mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
- } else {
- address = InetAddress.getByName(values[1]);
- }
- this.setNetworkSource(address, mask);
- } catch (UnknownHostException e) {
- logger.error("", e);
- }
- } else if (values[0].equals(STR_NW_PROTO)) {
- this.networkProtocol = U8.t(Short.valueOf(values[1]));
- if (!(this.networkProtocol == 0)) {
- /*
- * if user selects proto 0, don't use it
- */
- nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 5;
- }
- } else if (values[0].equals(STR_NW_TOS)) {
- this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
- nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 5;
- } else if (values[0].equals(STR_TP_DST)) {
- this.transportDestination = U16.t(Integer.valueOf(values[1]));
- tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
- } else if (values[0].equals(STR_TP_SRC)) {
- this.transportSource = U16.t(Integer.valueOf(values[1]));
- tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
- } else {
- throw new IllegalArgumentException("unknown token " + tokens[i]
- + " parsing " + match);
- }
- }
-
- /*
- * In a V6 extension message action list should be preceded by a padding
- * of 0 to 7 bytes based upon following formula.
- */
-
- pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
-
- }
-
- /**
- * Write this message's binary format to the specified ByteBuffer
- *
- * @param data
- */
- @Override
- public void writeTo(ByteBuffer data) {
- if (inputPortState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_ingress_port_msg = getIPv6ExtensionPortMatchMsg(this.inputPort);
- data.put(ipv6ext_ingress_port_msg);
- }
- if (ethTypeState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_ether_type_msg = getIPv6ExtensionEtherTypeMatchMsg(this.dataLayerType);
- data.put(ipv6ext_ether_type_msg);
- }
- if (dlDestState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_destmac_msg = getIPv6ExtensionDestMacMatchMsg(this.dataLayerDestination);
- data.put(ipv6ext_destmac_msg);
- }
- if (dlSourceState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
- data.put(ipv6ext_srcmac_msg);
- }
- if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_vlan_tci_msg = getIPv6ExtensionVlanTCIMatchMsg(
- this.dataLayerVirtualLan,
- this.dataLayerVirtualLanPriorityCodePoint);
- data.put(ipv6ext_vlan_tci_msg);
- } else if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
- byte[] ipv6ext_vlan_tci_msg_with_mask = getIPv6ExtensionVlanTCIMatchWithMaskMsg(
- this.dataLayerVirtualLan,
- this.dataLayerVirtualLanPriorityCodePoint,
- this.dataLayerVirtualLanTCIMask);
- data.put(ipv6ext_vlan_tci_msg_with_mask);
- }
- if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
- .getAddress());
- data.put(ipv6ext_src_ipv6_msg);
- } else if (nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
- byte[] ipv6ext_src_ipv6_with_mask_msg = getIPv6ExtensionSrcIPv6MatchwithMaskMsg(
- this.nwSrc.getAddress(), this.srcIPv6SubnetMaskbits);
- data.put(ipv6ext_src_ipv6_with_mask_msg);
- }
- if (nwDstState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_dst_ipv6_msg = getIPv6ExtensionDstIPv6MatchMsg(this.nwDst
- .getAddress());
- data.put(ipv6ext_dst_ipv6_msg);
- } else if (nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
- byte[] ipv6ext_dst_ipv6_with_mask_msg = getIPv6ExtensionDstIPv6MatchwithMaskMsg(
- this.nwDst.getAddress(), this.dstIPv6SubnetMaskbits);
- data.put(ipv6ext_dst_ipv6_with_mask_msg);
- }
- if (nwProtoState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_protocol_msg = getIPv6ExtensionProtocolMatchMsg(this.networkProtocol);
- if (ipv6ext_protocol_msg != null) {
- data.put(ipv6ext_protocol_msg);
- }
- }
- if (nwTosState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_tos_msg = getIPv6ExtensionTOSMatchMsg(this.networkTypeOfService);
- data.put(ipv6ext_tos_msg);
- }
- if (tpSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_srcport_msg = null;
- if (this.networkProtocol == IPProtocols.TCP.getValue()) {
- ipv6ext_srcport_msg = getIPv6ExtensionTCPSrcPortMatchMsg(this.transportSource);
- } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
- ipv6ext_srcport_msg = getIPv6ExtensionUDPSrcPortMatchMsg(this.transportSource);
- }
- if (ipv6ext_srcport_msg != null) {
- data.put(ipv6ext_srcport_msg);
- }
- }
- if (tpDstState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_dstport_msg = null;
- if (this.networkProtocol == IPProtocols.TCP.getValue()) {
- ipv6ext_dstport_msg = getIPv6ExtensionTCPDstPortMatchMsg(this.transportDestination);
- } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
- ipv6ext_dstport_msg = getIPv6ExtensionUDPDstPortMatchMsg(this.transportDestination);
- }
- if (ipv6ext_dstport_msg != null) {
- data.put(ipv6ext_dstport_msg);
- }
- }
- logger.trace("{}", this);
- }
-
- private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- /*
- * mask is not allowed for inport port
- */
- return;
- }
- super.setInputPort(data.getShort());
- this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
- this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
- this.match_len += 6;
- }
-
- private void readDataLinkDestination(ByteBuffer data, int nxmLen,
- boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
- return;
- } else {
- byte[] bytes = new byte[6];
- data.get(bytes);
- super.setDataLayerDestination(bytes);
- this.dataLayerDestinationMask = new byte[6];
- data.get(this.dataLayerDestinationMask);
- this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 16;
- }
- } else {
- if ((nxmLen != 6) || (data.remaining() < 6)) {
- return;
- } else {
- byte[] bytes = new byte[6];
- data.get(bytes);
- super.setDataLayerDestination(bytes);
- this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 10;
- }
- }
- this.wildcards ^= (1 << 3); // Sync with 0F 1.0 Match
- }
-
- private void readDataLinkSource(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in data link source
- */
- if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
- return;
- }
- byte[] bytes = new byte[6];
- data.get(bytes);
- super.setDataLayerSource(bytes);
- this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 10;
- this.wildcards ^= (1 << 2); // Sync with 0F 1.0 Match
- }
-
- private void readEtherType(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in ethertype
- */
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- return;
- }
- super.setDataLayerType(data.getShort());
- this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
- this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
- this.match_len += 6;
- }
-
- private short getVlanID(byte firstByte, byte secondByte) {
- short vlan_id_mask_firstByte = 0x0f;// this is the mask for the first
- // byte
- short vlan_id_mask_secondByte = 0xff;// this is the mask for the second
- // byte
- int vlanPart1 = (firstByte & vlan_id_mask_firstByte) << 8;
- int vlanPart2 = secondByte & vlan_id_mask_secondByte;
- return (short) (vlanPart1 + vlanPart2);
- }
-
- private byte getVlanPCP(byte pcpByte) {
- short vlan_pcp_mask = 0xe0;// this is the vlan pcp mask
- int pcp_int = pcpByte & vlan_pcp_mask;
- return (byte) (pcp_int >> 5);
- }
-
- private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
- return;
- }
- else {
- byte firstByte = data.get();
- byte secondByte = data.get();
- this.dataLayerVirtualLanTCIMask = data.getShort() & 0xffff; // we
- // need
- // the
- // last
- // 16
- // bits
- // check the mask now
- if ((this.dataLayerVirtualLanTCIMask & 0x0fff) != 0) {
- // if its a vlan id mask
- // extract the vlan id
- super.setDataLayerVirtualLan(getVlanID(firstByte,
- secondByte));
- } else {
- this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
- }
- if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
- // else if its a vlan pcp mask
- // extract the vlan pcp
- super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
- } else {
- this.wildcards ^= (1 << 20);
- }
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 8;
- }
- } else {
- if ((nxmLen != 2) || (data.remaining() < 2)) {
- return;
- }
- else {
- // get the vlan pcp
- byte firstByte = data.get();
- byte secondByte = data.get();
- super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
- super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- }
- }
- }
-
- private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in IP TOS
- */
- if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
- return;
- }
- super.setNetworkTypeOfService(data.get());
- this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 5;
- this.wildcards ^= (1 << 21); // Sync with 0F 1.0 Match
- }
-
- private void readIpProto(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in IP protocol
- */
- if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
- return;
- }
- super.setNetworkProtocol(data.get());
- this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 5;
- this.wildcards ^= (1 << 5); // Sync with 0F 1.0 Match
- }
-
- private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
- return;
- } else {
- byte[] sbytes = new byte[4];
- data.get(sbytes);
- // For compatibility, let's set the IPv4 in the parent OFMatch
- int address = NetUtils.byteArray4ToInt(sbytes);
- super.setNetworkSource(address);
- byte[] mbytes = new byte[4];
- data.get(mbytes);
- this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 12;
- int prefixlen = getNetworkMaskPrefixLength(mbytes);
- this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
- this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
- }
- } else {
- if ((nxmLen != 4) || (data.remaining() < 4)) {
- return;
- } else {
- byte[] sbytes = new byte[4];
- data.get(sbytes);
- // For compatibility, let's also set the IPv4 in the parent OFMatch
- int address = NetUtils.byteArray4ToInt(sbytes);
- super.setNetworkSource(address);
- this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 8;
- this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0
- // Match
- }
- }
- }
-
- private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
- return;
- } else {
- byte[] dbytes = new byte[4];
- data.get(dbytes);
- // For compatibility, let's also set the IPv4 in the parent OFMatch
- int address = NetUtils.byteArray4ToInt(dbytes);
- super.setNetworkDestination(address);
- byte[] mbytes = new byte[4];
- data.get(mbytes);
- this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 12;
- int prefixlen = getNetworkMaskPrefixLength(mbytes);
- this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
- // Match
- this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0
- // Match
- }
- } else {
- if ((nxmLen != 4) || (data.remaining() < 4)) {
- return;
- } else {
- byte[] dbytes = new byte[4];
- data.get(dbytes);
- int address = NetUtils.byteArray4ToInt(dbytes);
- super.setNetworkDestination(address);
- this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
- // Match
- this.match_len += 8;
- }
- }
- }
-
- private void readTcpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in TCP SRC
- */
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- return;
- }
- super.setTransportSource(data.getShort());
- this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
- }
-
- private void readTcpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in TCP DST
- */
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- return;
- }
- super.setTransportDestination(data.getShort());
- this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
- }
-
- private void readUdpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in UDP SRC
- */
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- return;
- }
- super.setTransportSource(data.getShort());
- this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
- }
-
- private void readUdpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
- /*
- * mask is not allowed in UDP DST
- */
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
- return;
- }
- super.setTransportDestination(data.getShort());
- this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
- }
-
- private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
- return;
- } else {
- byte[] sbytes = new byte[16];
- data.get(sbytes);
- try {
- this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
- } catch (UnknownHostException e) {
- return;
- }
- byte[] mbytes = new byte[16];
- data.get(mbytes);
- this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
- this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 36;
- }
- } else {
- if ((nxmLen != 16) || (data.remaining() < 16)) {
- return;
- } else {
- byte[] sbytes = new byte[16];
- data.get(sbytes);
- try {
- this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
- } catch (UnknownHostException e) {
- return;
- }
- this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 20;
- }
- }
- }
-
- private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
- if (hasMask) {
- if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
- return;
- } else {
- byte[] dbytes = new byte[16];
- data.get(dbytes);
- try {
- this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
- } catch (UnknownHostException e) {
- return;
- }
- byte[] mbytes = new byte[16];
- data.get(mbytes);
- this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
- this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 36;
- }
- } else {
- if ((nxmLen != 16) || (data.remaining() < 16)) {
- return;
- } else {
- byte[] dbytes = new byte[16];
- data.get(dbytes);
- try {
- this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
- } catch (UnknownHostException e) {
- return;
- }
- this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 20;
- }
- }
- }
-
- @Override
- public String toString() {
- return "V6Match [nwSrc=" + nwSrc + ", nwDst=" + nwDst
- + ", inputPortMask=" + inputPortMask + ", dataLayerSourceMask="
- + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
- + ", dataLayerDestinationMask="
- + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
- + ", dataLayerVirtualLanTCIMask=" + dataLayerVirtualLanTCIMask
- + ", dataLayerTypeMask=" + dataLayerTypeMask
- + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
- + ", networkProtocolMask=" + networkProtocolMask
- + ", transportSourceMask=" + transportSourceMask
- + ", transportDestinationMask=" + transportDestinationMask
- + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
- + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
- + ", inputPortState=" + inputPortState + ", dlSourceState="
- + dlSourceState + ", dlDestState=" + dlDestState
- + ", dlVlanTCIState=" + dlVlanTCIState + ", ethTypeState="
- + ethTypeState + ", nwTosState=" + nwTosState
- + ", nwProtoState=" + nwProtoState + ", nwSrcState="
- + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
- + tpSrcState + ", tpDstState=" + tpDstState + ", match_len="
- + match_len + ", pad_size=" + pad_size + "]";
- }
-
- /**
- * Read the data corresponding to the match field (received from the wire)
- * Input: data: match field(s). Since match field is of variable length, the
- * whole data that are passed in are assumed to fem0tbd.be the match fields.
- *
- * @param data
- */
- @Override
- public void readFrom(ByteBuffer data) {
- readFromInternal(data);
- postprocessWildCardInfo();
- }
-
- private void readFromInternal(ByteBuffer data) {
- this.match_len = 0;
- while (data.remaining() > 0) {
- if (data.remaining() < 4) {
- /*
- * at least 4 bytes for each match header
- */
- logger.error("Invalid Vendor Extension Header. Size {}",
- data.remaining());
- return;
- }
- /*
- * read the 4 byte match header
- */
- int nxmVendor = data.getShort();
- int b = data.get();
- int nxmField = b >> 1;
- boolean hasMask = ((b & 0x01) == 1) ? true : false;
- int nxmLen = data.get();
- if (nxmVendor == Extension_Types.OF_10.getValue()) {
- if (nxmField == OF_Match_Types.MATCH_OF_IN_PORT.getValue()) {
- readInPort(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_DST
- .getValue()) {
- readDataLinkDestination(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_SRC
- .getValue()) {
- readDataLinkSource(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_TYPE
- .getValue()) {
- readEtherType(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_VLAN_TCI
- .getValue()) {
- readVlanTci(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_IP_TOS
- .getValue()) {
- readIpTos(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_IP_PROTO
- .getValue()) {
- readIpProto(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_IP_SRC
- .getValue()) {
- readIpv4Src(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_IP_DST
- .getValue()) {
- readIpv4Dst(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_SRC
- .getValue()) {
- readTcpSrc(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_DST
- .getValue()) {
- readTcpDst(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_SRC
- .getValue()) {
- readUdpSrc(data, nxmLen, hasMask);
- } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_DST
- .getValue()) {
- readUdpDst(data, nxmLen, hasMask);
- } else {
- // unexpected nxmField
- return;
- }
- } else if (nxmVendor == Extension_Types.IPV6EXT.getValue()) {
- if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC
- .getValue()) {
- readIpv6Src(data, nxmLen, hasMask);
- } else if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST
- .getValue()) {
- readIpv6Dst(data, nxmLen, hasMask);
- } else {
- // unexpected nxmField
- return;
- }
- } else {
- // invalid nxmVendor
- return;
- }
- }
- }
-
- private void postprocessWildCardInfo() {
- // Sync with 0F 1.0 Match
- if (super.getDataLayerType() == 0x800) {
- if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
- // ipv4 src processing
- this.wildcards ^= (((1 << 5) - 1) << 8);
- }
- if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
- // ipv4 dest processing
- this.wildcards ^= (((1 << 5) - 1) << 14);
- }
- } else {
- this.wildcards = 0;
- }
- }
-
- @Override
- public V6Match clone() {
-
- V6Match ret = (V6Match) super.clone();
- try {
- if (this.nwSrc != null) {
- ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
- }
- if (this.nwDst != null) {
- ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
- }
- return ret;
- } catch (UnknownHostException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Get nw_dst
- *
- * @return
- */
-
- public Inet6Address getNetworkDest() {
- return this.nwDst;
- }
-
- /**
- * Set nw_src
- *
- * @return
- */
-
- public Inet6Address getNetworkSrc() {
- return this.nwSrc;
- }
-
- private int getNetworkMaskPrefixLength(byte[] netMask) {
- ByteBuffer nm = ByteBuffer.wrap(netMask);
- int trailingZeros = Integer.numberOfTrailingZeros(nm.getInt());
- return 32 - trailingZeros;
- }
-
- public short getInputPortMask() {
- return inputPortMask;
- }
-
- public void setInputPort(short port, short mask) {
- super.inputPort = port;
- this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
- // Looks like mask is not allowed for input port. Will discard it
- }
-
- public byte[] getDataLayerSourceMask() {
- return dataLayerSourceMask;
- }
-
- public void setDataLayerSource(byte[] mac, byte[] mask) {
- if (mac != null) {
- System.arraycopy(mac, 0, super.dataLayerSource, 0, mac.length);
- }
- if (mask == null) {
- this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 10;
- } else {
- if (this.dataLayerSourceMask == null) {
- this.dataLayerSourceMask = new byte[mask.length];
- }
- System.arraycopy(mask, 0, this.dataLayerSourceMask, 0, mask.length);
- this.dlSourceState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 16;
- }
- }
-
- public byte[] getDataLayerDestinationMask() {
- return dataLayerDestinationMask;
- }
-
- public void setDataLayerDestination(byte[] mac, byte[] mask) {
- if (mac != null) {
- System.arraycopy(mac, 0, super.dataLayerDestination, 0, mac.length);
- }
- if (mask == null) {
- this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 10;
- } else {
- if (this.dataLayerDestinationMask == null) {
- this.dataLayerDestinationMask = new byte[mask.length];
- }
- System.arraycopy(mask, 0, this.dataLayerDestinationMask, 0,
- mask.length);
- this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 16;
- }
- }
-
- public void setDataLayerVirtualLan(short vlan, short mask) {
- // mask is ignored as the code sets the appropriate mask
- super.dataLayerVirtualLan = vlan;
- this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
- // the variable dlVlanIDState is not really used as a flag
- // for serializing and deserializing. Rather it is used as a flag
- // to check if the vlan id is being set so that we can set the
- // dlVlanTCIState appropriately.
- if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len -= 2;
- } else {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.dataLayerVirtualLanTCIMask = 0x1fff;
- match_len += 8;
- }
- }
-
- public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
- // mask is ignored as the code sets the appropriate mask
- super.dataLayerVirtualLanPriorityCodePoint = pcp;
- this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
- // the variable dlVlanPCPState is not really used as a flag
- // for serializing and deserializing. Rather it is used as a flag
- // to check if the vlan pcp is being set so that we can set the
- // dlVlanTCIState appropriately.
- if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len -= 2;
- } else {
- this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.dataLayerVirtualLanTCIMask = 0xf000;
- match_len += 8;
- }
- }
-
- public void setDataLayerType(short ethType, short mask) {
- // mask not allowed
- super.dataLayerType = ethType;
- this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- }
-
- public void setNetworkTypeOfService(byte tos, byte mask) {
- // mask not allowed
- super.networkTypeOfService = tos;
- this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 5;
- }
-
- public void setNetworkProtocol(byte ipProto, byte mask) {
- // mask not allowed
- super.networkProtocol = ipProto;
- this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 5;
- }
-
- public Inet6Address getNetworkSourceMask() {
- return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
- this.srcIPv6SubnetMaskbits, true) : null;
- }
-
- public void setNetworkSource(InetAddress address, InetAddress mask) {
- if (address instanceof Inet6Address) {
- this.nwSrc = (Inet6Address) address;
- if (mask == null) {
- this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += (address instanceof Inet6Address) ? 20 : 8;
- } else {
- this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
- this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += (address instanceof Inet6Address) ? 36 : 12;
- }
- } else {
- super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
- this.wildcards ^= (((1 << 6) - 1) << 8);
- if (mask == null) {
- this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 8;
- } else {
- this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 12;
- this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
- }
- }
- }
-
- public Inet6Address getNetworkDestinationMask() {
- return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
- this.dstIPv6SubnetMaskbits, true) : null;
- }
-
- public void setNetworkDestination(InetAddress address, InetAddress mask) {
- if (address instanceof Inet6Address) {
- this.nwDst = (Inet6Address) address;
- if (mask == null) {
- this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += (address instanceof Inet6Address) ? 20 : 8;
- } else {
- this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
- this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += (address instanceof Inet6Address) ? 36 : 12;
- }
- } else {
- this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
- this.wildcards ^= (((1 << 6) - 1) << 14);
- if (mask == null) {
- this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 8;
- } else {
- this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 12;
- this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
- }
- }
- }
-
- public void setTransportSource(short tpSrc, short mask) {
- // mask not allowed
- super.transportSource = tpSrc;
- this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- }
-
- public short getTransportDestinationMask() {
- return transportDestinationMask;
- }
-
- public void setTransportDestination(short tpDst, short mask) {
- // mask not allowed
- super.transportDestination = tpDst;
- this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
- }
-
- private byte[] getIPv6NetworkMaskinBytes(short num) {
- byte[] nbytes = new byte[16];
- int quot = num / 8;
- int bits = num % 8;
- int i;
-
- for (i = 0; i < quot; i++) {
- nbytes[i] = (byte) 0xff;
- }
-
- if (bits > 0) {
- nbytes[i] = (byte) 0xff;
- nbytes[i] <<= 8 - bits;
- }
- return nbytes;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
- result = prime * result + Arrays.hashCode(dataLayerSourceMask);
- result = prime * result + dataLayerTypeMask;
- result = prime * result + dataLayerVirtualLanTCIMask;
- result = prime * result
- + ((dlDestState == null) ? 0 : dlDestState.hashCode());
- result = prime * result
- + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
- result = prime * result
- + ((dlVlanTCIState == null) ? 0 : dlVlanTCIState.hashCode());
- result = prime * result + dstIPv6SubnetMaskbits;
- result = prime * result
- + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
- result = prime * result + inputPortMask;
- result = prime * result
- + ((inputPortState == null) ? 0 : inputPortState.hashCode());
- result = prime * result + match_len;
- result = prime * result + networkProtocolMask;
- result = prime * result + networkTypeOfServiceMask;
- result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
- result = prime * result
- + ((nwDstState == null) ? 0 : nwDstState.hashCode());
- result = prime * result
- + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
- result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
- result = prime * result
- + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
- result = prime * result
- + ((nwTosState == null) ? 0 : nwTosState.hashCode());
- result = prime * result + pad_size;
- result = prime * result + srcIPv6SubnetMaskbits;
- result = prime * result
- + ((tpDstState == null) ? 0 : tpDstState.hashCode());
- result = prime * result
- + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
- result = prime * result + transportDestinationMask;
- result = prime * result + transportSourceMask;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- V6Match other = (V6Match) obj;
- if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
- return false;
- }
- if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
- return false;
- }
- if (dataLayerTypeMask != other.dataLayerTypeMask) {
- return false;
- }
- if (dataLayerVirtualLanTCIMask != other.dataLayerVirtualLanTCIMask) {
- return false;
- }
- if (dlVlanTCIState != other.dlVlanTCIState) {
- return false;
- }
- if (dlSourceState != other.dlSourceState) {
- return false;
- }
- if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
- return false;
- }
- if (ethTypeState != other.ethTypeState) {
- return false;
- }
- if (inputPortMask != other.inputPortMask) {
- return false;
- }
- if (inputPortState != other.inputPortState) {
- return false;
- }
- if (match_len != other.match_len) {
- return false;
- }
- if (networkProtocolMask != other.networkProtocolMask) {
- return false;
- }
- if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
- return false;
- }
- if (nwDst == null) {
- if (other.nwDst != null) {
- return false;
- }
- } else if (!nwDst.equals(other.nwDst)) {
- return false;
- }
- if (nwDstState != other.nwDstState) {
- return false;
- }
- if (nwProtoState != other.nwProtoState) {
- return false;
- }
- if (nwSrc == null) {
- if (other.nwSrc != null) {
- return false;
- }
- } else if (!nwSrc.equals(other.nwSrc)) {
- return false;
- }
- if (nwSrcState != other.nwSrcState) {
- return false;
- }
- if (nwTosState != other.nwTosState) {
- return false;
- }
- if (pad_size != other.pad_size) {
- return false;
- }
- if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
- return false;
- }
- if (tpDstState != other.tpDstState) {
- return false;
- }
- if (tpSrcState != other.tpSrcState) {
- return false;
- }
- if (transportDestinationMask != other.transportDestinationMask) {
- return false;
- }
- if (transportSourceMask != other.transportSourceMask) {
- return false;
- }
- return true;
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.vendorextension.v6extension;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.statistics.OFVendorStatistics;
-import org.openflow.util.U16;
-
-/**
- * This Class processes the OpenFlow Vendor Extension Reply message of a Stats
- * Request. It parses the reply message and initializes fields of V6StatsReply
- * object. Multiple instances of this class objects are created and used by
- * OpenDaylight's Troubleshooting Application.
- *
- */
-
-public class V6StatsReply extends OFVendorStatistics {
- private static final long serialVersionUID = 1L;
-
- public static int MINIMUM_LENGTH = 48; //48 for nx_flow_stats
-
- protected short length = (short) MINIMUM_LENGTH;
- protected byte tableId;
- protected int durationSeconds;
- protected int durationNanoseconds;
- protected short priority;
- protected short idleTimeout;
- protected short hardTimeout;
- protected short match_len;
- protected short idleAge;
- protected short hardAge;
- protected long cookie;
- protected long packetCount;
- protected long byteCount;
- protected V6Match match;
- protected List<OFAction> actions;
-
- /**
- * @return vendor id
- */
- public int getVendorId() {
- return vendor;
- }
-
- /**
- * @param vendor the vendor to set
- */
- public void setVendorId(int vendor) {
- this.vendor = vendor;
- }
-
- /**
- * @return the tableId
- */
- public byte getTableId() {
- return tableId;
- }
-
- /**
- * @param tableId the tableId to set
- */
- public void setTableId(byte tableId) {
- this.tableId = tableId;
- }
-
- /**
- * @return the durationSeconds
- */
- public int getDurationSeconds() {
- return durationSeconds;
- }
-
- /**
- * @param durationSeconds the durationSeconds to set
- */
- public void setDurationSeconds(int durationSeconds) {
- this.durationSeconds = durationSeconds;
- }
-
- /**
- * @return the durationNanoseconds
- */
- public int getDurationNanoseconds() {
- return durationNanoseconds;
- }
-
- /**
- * @param durationNanoseconds the durationNanoseconds to set
- */
- public void setDurationNanoseconds(int durationNanoseconds) {
- this.durationNanoseconds = durationNanoseconds;
- }
-
- /**
- * @return the priority
- */
- public short getPriority() {
- return priority;
- }
-
- /**
- * @param priority the priority to set
- */
- public void setPriority(short priority) {
- this.priority = priority;
- }
-
- /**
- * @return the idleTimeout
- */
- public short getIdleTimeout() {
- return idleTimeout;
- }
-
- /**
- * @param idleTimeout the idleTimeout to set
- */
- public void setIdleTimeout(short idleTimeout) {
- this.idleTimeout = idleTimeout;
- }
-
- /**
- * @return the hardTimeout
- */
- public short getHardTimeout() {
- return hardTimeout;
- }
-
- /**
- * @param hardTimeout the hardTimeout to set
- */
- public void setHardTimeout(short hardTimeout) {
- this.hardTimeout = hardTimeout;
- }
-
- /**
- * @param match_len the match_len to set
- */
- public void setMatchLen(short match_len) {
- this.match_len = match_len;
- }
-
- /**
- * @return the match_len
- */
- public short getMatchLen() {
- return match_len;
- }
-
- /**
- * @return the idleAge
- */
- public short getIdleAge() {
- return idleAge;
- }
-
- /**
- * @param idleAge the idleAge to set
- */
- public void setIdleAge(short idleAge) {
- this.idleAge = idleAge;
- }
-
- /**
- * @return the hardAge
- */
- public short getHardAge() {
- return hardAge;
- }
-
- /**
- * @param hardAge the hardAge to set
- */
- public void setHardAge(short hardAge) {
- this.hardAge = hardAge;
- }
-
- /**
- * @return the cookie
- */
- public long getCookie() {
- return cookie;
- }
-
- /**
- * @param cookie the cookie to set
- */
- public void setCookie(long cookie) {
- this.cookie = cookie;
- }
-
- /**
- * @return the packetCount
- */
- public long getPacketCount() {
- return packetCount;
- }
-
- /**
- * @param packetCount the packetCount to set
- */
- public void setPacketCount(long packetCount) {
- this.packetCount = packetCount;
- }
-
- /**
- * @return the byteCount
- */
- public long getByteCount() {
- return byteCount;
- }
-
- /**
- * @param byteCount the byteCount to set
- */
- public void setByteCount(long byteCount) {
- this.byteCount = byteCount;
- }
-
- /**
- * @param length the length to set
- */
- public void setLength(short length) {
- this.length = length;
- }
-
- @Override
- public int getLength() {
- return U16.f(length);
- }
-
- /**
- * @return the match
- */
- public V6Match getMatch() {
- return match;
- }
-
- /**
- * @return the actions
- */
- public List<OFAction> getActions() {
- return actions;
- }
-
- /**
- * @param actions the actions to set
- */
- public void setActions(List<OFAction> actions) {
- this.actions = actions;
- }
-
- @Override
- public void readFrom(ByteBuffer data) {
- short i;
- this.length = data.getShort();
- if (length < MINIMUM_LENGTH)
- return; //TBD - Spurious Packet?
- this.tableId = data.get();
- data.get(); // pad
- this.durationSeconds = data.getInt();
- this.durationNanoseconds = data.getInt();
- this.priority = data.getShort();
- this.idleTimeout = data.getShort();
- this.hardTimeout = data.getShort();
- this.match_len = data.getShort();
- this.idleAge = data.getShort();
- this.hardAge = data.getShort();
- this.cookie = data.getLong();
- this.packetCount = data.getLong();
- this.byteCount = data.getLong();
- if (this.length == MINIMUM_LENGTH) {
- return; //TBD - can this happen??
- }
- if (this.match == null)
- this.match = new V6Match();
- ByteBuffer mbuf = ByteBuffer.allocate(match_len);
- for (i = 0; i < match_len; i++) {
- mbuf.put(data.get());
- }
- mbuf.rewind();
- this.match.readFrom(mbuf);
- if (this.actionFactory == null)
- throw new RuntimeException("OFActionFactory not set");
- /*
- * action list may be preceded by a padding of 0 to 7 bytes based upon this:
- */
- short pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
- for (i = 0; i < pad_size; i++)
- data.get();
- int action_len = this.length - MINIMUM_LENGTH - (match_len + pad_size);
- if (action_len > 0)
- this.actions = this.actionFactory.parseActions(data, action_len);
- }
-
- @Override
- public void writeTo(ByteBuffer data) {
- super.writeTo(data);//TBD. This Fn needs work. Should never get called though.
-
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + ((actions == null) ? 0 : actions.hashCode());
- result = prime * result + (int) (byteCount ^ (byteCount >>> 32));
- result = prime * result + (int) (cookie ^ (cookie >>> 32));
- result = prime * result + durationNanoseconds;
- result = prime * result + durationSeconds;
- result = prime * result + hardAge;
- result = prime * result + hardTimeout;
- result = prime * result + idleAge;
- result = prime * result + idleTimeout;
- result = prime * result + length;
- result = prime * result + ((match == null) ? 0 : match.hashCode());
- result = prime * result + match_len;
- result = prime * result + (int) (packetCount ^ (packetCount >>> 32));
- result = prime * result + priority;
- result = prime * result + tableId;
- return result;
- }
-
- @Override
- public String toString() {
- return "V6StatsReply [length=" + length + ", tableId=" + tableId
- + ", durationSeconds=" + durationSeconds
- + ", durationNanoseconds=" + durationNanoseconds
- + ", priority=" + priority + ", idleTimeout=" + idleTimeout
- + ", hardTimeout=" + hardTimeout + ", match_len=" + match_len
- + ", idleAge=" + idleAge + ", hardAge=" + hardAge + ", cookie="
- + cookie + ", packetCount=" + packetCount + ", byteCount="
- + byteCount + ", match=" + match + ", actions=" + actions + "]";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (getClass() != obj.getClass())
- return false;
- V6StatsReply other = (V6StatsReply) obj;
- if (actions == null) {
- if (other.actions != null)
- return false;
- } else if (!actions.equals(other.actions))
- return false;
- if (byteCount != other.byteCount)
- return false;
- if (cookie != other.cookie)
- return false;
- if (durationNanoseconds != other.durationNanoseconds)
- return false;
- if (durationSeconds != other.durationSeconds)
- return false;
- if (hardAge != other.hardAge)
- return false;
- if (hardTimeout != other.hardTimeout)
- return false;
- if (idleAge != other.idleAge)
- return false;
- if (idleTimeout != other.idleTimeout)
- return false;
- if (length != other.length)
- return false;
- if (match == null) {
- if (other.match != null)
- return false;
- } else if (!match.equals(other.match))
- return false;
- if (match_len != other.match_len)
- return false;
- if (packetCount != other.packetCount)
- return false;
- if (priority != other.priority)
- return false;
- if (tableId != other.tableId)
- return false;
- return true;
- }
-
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.openflow.vendorextension.v6extension;
-
-import java.nio.ByteBuffer;
-
-import org.openflow.protocol.statistics.OFVendorStatistics;
-
-
-/**
- * This Class creates the OpenFlow Vendor Extension IPv6 Flow Stats Request
- * messages and also reads the Reply of a stats request message.
- *
- */
-
-public class V6StatsRequest extends OFVendorStatistics {
- private static final long serialVersionUID = 1L;
- protected int msgsubtype;
- protected short outPort;
- protected short match_len;
- protected byte tableId;
-
- public static final int NICIRA_VENDOR_ID = 0x00002320; //Nicira ID
- private static final int NXST_FLOW = 0x0; //Nicira Flow Stats Request Id
-
- public V6StatsRequest() {
- this.vendor = NICIRA_VENDOR_ID;
- this.msgsubtype = NXST_FLOW;
- this.match_len = 0;
- }
-
- /**
- * @param None. Being set with local variable (TBD).
- */
- public void setVendorId() {
- this.vendor = NICIRA_VENDOR_ID;
- }
-
- /**
- * @return vendor id
- */
- public int getVendorId() {
- return vendor;
- }
-
- /**
- * @param None. Being set with local variable (TBD).
- */
- public void setMsgtype() {
- this.msgsubtype = NXST_FLOW;
- }
-
- /**
- * @return vendor_msgtype
- */
- public int getMsgtype() {
- return msgsubtype;
- }
-
- /**
- * @param outPort the outPort to set
- */
- public void setOutPort(short outPort) {
- this.outPort = outPort;
- }
-
- /**
- * @return the outPort
- */
- public short getOutPort() {
- return outPort;
- }
-
- /**
- * @param match_len the match_len to set
- */
- public void setMatchLen(short match_len) {
- this.match_len = match_len;
- }
-
- /**
- * @return the match_len
- */
- public short getMatchLen() {
- return match_len;
- }
-
- /**
- * @param tableId the tableId to set
- */
- public void setTableId(byte tableId) {
- this.tableId = tableId;
- }
-
- /**
- * @return the tableId
- */
- public byte getTableId() {
- return tableId;
- }
-
- @Override
- public int getLength() {
- return 20;// 4(vendor)+4(msgsubtype)+4(pad)+2(outPort)+2(match_len)+1(tableid)+3(pad)
- }
-
- @Override
- public void readFrom(ByteBuffer data) {
- this.vendor = data.getInt();
- this.msgsubtype = data.getInt();
- data.getInt();//pad 4 bytes
- this.outPort = data.getShort();
- this.match_len = data.getShort();
- this.tableId = data.get();
- for (int i = 0; i < 3; i++)
- data.get();//pad byte
-
- }
-
- @Override
- public void writeTo(ByteBuffer data) {
- data.putInt(this.vendor);
- data.putInt(this.msgsubtype);
- data.putInt((int) 0x0);//pad0
- data.putShort(this.outPort);
- data.putShort(this.match_len);
- data.put(this.tableId);
- for (int i = 0; i < 3; i++)
- data.put((byte) 0x0);//pad byte
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + match_len;
- result = prime * result + msgsubtype;
- result = prime * result + outPort;
- result = prime * result + tableId;
- return result;
- }
-
- @Override
- public String toString() {
- return "V6StatsRequest [msgsubtype=" + msgsubtype + ", outPort="
- + outPort + ", match_len=" + match_len + ", tableId=" + tableId
- + "]";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (getClass() != obj.getClass())
- return false;
- V6StatsRequest other = (V6StatsRequest) obj;
- if (match_len != other.match_len)
- return false;
- if (msgsubtype != other.msgsubtype)
- return false;
- if (outPort != other.outPort)
- return false;
- if (tableId != other.tableId)
- return false;
- return true;
- }
-}
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.protocol_plugin.openflow.internal;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.action.OFAction;
-
-import org.opendaylight.controller.sal.action.Action;
-import org.opendaylight.controller.sal.action.Flood;
-import org.opendaylight.controller.sal.action.FloodAll;
-import org.opendaylight.controller.sal.action.HwPath;
-import org.opendaylight.controller.sal.action.Loopback;
-import org.opendaylight.controller.sal.action.Output;
-import org.opendaylight.controller.sal.action.PopVlan;
-import org.opendaylight.controller.sal.action.SetDlDst;
-import org.opendaylight.controller.sal.action.SetDlSrc;
-import org.opendaylight.controller.sal.action.SetNwDst;
-import org.opendaylight.controller.sal.action.SetNwSrc;
-import org.opendaylight.controller.sal.action.SetNwTos;
-import org.opendaylight.controller.sal.action.SetTpDst;
-import org.opendaylight.controller.sal.action.SetTpSrc;
-import org.opendaylight.controller.sal.action.SetVlanId;
-import org.opendaylight.controller.sal.action.SwPath;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.match.Match;
-import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.utils.EtherTypes;
-import org.opendaylight.controller.sal.utils.IPProtocols;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.openflowplugin.openflow.internal.FlowConverter;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6Match;
-
-public class FlowProgrammerServiceTest {
-
- @Test
- public void testSALtoOFFlowConverter() throws UnknownHostException {
- Node node = NodeCreator.createOFNode(1000l);
- NodeConnector port = NodeConnectorCreator.createNodeConnector(
- (short) 24, node);
- NodeConnector oport = NodeConnectorCreator.createNodeConnector(
- (short) 30, node);
- byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
- (byte) 0x9a, (byte) 0xbc };
- byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
- (byte) 0x5e, (byte) 0x6f };
- InetAddress srcIP = InetAddress.getByName("172.28.30.50");
- InetAddress dstIP = InetAddress.getByName("171.71.9.52");
- InetAddress ipMask = InetAddress.getByName("255.255.255.0");
- short ethertype = EtherTypes.IPv4.shortValue();
- short vlan = (short) 27;
- byte vlanPr = 3;
- Byte tos = 4;
- byte proto = IPProtocols.TCP.byteValue();
- short src = (short) 55000;
- short dst = 80;
-
- /*
- * Create a SAL Flow aFlow
- */
- Match match = new Match();
- match.setField(MatchType.IN_PORT, port);
- match.setField(MatchType.DL_SRC, srcMac);
- match.setField(MatchType.DL_DST, dstMac);
- match.setField(MatchType.DL_TYPE, ethertype);
- match.setField(MatchType.DL_VLAN, vlan);
- match.setField(MatchType.DL_VLAN_PR, vlanPr);
- match.setField(MatchType.NW_SRC, srcIP, ipMask);
- match.setField(MatchType.NW_DST, dstIP, ipMask);
- match.setField(MatchType.NW_TOS, tos);
- match.setField(MatchType.NW_PROTO, proto);
- match.setField(MatchType.TP_SRC, src);
- match.setField(MatchType.TP_DST, dst);
-
- Assert.assertTrue(match.isIPv4());
-
- List<Action> actions = new ArrayList<Action>();
- // Setting all the actions supported by of
- actions.add(new PopVlan());
- actions.add(new Output(oport));
- actions.add(new Flood());
- actions.add(new FloodAll());
- actions.add(new SwPath());
- actions.add(new HwPath());
- actions.add(new Loopback());
- byte mac[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
- actions.add(new SetDlSrc(mac));
- actions.add(new SetDlDst(mac));
- actions.add(new SetNwSrc(dstIP));
- actions.add(new SetNwDst(srcIP));
- actions.add(new SetNwTos(3));
- actions.add(new SetTpSrc(10));
- actions.add(new SetTpDst(20));
- actions.add(new SetVlanId(200));
-
- Flow aFlow = new Flow(match, actions);
-
- /*
- * Convert the SAL aFlow to OF Flow
- */
- FlowConverter salToOF = new FlowConverter(aFlow);
- OFMatch ofMatch = salToOF.getOFMatch();
- List<OFAction> ofActions = salToOF.getOFActions();
-
- /*
- * Convert the OF Flow to SAL Flow bFlow
- */
- FlowConverter ofToSal = new FlowConverter(ofMatch, ofActions);
- Flow bFlow = ofToSal.getFlow(node);
- Match bMatch = bFlow.getMatch();
- List<Action> bActions = bFlow.getActions();
-
- /*
- * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
- */
- Assert.assertTrue(((NodeConnector) match.getField(MatchType.IN_PORT)
- .getValue()).equals(((NodeConnector) bMatch.getField(
- MatchType.IN_PORT).getValue())));
- Assert.assertTrue(Arrays.equals((byte[]) match.getField(
- MatchType.DL_SRC).getValue(), (byte[]) bMatch.getField(
- MatchType.DL_SRC).getValue()));
- Assert.assertTrue(Arrays.equals((byte[]) match.getField(
- MatchType.DL_DST).getValue(), (byte[]) bMatch.getField(
- MatchType.DL_DST).getValue()));
- Assert
- .assertTrue(((Short) match.getField(MatchType.DL_TYPE)
- .getValue()).equals((Short) bMatch.getField(
- MatchType.DL_TYPE).getValue()));
- Assert
- .assertTrue(((Short) match.getField(MatchType.DL_VLAN)
- .getValue()).equals((Short) bMatch.getField(
- MatchType.DL_VLAN).getValue()));
- Assert.assertTrue(((Byte) match.getField(MatchType.DL_VLAN_PR)
- .getValue()).equals((Byte) bMatch
- .getField(MatchType.DL_VLAN_PR).getValue()));
- Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_SRC)
- .getValue()).equals((InetAddress) bMatch.getField(
- MatchType.NW_SRC).getValue()));
- Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_SRC)
- .getMask()).equals((InetAddress) bMatch.getField(
- MatchType.NW_SRC).getMask()));
- Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_DST)
- .getValue()).equals((InetAddress) bMatch.getField(
- MatchType.NW_DST).getValue()));
- Assert.assertTrue(((InetAddress) match.getField(MatchType.NW_DST)
- .getMask()).equals((InetAddress) bMatch.getField(
- MatchType.NW_DST).getMask()));
- Assert
- .assertTrue(((Byte) match.getField(MatchType.NW_PROTO)
- .getValue()).equals((Byte) bMatch.getField(
- MatchType.NW_PROTO).getValue()));
- Assert.assertTrue(((Byte) match.getField(MatchType.NW_TOS).getValue())
- .equals((Byte) bMatch.getField(MatchType.NW_TOS).getValue()));
- Assert.assertTrue(((Short) match.getField(MatchType.TP_SRC).getValue())
- .equals((Short) bMatch.getField(MatchType.TP_SRC).getValue()));
- Assert.assertTrue(((Short) match.getField(MatchType.TP_DST).getValue())
- .equals((Short) bMatch.getField(MatchType.TP_DST).getValue()));
-
- // FlowConverter parses and sets the actions in the same order for sal match and of match
- for (short i = 0; i < actions.size(); i++) {
- Assert.assertTrue(actions.get(i).equals(bActions.get(i)));
- }
- }
-
- @Test
- public void testVlanNoneIdFlowConversion() throws Exception {
- Node node = NodeCreator.createOFNode(1000l);
-
- /*
- * The value 0 is used to indicate that no VLAN ID is set
- * for SAL Flow.
- */
- short vlan = (short) 0;
-
- /*
- * Create a SAL Flow aFlow
- */
- Match match = new Match();
- match.setField(MatchType.DL_VLAN, vlan);
-
- List<Action> actions = new ArrayList<Action>();
-
- Flow aFlow = new Flow(match, actions);
-
- /*
- * Convert the SAL aFlow to OF Flow
- */
- FlowConverter salToOF = new FlowConverter(aFlow);
- OFMatch ofMatch = salToOF.getOFMatch();
- List<OFAction> ofActions = salToOF.getOFActions();
-
- /*
- * The value 0xffff (OFP_VLAN_NONE) is used to indicate
- * that no VLAN ID is set for OF Flow.
- */
- Assert.assertEquals((short) 0xffff, ofMatch.getDataLayerVirtualLan());
-
- /*
- * Convert the OF Flow to SAL Flow bFlow
- */
- FlowConverter ofToSal = new FlowConverter(ofMatch, ofActions);
- Flow bFlow = ofToSal.getFlow(node);
- Match bMatch = bFlow.getMatch();
-
- /*
- * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
- */
- Assert
- .assertTrue(((Short) match.getField(MatchType.DL_VLAN)
- .getValue()).equals((Short) bMatch.getField(
- MatchType.DL_VLAN).getValue()));
- }
-
- @Test
- public void testV6toSALFlowConversion() throws Exception {
- Node node = NodeCreator.createOFNode(12l);
- NodeConnector port = NodeConnectorCreator.createNodeConnector(
- (short) 34, node);
- NodeConnector oport = NodeConnectorCreator.createNodeConnector(
- (short) 30, node);
- byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
- (byte) 0x9a, (byte) 0xbc };
- byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
- (byte) 0x5e, (byte) 0x6f };
- InetAddress srcIP = InetAddress
- .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
- InetAddress dstIP = InetAddress
- .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
- InetAddress ipMask = InetAddress
- .getByName("ffff:ffff:ffff:ffff:0:0:0:0");
- short ethertype = EtherTypes.IPv6.shortValue();
- short vlan = (short) 27;
- byte vlanPr = 3;
- Byte tos = 4;
- byte proto = IPProtocols.TCP.byteValue();
- short src = (short) 55000;
- short dst = 80;
-
- /*
- * Create a SAL Flow aFlow
- */
- Match aMatch = new Match();
-
- aMatch.setField(MatchType.IN_PORT, port);
- aMatch.setField(MatchType.DL_SRC, srcMac);
- aMatch.setField(MatchType.DL_DST, dstMac);
- aMatch.setField(MatchType.DL_TYPE, ethertype);
- aMatch.setField(MatchType.DL_VLAN, vlan);
- aMatch.setField(MatchType.DL_VLAN_PR, vlanPr);
- aMatch.setField(MatchType.NW_SRC, srcIP, ipMask);
- aMatch.setField(MatchType.NW_DST, dstIP, ipMask);
- aMatch.setField(MatchType.NW_TOS, tos);
- aMatch.setField(MatchType.NW_PROTO, proto);
- aMatch.setField(MatchType.TP_SRC, src);
- aMatch.setField(MatchType.TP_DST, dst);
-
- Assert.assertTrue(aMatch.isIPv6());
-
- List<Action> actions = new ArrayList<Action>();
- // Setting all the actions supported by of for v6
- actions.add(new PopVlan());
- actions.add(new Output(oport));
- actions.add(new Flood());
- actions.add(new FloodAll());
- actions.add(new SwPath());
- actions.add(new HwPath());
- actions.add(new Loopback());
- byte mac[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
- actions.add(new SetDlSrc(mac));
- actions.add(new SetDlDst(mac));
- //actions.add(new SetNwSrc(dstIP)); Nicira extensions do not provide IPv6 match addresses change
- //actions.add(new SetNwDst(srcIP));
- actions.add(new SetNwTos(3));
- actions.add(new SetTpSrc(10));
- actions.add(new SetTpDst(65535));
- actions.add(new SetVlanId(200));
-
- Flow aFlow = new Flow(aMatch, actions);
-
- /*
- * Convert the SAL aFlow to OF Flow
- */
- FlowConverter salToOF = new FlowConverter(aFlow);
- V6Match v6Match = (V6Match) salToOF.getOFMatch();
- List<OFAction> ofActions = salToOF.getOFActions();
-
- /*
- * Convert the OF Flow to SAL Flow bFlow
- */
- FlowConverter ofToSal = new FlowConverter(v6Match, ofActions);
- Flow bFlow = ofToSal.getFlow(node);
- Match bMatch = bFlow.getMatch();
- List<Action> bActions = bFlow.getActions();
-
- /*
- * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow
- */
- Assert.assertTrue(((NodeConnector) aMatch.getField(MatchType.IN_PORT)
- .getValue()).equals(((NodeConnector) bMatch.getField(
- MatchType.IN_PORT).getValue())));
- Assert.assertTrue(Arrays.equals((byte[]) aMatch.getField(
- MatchType.DL_SRC).getValue(), (byte[]) bMatch.getField(
- MatchType.DL_SRC).getValue()));
- Assert.assertTrue(Arrays.equals((byte[]) aMatch.getField(
- MatchType.DL_DST).getValue(), (byte[]) bMatch.getField(
- MatchType.DL_DST).getValue()));
- Assert.assertTrue(((Short) aMatch.getField(MatchType.DL_TYPE)
- .getValue()).equals((Short) bMatch.getField(MatchType.DL_TYPE)
- .getValue()));
- Assert.assertTrue(((Short) aMatch.getField(MatchType.DL_VLAN)
- .getValue()).equals((Short) bMatch.getField(MatchType.DL_VLAN)
- .getValue()));
- Assert.assertTrue(((Byte) aMatch.getField(MatchType.DL_VLAN_PR)
- .getValue()).equals((Byte) bMatch
- .getField(MatchType.DL_VLAN_PR).getValue()));
- Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_SRC)
- .getValue()).equals((InetAddress) bMatch.getField(
- MatchType.NW_SRC).getValue()));
- Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_SRC)
- .getMask()).equals((InetAddress) bMatch.getField(
- MatchType.NW_SRC).getMask()));
- Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_DST)
- .getValue()).equals((InetAddress) bMatch.getField(
- MatchType.NW_DST).getValue()));
- Assert.assertTrue(((InetAddress) aMatch.getField(MatchType.NW_DST)
- .getMask()).equals((InetAddress) bMatch.getField(
- MatchType.NW_DST).getMask()));
- Assert.assertTrue(((Byte) aMatch.getField(MatchType.NW_PROTO)
- .getValue()).equals((Byte) bMatch.getField(MatchType.NW_PROTO)
- .getValue()));
- Assert.assertTrue(((Byte) aMatch.getField(MatchType.NW_TOS).getValue())
- .equals((Byte) bMatch.getField(MatchType.NW_TOS).getValue()));
- Assert
- .assertTrue(((Short) aMatch.getField(MatchType.TP_SRC)
- .getValue()).equals((Short) bMatch.getField(
- MatchType.TP_SRC).getValue()));
- Assert
- .assertTrue(((Short) aMatch.getField(MatchType.TP_DST)
- .getValue()).equals((Short) bMatch.getField(
- MatchType.TP_DST).getValue()));
-
- // FlowConverter parses and sets the actions in the same order for sal match and of match
- for (short i = 0; i < actions.size(); i++) {
- Assert.assertTrue(actions.get(i).equals(bActions.get(i)));
- }
- }
-
- @Test
- public void testV6MatchToSALMatchToV6MatchConversion()
- throws UnknownHostException {
- NodeConnector port = NodeConnectorCreator.createNodeConnector(
- (short) 24, NodeCreator.createOFNode(6l));
- byte srcMac[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78,
- (byte) 0x9a, (byte) 0xbc };
- byte dstMac[] = { (byte) 0x1a, (byte) 0x2b, (byte) 0x3c, (byte) 0x4d,
- (byte) 0x5e, (byte) 0x6f };
- InetAddress srcIP = InetAddress
- .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
- InetAddress dstIP = InetAddress
- .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
- InetAddress ipMask = null;//InetAddress.getByName("ffff:ffff:ffff:ffff:0:0:0:0");
- short ethertype = EtherTypes.IPv6.shortValue();
- short vlan = (short) 27;
- byte vlanPr = 3;
- Byte tos = 4;
- byte proto = IPProtocols.TCP.byteValue();
- short src = (short) 55000;
- short dst = 80;
-
- /*
- * Create a SAL Flow aFlow
- */
- Match aMatch = new Match();
-
- aMatch.setField(MatchType.IN_PORT, port);
- aMatch.setField(MatchType.DL_SRC, srcMac);
- aMatch.setField(MatchType.DL_DST, dstMac);
- aMatch.setField(MatchType.DL_TYPE, ethertype);
- aMatch.setField(MatchType.DL_VLAN, vlan);
- aMatch.setField(MatchType.DL_VLAN_PR, vlanPr);
- aMatch.setField(MatchType.NW_SRC, srcIP, ipMask);
- aMatch.setField(MatchType.NW_DST, dstIP, ipMask);
- aMatch.setField(MatchType.NW_TOS, tos);
- aMatch.setField(MatchType.NW_PROTO, proto);
- aMatch.setField(MatchType.TP_SRC, src);
- aMatch.setField(MatchType.TP_DST, dst);
-
- Assert.assertTrue(aMatch.isIPv6());
-
- }
-}
+++ /dev/null
-package org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension;
-
-import static org.junit.Assert.fail;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.openflowplugin.openflow.vendorextension.v6extension.V6Match;
-import org.openflow.protocol.OFMatch;
-
-public class V6ExtensionTest {
-
- @Test
- public void testFromString() throws UnknownHostException {
- // This tests creating V6Match using fromString and OFMatch by comparing
- // the results to each other
- V6Match match = new V6Match();
- V6Match match2 = new V6Match();
-
- OFMatch ofm = new OFMatch();
- V6Match match4 = new V6Match(ofm);
-
- match.fromString("");
- Assert.assertTrue(match.equals(match2));
- match.fromString("any");
- Assert.assertTrue(match.equals(match2));
- Assert.assertTrue(match.equals(match4));
- try {
- match.fromString("invalidArgument");
-
- fail("Did not throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // passed test for throwing exception.
- }
- try {
- match.fromString("invalidParameter=abcdefg");
- fail("Did not throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // passed test for throwing exception.
- }
-
- match.fromString("input_port=1");
- match.fromString("dl_dst=20:A0:11:10:00:99");
- match.fromString("dl_src=00:10:08:22:12:75");
-
- match.fromString("ip_src=10.1.1.1");
- match.fromString("ip_dst=1.2.3.4");
- match.fromString("eth_type=0x800");
- match.fromString("dl_vlan=10");
- match.fromString("dl_vpcp=1");
- match.fromString("nw_proto=6");
- match.fromString("nw_tos=100");
- match.fromString("tp_dst=8080");
- match.fromString("tp_src=60");
-
- Assert.assertTrue(match.getInputPort() == 1);
- // Assert.assertTrue(match.getIPv6MatchLen()==6);
-
- ofm.setInputPort((short) 1);
- // V6Match is meant for IPv6, but if using OFMatch, it will be set to
- // IPv4 values, as OF1.0 doesn't support IPv6.
- InetAddress addr = InetAddress.getByName("10.1.1.1");
- int ipsrc = ByteBuffer.wrap(addr.getAddress()).getInt();
- ofm.setNetworkSource(ipsrc);
-
- addr = InetAddress.getByName("1.2.3.4");
- int ipdst = ByteBuffer.wrap(addr.getAddress()).getInt();
- ofm.setNetworkDestination(ipdst);
-
- byte[] macSrc = { 0x00, 0x10, 0x08, 0x22, 0x12, 0x75 };
- ofm.setDataLayerSource(macSrc);
- byte[] macDst = { 0x20, (byte) 0xA0, 0x11, 0x10, 0x00, (byte) 0x99 };
- ofm.setDataLayerDestination(macDst);
- ofm.setDataLayerType((short) 0x800);
- ofm.setDataLayerVirtualLan((short) 10);
- ofm.setDataLayerVirtualLanPriorityCodePoint((byte) 1);
- ofm.setNetworkProtocol((byte) 6);
- ofm.setNetworkTypeOfService((byte) 100);
- ofm.setTransportSource((short) 60);
- ofm.setTransportDestination((short) 8080);
-
- V6Match match3 = new V6Match(ofm);
-
- Assert.assertTrue(match.getInputPort() == match3.getInputPort());
- Assert.assertTrue(Arrays.equals(match.getDataLayerSource(),
- match3.getDataLayerSource()));
- Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(),
- match3.getDataLayerDestination()));
- Assert.assertNull(match.getNetworkSrc());
- Assert.assertNull(match3.getNetworkSrc());
- Assert.assertNull(match.getNetworkDest());
- Assert.assertNull(match3.getNetworkDest());
- Assert.assertTrue(match.getDataLayerVirtualLan() == match3
- .getDataLayerVirtualLan());
- Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match3
- .getDataLayerVirtualLanPriorityCodePoint());
- Assert.assertTrue(match.getNetworkProtocol() == match3
- .getNetworkProtocol());
- Assert.assertTrue(match.getNetworkTypeOfService() == match3
- .getNetworkTypeOfService());
- Assert.assertTrue(match.getTransportSource() == match3
- .getTransportSource());
- Assert.assertTrue(match.getTransportDestination() == match3
- .getTransportDestination());
- Assert.assertTrue(match.getWildcards() == match3.getWildcards());
-
- }
-
- @Test
- public void testReadWriteBuffer() {
- V6Match match = new V6Match();
- match.fromString("input_port=1");
- match.fromString("dl_dst=20:A0:11:10:00:99");
- match.fromString("dl_src=00:10:08:22:12:75");
- // writeTo(ByteBuffer) will only write IPv6
- match.fromString("ip_src=2001:ddd:3e1:1234:0000:1111:2222:3333/64");
- match.fromString("ip_dst=2001:123:222:abc:111:aaa:1111:2222/64");
- match.fromString("dl_vlan=10");
- match.fromString("dl_vpcp=1");
- match.fromString("nw_proto=6");
- match.fromString("nw_tos=100");
- match.fromString("tp_dst=8080");
- match.fromString("tp_src=60");
- match.fromString("dl_type=0x800");
-
- ByteBuffer data = ByteBuffer.allocateDirect(10000);
- match.writeTo(data);
- data.flip();
- V6Match match2 = new V6Match();
- match2.readFrom(data);
- Assert.assertTrue(match.getInputPort() == match2.getInputPort());
- Assert.assertTrue(Arrays.equals(match.getDataLayerSource(),
- match2.getDataLayerSource()));
- Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(),
- match2.getDataLayerDestination()));
-
- Assert.assertTrue(match.getNetworkSrc().equals(match2.getNetworkSrc()));
- Assert.assertTrue(match.getNetworkDest()
- .equals(match2.getNetworkDest()));
-
- Assert.assertTrue(match.getDataLayerVirtualLan() == match2
- .getDataLayerVirtualLan());
- Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match2
- .getDataLayerVirtualLanPriorityCodePoint());
- Assert.assertTrue(match.getNetworkProtocol() == match2
- .getNetworkProtocol());
- Assert.assertTrue(match.getNetworkTypeOfService() == match2
- .getNetworkTypeOfService());
- Assert.assertTrue(match.getTransportSource() == match2
- .getTransportSource());
- Assert.assertTrue(match.getTransportDestination() == match2
- .getTransportDestination());
-
- }
-
- @Test
- public void testClone() {
- V6Match match = new V6Match();
- match.fromString("input_port=1");
- match.fromString("dl_dst=20:A0:11:10:00:99");
- match.fromString("dl_src=00:10:08:22:12:75");
- match.fromString("ip_src=2001:ddd:3e1:1234:0000:1111:2222:3333/64");
- match.fromString("ip_dst=2001:123:222:abc:111:aaa:1111:2222/64");
- match.fromString("dl_vlan=10");
- match.fromString("dl_vpcp=1");
- match.fromString("nw_proto=6");
- match.fromString("nw_tos=100");
- match.fromString("tp_dst=8080");
- match.fromString("tp_src=60");
- match.fromString("dl_type=0x800");
-
- V6Match match2 = match.clone();
- Assert.assertTrue(match.getInputPort() == match2.getInputPort());
- Assert.assertTrue(Arrays.equals(match.getDataLayerSource(),
- match2.getDataLayerSource()));
- Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(),
- match2.getDataLayerDestination()));
- Assert.assertTrue(match.getNetworkSrc().equals(match2.getNetworkSrc()));
- Assert.assertTrue(match.getNetworkDest()
- .equals(match2.getNetworkDest()));
- Assert.assertTrue(match.getDataLayerVirtualLan() == match2
- .getDataLayerVirtualLan());
- Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match2
- .getDataLayerVirtualLanPriorityCodePoint());
- Assert.assertTrue(match.getNetworkProtocol() == match2
- .getNetworkProtocol());
- Assert.assertTrue(match.getNetworkTypeOfService() == match2
- .getNetworkTypeOfService());
- Assert.assertTrue(match.getTransportSource() == match2
- .getTransportSource());
- Assert.assertTrue(match.getTransportDestination() == match2
- .getTransportDestination());
- Assert.assertTrue(match.getWildcards() == match2.getWildcards());
- }
-
- @Test
- public void testPadding() {
- // testing that matchlen+pad keeps the 8byte alignment
- V6Match match = new V6Match();
-
- match.fromString("input_port=1");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("dl_dst=20:A0:11:10:00:99");
- match.fromString("dl_src=00:10:08:22:12:75");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("ip_src=2001:ddd:3e1:1234:0000:1111:2222:3333");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("ip_dst=2001:123:222:abc:111:aaa:1111:2222");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("dl_vlan=10");
- match.fromString("dl_vpcp=1");
- match.fromString("nw_proto=6");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("nw_tos=100");
- match.fromString("tp_dst=8080");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- match.fromString("tp_src=60");
- Assert.assertTrue((match.getPadSize() + match.getIPv6MatchLen()) % 8 == 0);
- }
-}
<maven>3.0</maven>
</prerequisites>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<artifactId>simple-client</artifactId>
<version>${openflowjava.version}</version>
</dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.thirdparty</groupId>
- <artifactId>org.openflow.openflowj</artifactId>
- <version>1.0.2-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-base</artifactId>
</releases>
</pluginRepository>
</pluginRepositories>
+ <modules>
+ <module>openflowplugin</module>
+ <module>distribution/base</module>
+ <module>openflowplugin-it</module>
+ <module>test-provider</module>
+ </modules>
</project>
\ No newline at end of file
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
- <relativePath>../../commons</relativePath>
+ <relativePath>../../</relativePath>
</parent>
<artifactId>sample-consumer</artifactId>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>openflowplugin-commons</artifactId>
+ <artifactId>openflowplugin-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
- <relativePath>../commons</relativePath>
+ <relativePath>../</relativePath>
</parent>
<artifactId>test-provider</artifactId>
<packaging>bundle</packaging>
+++ /dev/null
-openflowj_netty has been moved to the openflowjava project as
-of Aug 30, 2013:
-
-https://git.opendaylight.org/gerrit/#/c/1047/
-
-You can include it in your maven project with:
-
-<repositories>
- <!-- OpenDayLight Released artifact -->
- <repository>
- <id>opendaylight-release</id>
- <name>opendaylight-release</name>
- <url>${nexusproxy}/repositories/opendaylight.release/</url>
- </repository>
- <!-- OpenDayLight Snapshot artifact -->
- <repository>
- <id>opendaylight-snapshot</id>
- <name>opendaylight-snapshot</name>
- <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
- </repository>
-</repositories>
-
-<dependency>
- <groupId>org.opendaylight.openflowjava.thirdparty</groupId>
- <artifactId>org.openflow.openflowj_netty</artifactId>
- <version>1.0.2-SNAPSHOT</version>
-</dependency>