for (FlowEntry flowEntry : inactiveFlows) {
Status status = this.removeEntry(flowEntry);
if (!status.isSuccess()) {
- log.warn("Failed to remove entry: {}. The failure is: {}"
- + flowEntry, status.getDescription());
+ log.warn("Failed to remove entry: {}. The failure is: {}",
+ flowEntry, status.getDescription());
}
}
}
for (FlowEntry flowEntry : this.inactiveFlows) {
Status status = this.addEntry(flowEntry);
if (!status.isSuccess()) {
- log.warn("Failed to install entry: {}. The failure is: {}"
- + flowEntry, status.getDescription());
+ log.warn("Failed to install entry: {}. The failure is: {}",
+ flowEntry, status.getDescription());
}
}
@Override
public void portGroupChanged(PortGroupConfig config,
Map<Node, PortGroup> data, boolean add) {
- log.info("PortGroup Changed for :" + config + " Data: " + portGroupData);
+ log.info("PortGroup Changed for: {} Data: {}", config, portGroupData);
Map<Node, PortGroup> existingData = portGroupData.get(config);
if (existingData != null) {
for (Map.Entry<Node, PortGroup> entry : data.entrySet()) {
this.updateLocalDatabase(installedEntry, false);
}
+ @Override
+ public void flowErrorReported(Node node, long rid, Object err) {
+ log.error("Got error {} for message rid {} from node {}", new Object[] {
+ err, rid, node });
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
private AtomicInteger switchInstanceNumber;
/*
- * this thread monitors the switchEvents queue for new incoming events from switch
+ * this thread monitors the switchEvents queue for new incoming events from
+ * switch
*/
private class EventHandler implements Runnable {
@Override
SwitchEvent ev = switchEvents.take();
SwitchEvent.SwitchEventType eType = ev.getEventType();
ISwitch sw = ev.getSwitch();
- if (eType != SwitchEvent.SwitchEventType.SWITCH_MESSAGE) {
- //logger.debug("Received " + ev.toString() + " from " + sw.toString());
- }
switch (eType) {
case SWITCH_ADD:
Long sid = sw.getId();
ISwitch existingSwitch = switches.get(sid);
if (existingSwitch != null) {
- logger.info(" Replacing existing "
- + existingSwitch.toString() + " with New "
- + sw.toString());
+ logger.info("Replacing existing {} with New {}",
+ existingSwitch.toString(), sw.toString());
disconnectSwitch(existingSwitch);
}
switches.put(sid, sw);
}
break;
default:
- logger.error("unknow switch event " + eType.ordinal());
+ logger.error("Unknown switch event {}", eType.ordinal());
}
} catch (InterruptedException e) {
switchEvents.clear();
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
public void init() {
- logger.debug("OpenFlowCore init");
+ logger.debug("Initializing!");
this.switches = new ConcurrentHashMap<Long, ISwitch>();
this.switchEvents = new LinkedBlockingQueue<SwitchEvent>();
this.messageListeners = new ConcurrentHashMap<OFType, IMessageListener>();
}
/**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
- *
+ * 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("OpenFlowCore start() is called");
+ logger.debug("Starting!");
/*
* start a thread to handle event coming from the switch
*/
try {
controllerIO.start();
} catch (IOException ex) {
- logger.error("Caught exception: " + ex + " during start");
+ 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
- *
+ * 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
}
switchEventThread.interrupt();
try {
- controllerIO.shutDown();
+ controllerIO.shutDown();
} catch (IOException ex) {
- logger.error("Caught exception: " + ex + " during stop");
+ 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.
- *
+ * 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() {
}
public void addMessageListener(OFType type, IMessageListener listener) {
IMessageListener currentListener = this.messageListeners.get(type);
if (currentListener != null) {
- logger.warn(type.toString() + " already listened by "
- + currentListener.toString());
+ logger.warn("{} is already listened by {}", type.toString(),
+ currentListener.toString());
}
this.messageListeners.put(type, listener);
- logger.debug(type.toString() + " is now listened by "
- + listener.toString());
+ 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(this.switchStateListener.toString()
- + "already listened to switch events");
+ logger.warn("Switch events are already listened by {}",
+ this.switchStateListener.toString());
}
this.switchStateListener = listener;
- logger.debug(listener.toString() + " now listens to switch events");
+ 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;
}
}
SwitchHandler switchHandler = new SwitchHandler(this, sc,
instanceName);
switchHandler.start();
- logger.info(instanceName + " connected: " + sc.toString());
+ if (sc.isConnected()) {
+ logger.info("Switch:{} is connected to the Controller", sc
+ .getRemoteAddress().toString().split("/")[1]);
+ }
+
} catch (IOException e) {
return;
}
if (((SwitchHandler) sw).isOperational()) {
Long sid = sw.getId();
if (this.switches.remove(sid, sw)) {
- logger.warn(sw.toString() + " is disconnected");
+ logger.warn("{} is Disconnected", sw.toString());
notifySwitchDeleted(sw);
- } else {
- //logger.warn(sw.toString() + " has been replaced by " +
- // this.switches.get(sid));
}
}
((SwitchHandler) sw).stop();
}
}
- public void takeSwtichEventAdd(ISwitch sw) {
+ public void takeSwitchEventAdd(ISwitch sw) {
SwitchEvent ev = new SwitchEvent(
SwitchEvent.SwitchEventType.SWITCH_ADD, sw, null);
addSwitchEvent(ev);
while (iter.hasNext()) {
Long sid = iter.next();
Date date = switches.get(sid).getConnectedDate();
- String switchInstanceName = ((SwitchHandler) switches.get(sid)).getInstanceName();
+ String switchInstanceName = ((SwitchHandler) switches.get(sid))
+ .getInstanceName();
s.append(switchInstanceName + "/" + HexString.toHexString(sid)
+ " connected since " + date.toString() + "\n");
}
@Override
public String getHelp() {
StringBuffer help = new StringBuffer();
- help.append("-- Open Flow Controller --\n");
+ help.append("---Open Flow Controller---\n");
help.append("\t controllerShowSwitches\n");
help.append("\t controllerReset\n");
help.append("\t controllerShowConnConfig\n");
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
try {
openFlowPort = Short.decode(portString).shortValue();
} catch (NumberFormatException e) {
- logger.warn("Invalid port:" + portString + ", use default("
- + openFlowPort + ")");
+ logger.warn("Invalid port:{}, use default({})", portString,
+ openFlowPort);
}
}
}
SelectionKey skey = selectedKeys.next();
selectedKeys.remove();
if (skey.isValid() && skey.isAcceptable()) {
- ((Controller) listener).handleNewConnection(selector,
- serverSelectionKey);
+ ((Controller) listener).handleNewConnection(
+ selector, serverSelectionKey);
}
}
} catch (Exception e) {
}
}, "ControllerI/O Thread");
controllerIOThread.start();
- logger.info("Controller is now listening on port " + openFlowPort);
+ logger.info("Controller is now listening on port {}", openFlowPort);
}
public void shutDown() throws IOException {
}
for (OFMessage msg : msgs) {
logger.trace("Message received: {}", msg.toString());
- /*
- * if ((msg.getType() != OFType.ECHO_REQUEST) && (msg.getType() !=
- * OFType.ECHO_REPLY)) { logger.debug(msg.getType().toString() +
- * " received from sw " + toString()); }
- */
this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
OFType type = msg.getType();
switch (type) {
}
private void processPortStatusMsg(OFPortStatus msg) {
- // short portNumber = msg.getDesc().getPortNumber();
OFPhysicalPort port = msg.getDesc();
if (msg.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
updatePhysicalPort(port);
- // logger.debug("Port " + portNumber + " on " + toString() +
- // " modified");
} else if (msg.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
updatePhysicalPort(port);
- // logger.debug("Port " + portNumber + " on " + toString() +
- // " added");
} else if (msg.getReason() == (byte) OFPortReason.OFPPR_DELETE
.ordinal()) {
deletePhysicalPort(port);
- // logger.debug("Port " + portNumber + " on " + toString() +
- // " deleted");
}
}
reportSwitchStateChange(false);
} else {
// send a probe to see if the switch is still alive
- // logger.debug("Send idle probe (Echo Request) to "
- // + switchName());
+ logger.debug(
+ "Send idle probe (Echo Request) to {}",
+ toString());
probeSent = true;
OFMessage echo = factory
.getMessage(OFType.ECHO_REQUEST);
private void reportError(Exception e) {
if (e instanceof AsynchronousCloseException
|| e instanceof InterruptedException
- || e instanceof SocketException
- || e instanceof IOException) {
+ || e instanceof SocketException || e instanceof IOException) {
logger.debug("Caught exception {}", e.getMessage());
} else {
logger.warn("Caught exception ", e);
private void reportSwitchStateChange(boolean added) {
if (added) {
- ((Controller) core).takeSwtichEventAdd(this);
+ ((Controller) core).takeSwitchEventAdd(this);
} else {
((Controller) core).takeSwitchEventDelete(this);
}
.getValue()
| OFPortFeatures.OFPPF_1GB_HD
.getValue() | OFPortFeatures.OFPPF_10GB_FD
- .getValue()));
+ .getValue()));
}
private void deletePhysicalPort(OFPhysicalPort port) {
@Override
public String toString() {
- return ("["
- + this.socket.toString()
- + " SWID "
- + (isOperational() ? HexString.toHexString(this.sid)
- : "unkbown") + "]");
+ try {
+ return ("Switch:"
+ + socket.getRemoteAddress().toString().split("/")[1]
+ + " SWID:" + (isOperational() ? HexString
+ .toHexString(this.sid) : "unknown"));
+ } catch (Exception e) {
+ return (isOperational() ? HexString.toHexString(this.sid)
+ : "unknown");
+ }
+
}
@Override
}
/**
- * Sends synchronous Barrier message
+ * Sends synchronous Barrier message
*/
@Override
public Object sendBarrierMessage() {
OFBarrierRequest barrierMsg = new OFBarrierRequest();
- return syncSend(barrierMsg);
+ return syncSend(barrierMsg);
}
-
+
/**
* This method returns the switch liveness timeout value. If controller did
* not receive any message from the switch for such a long period,
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
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.opendaylight.controller.sal.reader.NodeDescription;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Utility class for converting openflow description statistics
- * into SAL NodeDescription object
- *
- *
- *
+ * 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;
hwDesc.setDescription(ofDesc.getDatapathDescription());
hwDesc.setSerialNumber(ofDesc.getSerialNumber());
}
+ log.trace("OFDescriptionStatistics: {}", ofDesc);
+ log.trace("NodeDescription: {}", hwDesc);
return hwDesc;
}
try {
ethPkt.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
} catch (Exception e) {
- logger.warn("Failed to decode LLDP packet from "
- + inPkt.getIncomingNodeConnector() + ": " + e);
+ logger.warn("Failed to decode LLDP packet from {}: {}",
+ inPkt.getIncomingNodeConnector(), e);
return PacketResult.IGNORED;
}
if (ethPkt.getPayload() instanceof LLDP) {
import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod;
import org.opendaylight.controller.protocol_plugin.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.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.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.ActionType;
import org.opendaylight.controller.sal.action.Controller;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.NetUtils;
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+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.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;
*/
public class FlowConverter {
protected static final Logger logger = LoggerFactory
- .getLogger(FlowConverter.class);
+ .getLogger(FlowConverter.class);
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
ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
}
}
-
+ logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
+ ofMatch);
return ofMatch;
}
}
}
}
+ logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
+ actionsList);
return actionsList;
}
}
}
}
+ logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
+ actionsList);
+ logger.trace("Openflow Mod Message: {}", fm);
return fm;
}
try {
ip = InetAddress.getByAddress(addr);
} catch (UnknownHostException e) {
- logger.error("",e);
+ logger.error("", e);
}
salAction = new SetNwSrc(ip);
} else if (ofAction instanceof OFActionNetworkLayerDestination) {
try {
ip = InetAddress.getByAddress(addr);
} catch (UnknownHostException e) {
- logger.error("",e);
+ logger.error("", e);
}
salAction = new SetNwDst(ip);
} else if (ofAction instanceof OFActionNetworkTypeOfService) {
// Create Flow
flow = new Flow(salMatch, salActionList);
}
+ logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
+ actionsList);
+ logger.trace("SAL Flow: {}", flow);
return flow;
}
}
}
+ @Override
+ public void flowErrorReported(Node node, long rid, Object err) {
+ if (salNotifier != null) {
+ salNotifier.flowErrorReported(node, rid, err);
+ } else {
+ logger.warn("Unable to relay switch error message to upper layer");
+ }
+ }
+
}
public FlowProgrammerService() {
controller = null;
flowProgrammerNotifiers = new ConcurrentHashMap<String, IFlowProgrammerNotifier>();
+ containerToNc = new HashMap<String, Set<NodeConnector>>();
xid2rid = new ConcurrentHashMap<Long, Map<Integer, Long>>();
}
*/
void init() {
this.controller.addMessageListener(OFType.FLOW_REMOVED, this);
+ this.controller.addMessageListener(OFType.ERROR, this);
registerWithOSGIConsole();
}
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 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) {
* The OF message xid
* @return The Request ID
*/
- public long getMessageRid(long swid, int xid) {
+ private Long getMessageRid(long swid, Integer xid) {
+ Long rid = null;
+
+ if (xid == null) {
+ return rid;
+ }
+
Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
- long rid = 0;
-
if (swxid2rid != null) {
rid = swxid2rid.get(xid);
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import java.util.List;
import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6StatsReply;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.reader.FlowOnNode;
+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
- *
- *
- *
+ * 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;
if (statsList == null) {// || statsList.isEmpty()) {
this.ofStatsList = new ArrayList<OFStatistics>(1); // dummy list
} else {
- this.ofStatsList = statsList; //new ArrayList<OFStatistics>(statsList);
+ this.ofStatsList = statsList; // new
+ // ArrayList<OFStatistics>(statsList);
}
this.flowOnNodeList = null;
}
flowOnNodeList.add(flowOnNode);
}
}
+ log.trace("OFStatistics: {} FlowOnNode: {}", ofStatsList,
+ flowOnNodeList);
return flowOnNodeList;
}
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
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
+ * 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 Timer statisticsTimer;
private TimerTask statisticsTimerTask;
private ConcurrentMap<Long, Boolean> switchSupportsVendorExtStats;
- private Map<Long, Map<Short, TxRates>> txRates; // Per port sampled (every portStatsPeriod) transmit rate
+ private Map<Long, Map<Short, TxRates>> txRates; // Per port sampled (every
+ // portStatsPeriod) transmit
+ // rate
private Set<IStatisticsListener> descriptionListeners;
/**
- * The object containing the latest factoredSamples tx rate samples
- * for a given switch port
+ * The object containing the latest factoredSamples tx rate samples for a
+ * given switch port
*/
protected class TxRates {
- Deque<Long> sampledTxBytes; // contains the latest factoredSamples sampled transmitted bytes
+ Deque<Long> sampledTxBytes; // contains the latest factoredSamples
+ // sampled transmitted bytes
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
+ * Based on how many samples our average works on, we might have to
+ * remove the oldest sample
*/
if (sampledTxBytes.size() == factoredSamples) {
sampledTxBytes.removeLast();
/**
* Returns the average transmit rate in bps
+ *
* @return the average transmit rate [bps]
*/
public long getAverageTxRate() {
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
void init() {
- flowStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
+ flowStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
descStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
dummyList = new ArrayList<OFStatistics>(1);
StatsRequest req = pendingStatsRequests.take();
acquireStatistics(req.switchId, req.type);
} catch (InterruptedException e) {
- log.warn("Flow Statistics Collector thread " +
- "interrupted");
+ log.warn("Flow Statistics Collector thread "
+ + "interrupted", e);
}
}
}
long switchId = switchPortStatsUpdated.take();
updatePortsTxRate(switchId);
} catch (InterruptedException e) {
- log.warn("TX Rate Updater thread interrupted");
+ log.warn("TX Rate Updater thread interrupted", e);
}
}
}
}
/**
- * 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.
- *
+ * 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
- *
+ * 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
}
/**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
- *
+ * 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
}
public void setStatisticsListener(IStatisticsListener s) {
- this.descriptionListeners.add(s);
+ this.descriptionListeners.add(s);
}
-
+
public void unsetStatisticsListener(IStatisticsListener s) {
- if (s != null) {
- this.descriptionListeners.remove(s);
- }
+ if (s != null) {
+ this.descriptionListeners.remove(s);
+ }
}
-
+
private void registerWithOSGIConsole() {
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
.getBundleContext();
}
private void addStatisticsTicks(Long switchId) {
- switchSupportsVendorExtStats.put(switchId, Boolean.TRUE); // Assume switch supports Vendor extension stats
+ switchSupportsVendorExtStats.put(switchId, Boolean.TRUE); // Assume
+ // switch
+ // supports
+ // Vendor
+ // extension
+ // stats
statisticsTimerTicks.put(switchId, new StatisticsTicks(true));
- log.info("Added Switch {} to target pool", HexString
- .toHexString(switchId.longValue()));
+ log.info("Added Switch {} to target pool",
+ HexString.toHexString(switchId.longValue()));
}
protected static class StatisticsTicks {
}
public boolean decrementFlowTicksIsZero() {
- // Please ensure no code is inserted between the if check and the flowStatisticsTicks reset
+ // Please ensure no code is inserted between the if check and the
+ // flowStatisticsTicks reset
if (--flowStatisticsTicks == 0) {
flowStatisticsTicks = statisticsTickNumber;
return true;
}
public boolean decrementDescTicksIsZero() {
- // Please ensure no code is inserted between the if check and the descriptionTicks reset
+ // Please ensure no code is inserted between the if check and the
+ // descriptionTicks reset
if (--descriptionTicks == 0) {
descriptionTicks = descriptionTickNumber;
return true;
}
public boolean decrementPortTicksIsZero() {
- // Please ensure no code is inserted between the if check and the descriptionTicks reset
+ // Please ensure no code is inserted between the if check and the
+ // descriptionTicks reset
if (--portStatisticsTicks == 0) {
portStatisticsTicks = portTickNumber;
return true;
}
private void printInfoMessage(String type, StatsRequest request) {
- log
- .info(
- type
- + " stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
- new Object[] { HexString.toHexString(request.switchId),
- pendingStatsRequests.size(),
- statisticsCollector.getState().toString() });
+ 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() {
Long switchId = entry.getKey();
if (clock.decrementFlowTicksIsZero() == true) {
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
+ 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() == true) {
request = new StatsRequest(switchId, OFStatisticsType.DESC);
- // If a request for this switch is already in the queue, skip to add this new request
+ // 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() == true) {
request = new StatsRequest(switchId, OFStatisticsType.PORT);
- // If a request for this switch is already in the queue, skip to add this new request
+ // 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);
}
private void removeStatsRequestTasks(Long switchId) {
- log.info("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
+ log.info("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,
statisticsTimerTicks.remove(switchId);
removeStatsRequestTasks(switchId);
flowStatistics.remove(switchId);
- log.info("Statistics removed for switch "
- + HexString.toHexString(switchId));
+ log.info("Statistics removed for switch {}",
+ HexString.toHexString(switchId));
}
private void acquireStatistics(Long switchId, OFStatisticsType statType) {
|| (statType == OFStatisticsType.VENDOR)) {
flowStatistics.put(switchId, values);
} else if (statType == OFStatisticsType.DESC) {
- // Notify who may be interested in a description change
- notifyDescriptionListeners(switchId, values);
-
+ // Notify who may be interested in a description change
+ notifyDescriptionListeners(switchId, values);
+
// Overwrite cache
descStatistics.put(switchId, values);
} else if (statType == OFStatisticsType.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
+ // Wake up the thread which maintains the TX byte counters for
+ // each port
switchPortStatsUpdated.offer(switchId);
}
}
}
private void notifyDescriptionListeners(Long switchId,
- List<OFStatistics> values) {
- for (IStatisticsListener l : this.descriptionListeners) {
- l.descriptionRefreshed(switchId,
- ((OFDescriptionStatistics)values.get(0)));
- }
+ List<OFStatistics> values) {
+ for (IStatisticsListener l : this.descriptionListeners) {
+ l.descriptionRefreshed(switchId,
+ ((OFDescriptionStatistics) values.get(0)));
+ }
}
-
+
/*
* Generic function to get the statistics form a OF switch
*/
match.setWildcards(0xffffffff);
} else if (!(target instanceof OFMatch)) {
// Malformed request
- log.warn("Invalid target type for Flow stats request: "
- + target.getClass());
+ log.warn("Invalid target type for Flow stats request: {}",
+ target.getClass());
return null;
} else {
// Specific flow request
targetPort = (short) OFPort.OFPP_NONE.getValue();
} else if (!(target instanceof Short)) {
// Malformed request
- log.warn("Invalid target type for Port stats request: "
- + target.getClass());
+ log.warn("Invalid target type for Port stats request: {}",
+ target.getClass());
return null;
} else {
// Specific port request
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: "
- + Utils.getOFErrorString((OFError) result), HexString
- .toHexString(switchId), type);
+ 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));
+ log.warn(
+ "Switching back to regular Flow stats requests for switch {}",
+ HexString.toHexString(switchId));
this.switchSupportsVendorExtStats.put(switchId,
Boolean.FALSE);
}
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)
+ * 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
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)
+ * 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
+ * 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);
ByteBuffer data = ByteBuffer.allocate(length);
stat.writeTo(data);
data.rewind();
- log.trace("getV6ReplyStatistics: Buffer BYTES ARE {}", HexString
- .toHexString(data.array()));
+ log.trace("getV6ReplyStatistics: Buffer BYTES ARE {}",
+ HexString.toHexString(data.array()));
- int vendor = data.getInt(); //first 4 bytes is vendor id.
+ int vendor = data.getInt(); // first 4 bytes is vendor id.
if (vendor != V6StatsRequest.NICIRA_VENDOR_ID) {
- log
- .debug("Unexpected vendor id: 0x{}", Integer
- .toHexString(vendor));
+ 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
+ // 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;
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
+ * 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) {
}
/*
- * InventoryShim replay for us all the switch addition which happened before we were brought up
+ * 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) {
}
/**
- * Update the cached port rates for this switch with the latest
- * retrieved port transmit byte count
+ * Update the cached port rates for this switch with the latest retrieved
+ * port transmit byte count
+ *
* @param switchId
*/
private synchronized void updatePortsTxRate(long switchId) {
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 ofdumpstatsmgr - "
+ + "Print Internal Stats Mgr db\n");
return help.toString();
}
public void _ofdumpstatsmgr(CommandInterpreter ci) {
ci.println("Global Counter: " + counter);
- ci
- .println("Timer Ticks: "
- + prettyPrintSwitchMap(statisticsTimerTicks));
+ ci.println("Timer Ticks: " + prettyPrintSwitchMap(statisticsTimerTicks));
ci.println("PendingStatsQueue: " + pendingStatsRequests);
ci.println("PendingStatsQueue size: " + pendingStatsRequests.size());
ci.println("Stats Collector alive: " + statisticsCollector.isAlive());
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");
+ ci.println("Insert the length in seconds of the median "
+ + "window for tx rate");
+ ci.println("Current: " + factoredSamples * portTickNumber + " secs");
return;
}
try {
} catch (NumberFormatException e) {
ci.println("Invalid period.");
}
- OFStatisticsManager.factoredSamples = (short) (seconds/portTickNumber);
+ OFStatisticsManager.factoredSamples = (short) (seconds / portTickNumber);
ci.println("New: " + factoredSamples * portTickNumber + " secs");
}
public void _ofstatsmgrintervals(CommandInterpreter ci) {
String flowStatsInterv = ci.nextArgument();
String portStatsInterv = ci.nextArgument();
-
+
if (flowStatsInterv == null || portStatsInterv == null) {
ci.println("Usage: ostatsmgrintervals <fP> <pP> (in seconds)");
- ci.println("Current Values: fP=" + statisticsTickNumber +
- "s pP=" + portTickNumber + "s");
+ ci.println("Current Values: fP=" + statisticsTickNumber + "s pP="
+ + portTickNumber + "s");
return;
}
Short fP, pP;
try {
- fP = Short.parseShort(flowStatsInterv);
- pP = Short.parseShort(portStatsInterv);
+ fP = Short.parseShort(flowStatsInterv);
+ pP = Short.parseShort(portStatsInterv);
} catch (Exception e) {
- ci.println("Invalid format values: " + e.getMessage());
- return;
+ ci.println("Invalid format values: " + e.getMessage());
+ return;
}
- if (pP <= 1 || fP <=1) {
- ci.println("Invalid values. fP and pP have to be greater than 1.");
- return;
+ if (pP <= 1 || fP <= 1) {
+ ci.println("Invalid values. fP and pP have to be greater than 1.");
+ return;
}
-
+
statisticsTickNumber = fP;
portTickNumber = pP;
-
- ci.println("New Values: fP=" + statisticsTickNumber +
- "s pP=" + portTickNumber + "s");
+
+ ci.println("New Values: fP=" + statisticsTickNumber + "s pP="
+ + portTickNumber + "s");
}
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
package org.opendaylight.controller.protocol_plugin.openflow.internal;
-import org.openflow.protocol.OFPort;
-
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
- *
- *
- *
+ * 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 int maxOFPhysicalPort =
- NetUtils.getUnsignedShort(OFPort.OFPP_MAX.getValue());
+ 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(
* 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)) {
+ } else if (salPort.getType().equals(NodeConnectorIDType.HWPATH)) {
return OFPort.OFPP_NORMAL.getValue();
- } else if (salPort.getType().equals(
- NodeConnectorIDType.CONTROLLER)) {
+ } else if (salPort.getType().equals(NodeConnectorIDType.CONTROLLER)) {
return OFPort.OFPP_CONTROLLER.getValue();
}
return (Short) salPort.getID();
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import java.util.ArrayList;
import java.util.List;
-import org.openflow.protocol.statistics.OFPortStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-
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;
.getReceiveFrameErrors());
NCStat.setReceiveOverRunErrorCount(ofPortStat
.getReceiveOverrunErrors());
- NCStat
- .setReceiveCRCErrorCount(ofPortStat
- .getReceiveCRCErrors());
+ NCStat.setReceiveCRCErrorCount(ofPortStat.getReceiveCRCErrors());
NCStat.setCollisionCount(ofPortStat.getCollisions());
this.ncStatsList.add(NCStat);
}
}
+ log.trace("OFStatistics: {} NodeConnectorStatistics: {}", ofStatsList,
+ ncStatsList);
return this.ncStatsList;
}
* and flow parameters fields. Actions may not be present.
*/
public void flowRemoved(Node node, Flow flow);
+
+ /**
+ * Inform SAL that an error message has been received from a switch
+ * regarding a flow message previously sent to the switch. A Request ID
+ * associated with the offending message is also returned.
+ *
+ * @param node
+ * the network node on which the error reported
+ * @param rid
+ * the offending message request id
+ * @param err
+ * the error message
+ */
+ public void flowErrorReported(Node node, long rid, Object err);
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* - convert bits to primitive data type - like short, int, long
* - store bits in specified location in stream of bits
* - convert primitive data types to stream of bits
- *
- *
*/
public abstract class BitBufferHelper {
protected static final Logger logger = LoggerFactory
.getLogger(BitBufferHelper.class);
- public static long ByteMask = 0xFF;
+ public static final long ByteMask = 0xFF;
// Getters
// data: array where data are stored
public static byte getByte(byte[] data) {
if ((data.length * NetUtils.NumBitsInAByte) > Byte.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
return (data[0]);
public static short getShort(byte[] data) {
if (data.length > Short.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
return (short) toNumber(data);
public static int getInt(byte[] data) {
if (data.length > Integer.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
return (int) toNumber(data);
public static long getLong(byte[] data) {
if (data.length > Long.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
} catch (Exception e) {
- logger.error("",e);
+ logger.error("", e);
}
}
return (long) toNumber(data);
* @param byte[] data
* @param int - numBits
* @return short - the short value of byte array
- * @throws Exception
*/
- public static short getShort(byte[] data, int numBits) throws Exception {
+ public static short getShort(byte[] data, int numBits) {
if (numBits > Short.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- return (short) toNumber(BitBufferHelper.getBits(data, startOffset,
- numBits), numBits);
+ byte[] bits = null;
+ try {
+ bits = BitBufferHelper.getBits(data, startOffset, numBits);
+ } catch (BufferException e) {
+ logger.error("", e);
+ }
+ return (short) toNumber(bits, numBits);
}
/**
* @param byte[] data
* @param int - numBits
* @return int - the integer value of byte array
- * @throws Exception
*/
- public static int getInt(byte[] data, int numBits) throws Exception {
+ public static int getInt(byte[] data, int numBits) {
if (numBits > Integer.SIZE) {
try {
- throw new Exception(
- "Container is too small for the number of requiested bits");
- } catch (Exception e) {
- logger.error("",e);
+ throw new BufferException(
+ "Container is too small for the number of requested bits");
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- return (int) toNumber(BitBufferHelper.getBits(data, startOffset,
- numBits), numBits);
+ byte[] bits = null;
+ try {
+ bits = BitBufferHelper.getBits(data, startOffset, numBits);
+ } catch (BufferException e) {
+ logger.error("", e);
+ }
+ return (int) toNumber(bits, numBits);
}
/**
* @param byte[] data
* @param int - numBits
* @return long - the integer value of byte array
- * @throws Exception
*/
-
- public static long getLong(byte[] data, int numBits) throws Exception {
+ public static long getLong(byte[] data, int numBits) {
if (numBits > Long.SIZE) {
try {
- throw new Exception(
+ throw new BufferException(
"Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
if (numBits > data.length * NetUtils.NumBitsInAByte) {
try {
- throw new Exception(
+ throw new BufferException(
"Trying to read more bits than contained in the data buffer");
- } catch (Exception e) {
- logger.error("",e);
+ } catch (BufferException e) {
+ logger.error("", e);
}
}
int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- return toNumber(BitBufferHelper.getBits(data, startOffset, numBits),
- numBits);
+ byte[] bits = null;
+ try {
+ bits = BitBufferHelper.getBits(data, startOffset, numBits);
+ } catch (BufferException e) {
+ logger.error("", e);
+ }
+ return (long) toNumber(bits, numBits);
}
/**
* @param int startOffset - offset to start fetching bits from data from
* @param int numBits - number of bits to be fetched from data
* @return byte [] - LSB aligned bits
- * @throws Exception
+ *
+ * @throws BufferException
+ * when the startOffset and numBits parameters are not congruent
+ * with the data buffer size
*/
public static byte[] getBits(byte[] data, int startOffset, int numBits)
- throws Exception {
+ throws BufferException {
int startByteOffset = 0;
int valfromcurr, valfromnext;
byte[] shiftedBytes = new byte[numBytes];
startByteOffset = startOffset / NetUtils.NumBitsInAByte;
byte[] bytes = new byte[numBytes];
- if (numBits == 0)
+ if (numBits == 0) {
return bytes;
+ }
checkExceptions(data, startOffset, numBits);
} else {
int i;
for (i = 0; i < numBits / NetUtils.NumBitsInAByte; i++) {
- // Reading Numbytes starting from offset
+ // Reading numBytes starting from offset
valfromcurr = (data[startByteOffset + i])
& getLSBMask(NetUtils.NumBitsInAByte - extraOffsetBits);
valfromnext = (data[startByteOffset + i + 1])
* @param byte - input byte to be inserted
* @param startOffset - offset of data[] to start inserting byte from
* @param numBits - number of bits of input to be inserted into data[]
- * @return void
- * @throws Exception
+ *
+ * @throws BufferException
+ * when the input, startOffset and numBits are not congruent
+ * with the data buffer size
*/
public static void setByte(byte[] data, byte input, int startOffset,
- int numBits) throws Exception {
+ int numBits) throws BufferException {
byte[] inputByteArray = new byte[1];
Arrays.fill(inputByteArray, 0, 1, input);
setBytes(data, inputByteArray, startOffset, numBits);
* @param startOffset - offset of data[] to start inserting byte from
* @param numBits - number of bits of input to be inserted into data[]
* @return void
- * @throws Exception
+ * @throws BufferException
+ * when the startOffset and numBits parameters are not congruent
+ * with data and input buffers' size
*/
public static void setBytes(byte[] data, byte[] input, int startOffset,
- int numBits) throws Exception {
+ int numBits) throws BufferException {
checkExceptions(data, startOffset, numBits);
insertBits(data, input, startOffset, numBits);
}
/**
* Returns numBits 1's in the MSB position
+ *
* @param numBits
* @return
*/
/**
* Returns numBits 1's in the LSB position
+ *
* @param numBits
* @return
*/
/**
* Returns the numerical value of the byte array passed
+ *
* @param byte[] - array
* @return long - numerical value of byte array passed
*/
}
/**
- * Returns the numerical value of the last numBits (LSB bits)
- * of the byte array passed
+ * Returns the numerical value of the last numBits (LSB bits) of the byte
+ * array passed
+ *
* @param byte[] - array
* @param int - numBits
* @return long - numerical value of byte array passed
}
/**
- * Accepts a number as input and returns its value in byte form
- * in LSB aligned form
- * example: input = 5000 [1001110001000]
- * bytes = 19, -120 [00010011] [10001000]
+ * Accepts a number as input and returns its value in byte form in LSB
+ * aligned form example: input = 5000 [1001110001000] bytes = 19, -120
+ * [00010011] [10001000]
+ *
* @param Number
* @return byte[]
- *
+ *
*/
public static byte[] toByteArray(Number input) {
Class<? extends Number> dataType = input.getClass();
short size = 0;
- long Lvalue = input.longValue();
+ long longValue = input.longValue();
- if (dataType == Byte.class || dataType == byte.class)
+ if (dataType == Byte.class || dataType == byte.class) {
size = Byte.SIZE;
- else if (dataType == Short.class || dataType == short.class)
+ } else if (dataType == Short.class || dataType == short.class) {
size = Short.SIZE;
- else if (dataType == Integer.class || dataType == int.class)
+ } else if (dataType == Integer.class || dataType == int.class) {
size = Integer.SIZE;
- else if (dataType == Long.class || dataType == long.class)
+ } else if (dataType == Long.class || dataType == long.class) {
size = Long.SIZE;
- else
+ } else {
throw new IllegalArgumentException(
"Parameter must one of the following: Short/Int/Long\n");
+ }
int length = size / NetUtils.NumBitsInAByte;
byte bytes[] = new byte[length];
- /*Getting the bytes from input value*/
+ // Getting the bytes from input value
for (int i = 0; i < length; i++) {
- bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length
+ bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length
- i - 1))) & ByteMask);
}
return bytes;
}
/**
- * Accepts a number as input and returns its value in byte form
- * in MSB aligned form
- * example: input = 5000 [1001110001000]
- * bytes = -114, 64 [10011100] [01000000]
- * @param Number input
+ * Accepts a number as input and returns its value in byte form in MSB
+ * aligned form example: input = 5000 [1001110001000] bytes = -114, 64
+ * [10011100] [01000000]
+ *
+ * @param Number
+ * input
* @param int numBits - the number of bits to be returned
* @return byte[]
- *
+ *
*/
public static byte[] toByteArray(Number input, int numBits) {
Class<? extends Number> dataType = input.getClass();
short size = 0;
- long Lvalue = input.longValue();
+ long longValue = input.longValue();
if (dataType == Short.class) {
size = Short.SIZE;
byte[] inputbytes = new byte[length];
byte shiftedBytes[];
- //Getting the bytes from input value
+ // Getting the bytes from input value
for (int i = 0; i < length; i++) {
- bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length
+ bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length
- i - 1))) & ByteMask);
}
}
/**
- * Takes an LSB aligned byte array and returned the LSB numBits in a MSB aligned byte array
- *
+ * Takes an LSB aligned byte array and returned the LSB numBits in a MSB
+ * aligned byte array
+ *
* @param inputbytes
* @param numBits
* @return
*/
/**
- * It aligns the last numBits bits to the head of the byte array
- * following them with numBits % 8 zero bits.
- *
- * Example:
- * For inputbytes = [00000111][01110001] and numBits = 12 it returns:
- * shiftedBytes = [01110111][00010000]
- *
+ * It aligns the last numBits bits to the head of the byte array following
+ * them with numBits % 8 zero bits.
+ *
+ * Example: For inputbytes = [00000111][01110001] and numBits = 12 it
+ * returns: shiftedBytes = [01110111][00010000]
+ *
* @param byte[] inputBytes
* @param int numBits - number of bits to be left aligned
* @return byte[]
}
}
- if (numBits % NetUtils.NumBitsInAByte == 0)
+ if (numBits % NetUtils.NumBitsInAByte == 0) {
numBitstoShiftBy = 0;
- else
+ } else {
numBitstoShiftBy = ((NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte)) < leadZeroesMSB) ? (NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte))
: leadZeroesMSB;
-
- if (numBitstoShiftBy == 0)
+ }
+ if (numBitstoShiftBy == 0) {
return inputBytes;
+ }
- if (numBits < NetUtils.NumBitsInAByte) { //inputbytes.length = 1 OR Read less than a byte
+ if (numBits < NetUtils.NumBitsInAByte) {
+ // inputbytes.length = 1 OR read less than a byte
shiftedBytes[0] = (byte) ((inputBytes[0] & getLSBMask(numBits)) << numBitstoShiftBy);
} else {
+ // # of bits to read from last byte
numEndRestBits = NetUtils.NumBitsInAByte
- - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy); //# of bits to read from last byte
+ - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy);
+
for (i = 0; i < (size - 1); i++) {
if ((i + 1) == (size - 1)) {
if (numEndRestBits > numBitstoShiftBy) {
/**
* It aligns the first numBits bits to the right end of the byte array
* preceding them with numBits % 8 zero bits.
- *
- * Example:
- * For inputbytes = [01110111][00010000] and numBits = 12 it returns:
- * shiftedBytes = [00000111][01110001]
- *
+ *
+ * Example: For inputbytes = [01110111][00010000] and numBits = 12 it
+ * returns: shiftedBytes = [00000111][01110001]
+ *
* @param byte[] inputBytes
* @param int numBits - number of bits to be right aligned
* @return byte[]
byte[] shiftedBytes = new byte[numBytes];
int inputLsb = 0, inputMsb = 0;
- if (numBitstoShift == 0)
+ if (numBitstoShift == 0) {
return inputBytes;
+ }
for (int i = 1; i < numBytes; i++) {
inputLsb = inputBytes[i - 1]
/**
* Insert in the data buffer at position dictated by the offset the number
- * of bits specified from the input data byte array.
- * The input byte array has the bits stored starting from the LSB
- *
+ * of bits specified from the input data byte array. The input byte array
+ * has the bits stored starting from the LSB
+ *
* @param byte[] data
* @param byte[] inputdata
* @param int startOffset
* @param int numBits
- * @return void
*/
public static void insertBits(byte[] data, byte[] inputdataLSB,
int startOffset, int numBits) {
- byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to MSB the passed byte array
+ byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to
+ // MSB the
+ // passed byte
+ // array
int numBytes = numBits / NetUtils.NumBitsInAByte;
int startByteOffset = startOffset / NetUtils.NumBitsInAByte;
int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte;
int InputMSBbits = 0, InputLSBbits = 0;
int i;
- if (numBits == 0)
- return;
+ if (numBits == 0) {
+ return;
+ }
if (extraOffsetBits == 0) {
if (extranumBits == 0) {
* @param data
* @param startOffset
* @param numBits
- * @throws Exception
+ * @throws PacketException when the startOffset and numBits parameters
+ * are not congruent with the data buffer's size
*/
public static void checkExceptions(byte[] data, int startOffset, int numBits)
- throws Exception {
+ throws BufferException {
int endOffsetByte;
int startByteOffset;
endOffsetByte = startOffset
startByteOffset = startOffset / NetUtils.NumBitsInAByte;
if (data == null) {
- throw new Exception("data[] is null\n");
+ throw new BufferException("data[] is null\n");
}
if ((startOffset < 0) || (startByteOffset >= data.length)
|| (endOffsetByte > data.length) || (numBits < 0)
|| (numBits > NetUtils.NumBitsInAByte * data.length)) {
- throw new Exception(
+ throw new BufferException(
"Illegal arguement/out of bound exception - data.length = "
+ data.length + " startOffset = " + startOffset
+ " numBits " + numBits);
--- /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.sal.packet;
+
+/**
+ * Describes an exception that is raised during BitBufferHelper operations.
+ */
+public class BufferException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public BufferException(String message) {
+ super(message);
+ }
+}
// TODO: This has to be outside and it should be possible for osgi
// to add new coming packet classes
- public static Map<Short, Class<? extends Packet>> etherTypeClassMap;
+ public static final Map<Short, Class<? extends Packet>> etherTypeClassMap;
static {
etherTypeClassMap = new HashMap<Short, Class<? extends Packet>>();
etherTypeClassMap.put(EtherTypes.ARP.shortValue(), ARP.class);
private static final String DIP = "DestinationIPAddress";
private static final String OPTIONS = "Options";
- public static Map<Byte, Class<? extends Packet>> protocolClassMap;
+ public static final Map<Byte, Class<? extends Packet>> protocolClassMap;
static {
protocolClassMap = new HashMap<Byte, Class<? extends Packet>>();
protocolClassMap.put(IPProtocols.ICMP.byteValue(), ICMP.class);
* Method to perform post serialization - like computation of checksum of serialized header
* @param serializedBytes
* @return void
- * @Exception throws exception
+ * @Exception throws PacketException
*/
protected void postSerializeCustomOperation(byte[] serializedBytes)
- throws Exception {
+ throws PacketException {
int startOffset = this.getfieldOffset(CHECKSUM);
int numBits = this.getfieldnumBits(CHECKSUM);
byte[] checkSum = BitBufferHelper.toByteArray(computeChecksum(
serializedBytes, serializedBytes.length));
- BitBufferHelper.setBytes(serializedBytes, checkSum, startOffset,
- numBits);
- return;
+ try {
+ BitBufferHelper.setBytes(serializedBytes, checkSum, startOffset,
+ numBits);
+ } catch (BufferException e) {
+ throw new PacketException(e.getMessage());
+ }
}
@Override
int payloadLength = 0;
try {
payloadLength = payload.serialize().length;
- } catch (Exception e) {
- logger.error("",e);
+ } catch (PacketException e) {
+ logger.error("", e);
}
this.setTotalLength((short) (this.getHeaderLen() + payloadLength));
}
int endByteOffset = endBitOffset / NetUtils.NumBitsInAByte;
int computedChecksum = computeChecksum(data, endByteOffset);
int actualChecksum = BitBufferHelper.getInt(fieldValues.get(CHECKSUM));
- if (computedChecksum != actualChecksum)
+ if (computedChecksum != actualChecksum) {
corrupted = true;
+ }
}
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
*/
public class LLDP extends Packet {
- private static final String CHASSISID = "ChassisId";
- private static final String PORTID = "PortId";
- private static final String TTL = "TTL";
- private static final int LLDPDefaultTlvs = 3;
- private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short)0).setType((byte)0);
- public static final byte[] LLDPMulticastMac = {1,(byte)0x80,(byte)0xc2, 0, 0,(byte)0xe};
- private Map<Byte, LLDPTLV> tlvList;
-
- /**
- * Default constructor that creates the tlvList LinkedHashMap
- */
- public LLDP() {
- super();
- tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs);
- }
-
- /**
- * Constructor that creates the tlvList LinkedHashMap and sets
- * the write access for the same
- */
- public LLDP (boolean writeAccess) {
- super(writeAccess);
- tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs); // Mandatory TLVs
- }
-
- /**
- * @param String - description of the type of TLV
- * @return byte - type of TLV
- */
- private byte getType(String typeDesc) {
- if (typeDesc.equals(CHASSISID)) {
- return LLDPTLV.TLVType.ChassisID.getValue();
- } else if (typeDesc.equals(PORTID)) {
- return LLDPTLV.TLVType.PortID.getValue();
- } else if (typeDesc.equals(TTL)) {
- return LLDPTLV.TLVType.TTL.getValue();
- } else {
- return LLDPTLV.TLVType.Unknown.getValue();
- }
- }
-
- /**
- * @param String - description of the type of TLV
- * @return LLDPTLV - full TLV
- */
+ private static final String CHASSISID = "ChassisId";
+ private static final String PORTID = "PortId";
+ private static final String TTL = "TTL";
+ private static final int LLDPDefaultTlvs = 3;
+ private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0)
+ .setType((byte) 0);
+ public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
+ (byte) 0xc2, 0, 0, (byte) 0xe };
+ private Map<Byte, LLDPTLV> tlvList;
+
+ /**
+ * Default constructor that creates the tlvList LinkedHashMap
+ */
+ public LLDP() {
+ super();
+ tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
+ }
+
+ /**
+ * Constructor that creates the tlvList LinkedHashMap and sets the write
+ * access for the same
+ */
+ public LLDP(boolean writeAccess) {
+ super(writeAccess);
+ tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
+ // TLVs
+ }
+
+ /**
+ * @param String
+ * - description of the type of TLV
+ * @return byte - type of TLV
+ */
+ private byte getType(String typeDesc) {
+ if (typeDesc.equals(CHASSISID)) {
+ return LLDPTLV.TLVType.ChassisID.getValue();
+ } else if (typeDesc.equals(PORTID)) {
+ return LLDPTLV.TLVType.PortID.getValue();
+ } else if (typeDesc.equals(TTL)) {
+ return LLDPTLV.TLVType.TTL.getValue();
+ } else {
+ return LLDPTLV.TLVType.Unknown.getValue();
+ }
+ }
+
+ /**
+ * @param String
+ * - description of the type of TLV
+ * @return LLDPTLV - full TLV
+ */
public LLDPTLV getTLV(String type) {
- return tlvList.get(getType(type));
+ return tlvList.get(getType(type));
}
- /**
- * @param String - description of the type of TLV
- * @param LLDPTLV - tlv to set
- * @return void
- */
+ /**
+ * @param String
+ * - description of the type of TLV
+ * @param LLDPTLV
+ * - tlv to set
+ * @return void
+ */
public void setTLV(String type, LLDPTLV tlv) {
- tlvList.put(getType(type), tlv);
+ tlvList.put(getType(type), tlv);
}
/**
* @return the chassisId TLV
*/
public LLDPTLV getChassisId() {
- return getTLV(CHASSISID);
+ return getTLV(CHASSISID);
}
/**
- * @param LLDPTLV - the chassisId to set
+ * @param LLDPTLV
+ * - the chassisId to set
*/
public LLDP setChassisId(LLDPTLV chassisId) {
- tlvList.put(getType(CHASSISID), chassisId);
+ tlvList.put(getType(CHASSISID), chassisId);
return this;
}
-
+
/**
* @return LLDPTLV - the portId TLV
*/
public LLDPTLV getPortId() {
- return tlvList.get(getType(PORTID));
+ return tlvList.get(getType(PORTID));
}
/**
- * @param LLDPTLV - the portId to set
+ * @param LLDPTLV
+ * - the portId to set
* @return LLDP
*/
public LLDP setPortId(LLDPTLV portId) {
- tlvList.put(getType(PORTID), portId);
+ tlvList.put(getType(PORTID), portId);
return this;
}
* @return LLDPTLV - the ttl TLV
*/
public LLDPTLV getTtl() {
- return tlvList.get(getType(TTL));
+ return tlvList.get(getType(TTL));
}
/**
- * @param LLDPTLV - the ttl to set
+ * @param LLDPTLV
+ * - the ttl to set
* @return LLDP
*/
public LLDP setTtl(LLDPTLV ttl) {
- tlvList.put(getType(TTL), ttl);
+ tlvList.put(getType(TTL), ttl);
return this;
}
* @return the optionalTLVList
*/
public List<LLDPTLV> getOptionalTLVList() {
- List<LLDPTLV> list = new ArrayList<LLDPTLV>();
- for (Map.Entry<Byte,LLDPTLV> entry : tlvList.entrySet()) {
- byte type = entry.getKey();
- if ((type == LLDPTLV.TLVType.ChassisID.getValue()) ||
- (type == LLDPTLV.TLVType.PortID.getValue()) ||
- (type == LLDPTLV.TLVType.TTL.getValue())) {
- continue;
- } else {
- list.add(entry.getValue());
- }
- }
+ List<LLDPTLV> list = new ArrayList<LLDPTLV>();
+ for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
+ byte type = entry.getKey();
+ if ((type == LLDPTLV.TLVType.ChassisID.getValue())
+ || (type == LLDPTLV.TLVType.PortID.getValue())
+ || (type == LLDPTLV.TLVType.TTL.getValue())) {
+ continue;
+ } else {
+ list.add(entry.getValue());
+ }
+ }
return list;
}
/**
- * @param optionalTLVList the optionalTLVList to set
+ * @param optionalTLVList
+ * the optionalTLVList to set
* @return LLDP
*/
- public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList)
- {
- for (LLDPTLV tlv : optionalTLVList) {
- tlvList.put(tlv.getType(), tlv);
- }
+ public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
+ for (LLDPTLV tlv : optionalTLVList) {
+ tlvList.put(tlv.getType(), tlv);
+ }
return this;
}
@Override
- public Packet deserialize (byte[] data, int bitOffset, int size) throws Exception {
- int lldpOffset = bitOffset; // LLDP start
- int lldpSize = size; // LLDP size
-
- /*
- * Deserialize the TLVs until we reach the end of the packet
- */
-
- while (lldpSize > 0) {
- LLDPTLV tlv = new LLDPTLV();
- tlv.deserialize(data, lldpOffset, lldpSize);
- lldpOffset += tlv.getTLVSize(); //Size of current TLV in bits
- lldpSize -= tlv.getTLVSize();
- this.tlvList.put(tlv.getType(), tlv);
- }
- return this;
- }
-
+ public Packet deserialize(byte[] data, int bitOffset, int size)
+ throws PacketException {
+ int lldpOffset = bitOffset; // LLDP start
+ int lldpSize = size; // LLDP size
+
+ /*
+ * Deserialize the TLVs until we reach the end of the packet
+ */
+ while (lldpSize > 0) {
+ LLDPTLV tlv = new LLDPTLV();
+ tlv.deserialize(data, lldpOffset, lldpSize);
+ int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
+ lldpOffset += tlvSize;
+ lldpSize -= tlvSize;
+ this.tlvList.put(tlv.getType(), tlv);
+ }
+ return this;
+ }
+
@Override
- public byte[] serialize() throws Exception {
- int startOffset = 0;
- byte[] serializedBytes = new byte[getLLDPPacketLength()];
-
- for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
- LLDPTLV tlv = entry.getValue();
- int numBits = tlv.getTLVSize();
- BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), startOffset, numBits);
- startOffset += numBits;
- }
- // Now add the empty LLDPTLV at the end
- BitBufferHelper.setBytes(serializedBytes, LLDP.emptyTLV.serialize(), startOffset, LLDP.emptyTLV.getTLVSize());
-
- return serializedBytes;
- }
-
+ public byte[] serialize() throws PacketException {
+ int startOffset = 0;
+ byte[] serializedBytes = new byte[getLLDPPacketLength()];
+
+ for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
+ LLDPTLV tlv = entry.getValue();
+ int numBits = tlv.getTLVSize();
+ try {
+ BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
+ startOffset, numBits);
+ } catch (BufferException e) {
+ throw new PacketException(e.getMessage());
+ }
+ startOffset += numBits;
+ }
+ // Now add the empty LLDPTLV at the end
+ try {
+ BitBufferHelper.setBytes(serializedBytes,
+ LLDP.emptyTLV.serialize(), startOffset,
+ LLDP.emptyTLV.getTLVSize());
+ } catch (BufferException e) {
+ throw new PacketException(e.getMessage());
+ }
+
+ return serializedBytes;
+ }
+
/**
* Returns the size of LLDP packet in bytes
+ *
* @return int - LLDP Packet size in bytes
- * @throws Exception
*/
- private int getLLDPPacketLength() throws Exception {
- int len = 0;
- LLDPTLV tlv;
-
- for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
- tlv = entry.getValue();
- len += tlv.getTLVSize();
- }
- len += LLDP.emptyTLV.getTLVSize();
-
- return len/NetUtils.NumBitsInAByte;
+ private int getLLDPPacketLength() {
+ int len = 0;
+ LLDPTLV tlv;
+
+ for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
+ tlv = entry.getValue();
+ len += tlv.getTLVSize();
+ }
+ len += LLDP.emptyTLV.getTLVSize();
+
+ return len / NetUtils.NumBitsInAByte;
}
}
}
@Override
- public int getfieldnumBits(String fieldName) throws Exception {
+ public int getfieldnumBits(String fieldName) {
if (fieldName.equals(VALUE)) {
return (NetUtils.NumBitsInAByte * (int) BitBufferHelper.getShort(
fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
* Returns the size in bits of the whole TLV
*
* @return int - size in bits of full TLV
- * @throws Exception
*/
- public int getTLVSize() throws Exception {
+ public int getTLVSize() {
return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
getfieldnumBits(VALUE)); // variable
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import org.slf4j.LoggerFactory;
/**
- * Abstract class which represents the generic network packet object
- * It provides the basic methods which are common for all the packets,
- * like serialize and deserialize
- *
- *
+ * Abstract class which represents the generic network packet object It provides
+ * the basic methods which are common for all the packets, like serialize and
+ * deserialize
+ *
+ *
*/
public abstract class Packet {
protected static final Logger logger = LoggerFactory
- .getLogger(Packet.class);
+ .getLogger(Packet.class);
// Access level granted to this packet
protected boolean writeAccess;
// When deserialized from wire, packet could result corrupted
}
/**
- * This method deserializes the data bits obtained from the wire
- * into the respective header and payload which are of type Packet
+ * This method deserializes the data bits obtained from the wire into the
+ * respective header and payload which are of type Packet
+ *
* @param byte[] data - data from wire to deserialize
- * @param int bitOffset bit position where packet header starts in data array
+ * @param int bitOffset bit position where packet header starts in data
+ * array
* @param int size of packet in bits
* @return Packet
- * @throws Exception
+ * @throws PacketException
*/
public Packet deserialize(byte[] data, int bitOffset, int size)
- throws Exception {
+ throws PacketException {
String hdrField;
Integer startOffset = 0, numBits = 0;
byte[] hdrFieldBytes;
startOffset = bitOffset + this.getfieldOffset(hdrField);
numBits = this.getfieldnumBits(hdrField);
- hdrFieldBytes = BitBufferHelper.getBits(data, startOffset, numBits);
+ try {
+ hdrFieldBytes = BitBufferHelper.getBits(data, startOffset,
+ numBits);
+ } catch (BufferException e) {
+ throw new PacketException(e.getMessage());
+ }
/*
- * Store the raw read value, checks the payload type and
- * set the payloadClass accordingly
+ * Store the raw read value, checks the payload type and set the
+ * payloadClass accordingly
*/
this.setHeaderField(hdrField, hdrFieldBytes);
}
postDeserializeCustomOperation(data, startOffset);
int payloadStart = startOffset + numBits;
- //int payloadSize = size - payloadStart;
+ // int payloadSize = size - payloadStart;
int payloadSize = data.length * NetUtils.NumBitsInAByte - payloadStart;
if (payloadClass != null) {
}
/**
- * This method serializes the header and payload bytes from
- * the respective packet class, into a single stream of bytes
- * to be sent on the wire
+ * This method serializes the header and payload bytes from the respective
+ * packet class, into a single stream of bytes to be sent on the wire
+ *
* @return byte[] - serialized bytes
- * @throws Exception
+ * @throws PacketException
*/
- public byte[] serialize() throws Exception {
+ public byte[] serialize() throws PacketException {
byte[] payloadBytes = null;
int payloadSize = 0;
int headerSize = this.getHeaderSize();
if (fieldBytes != null) {
startOffset = this.getfieldOffset(field);
numBits = this.getfieldnumBits(field);
- BitBufferHelper.setBytes(headerBytes, fieldBytes, startOffset,
- numBits);
+ try {
+ BitBufferHelper.setBytes(headerBytes, fieldBytes,
+ startOffset, numBits);
+ } catch (BufferException e) {
+ throw new PacketException(e.getMessage());
+ }
}
}
postSerializeCustomOperation(headerBytes);
}
/**
- * This method gets called at the end of the serialization process
- * It is intended for the child packets to insert some custom data
- * into the output byte stream which cannot be done or cannot be done
- * efficiently during the normal Packet.serialize() path.
- * An example is the checksum computation for IPv4
+ * This method gets called at the end of the serialization process It is
+ * intended for the child packets to insert some custom data into the output
+ * byte stream which cannot be done or cannot be done efficiently during the
+ * normal Packet.serialize() path. An example is the checksum computation
+ * for IPv4
+ *
* @param byte[] - serialized bytes
+ * @throws PacketException
*/
protected void postSerializeCustomOperation(byte[] myBytes)
- throws Exception {
+ throws PacketException {
// no op
}
/**
- * This method re-computes the checksum of the bits received on the
- * wire and validates it with the checksum in the bits received
- * Since the computation of checksum varies based on the protocol,
- * this method is overridden
- * Currently only IPv4 does checksum computation and validation
- * TCP and UDP need to implement these if required
+ * This method re-computes the checksum of the bits received on the wire and
+ * validates it with the checksum in the bits received Since the computation
+ * of checksum varies based on the protocol, this method is overridden
+ * Currently only IPv4 does checksum computation and validation TCP and UDP
+ * need to implement these if required
+ *
* @param byte[] data
* @param int endBitOffset
- * @return void
+ * @throws PacketException
*/
protected void postDeserializeCustomOperation(byte[] data, int endBitOffset)
- throws Exception {
- // no op
+ throws PacketException {
+ // no op
}
/**
* Gets the header length in bits
- * @return int
- * @throws Exception
+ *
+ * @return int the header length in bits
*/
- public int getHeaderSize() throws Exception {
+ public int getHeaderSize() {
int size = 0;
/*
- * We need to iterate over the fields that were read in the frame (hdrFieldsMap)
- * not all the possible ones described in hdrFieldCoordMap.
- * For ex, 802.1Q may or may not be there
+ * We need to iterate over the fields that were read in the frame
+ * (hdrFieldsMap) not all the possible ones described in
+ * hdrFieldCoordMap. For ex, 802.1Q may or may not be there
*/
for (Map.Entry<String, byte[]> fieldEntry : hdrFieldsMap.entrySet()) {
if (fieldEntry.getValue() != null) {
/**
* This method fetches the start bit offset for header field specified by
- * 'fieldname'. The offset is present in the hdrFieldCoordMap of the respective
- * packet class
- * @param String fieldName
+ * 'fieldname'. The offset is present in the hdrFieldCoordMap of the
+ * respective packet class
+ *
+ * @param String
+ * fieldName
* @return Integer - startOffset of the requested field
*/
public int getfieldOffset(String fieldName) {
/**
* This method fetches the number of bits for header field specified by
- * 'fieldname'. The numBits are present in the hdrFieldCoordMap of the respective
- * packet class
- * @param String fieldName
+ * 'fieldname'. The numBits are present in the hdrFieldCoordMap of the
+ * respective packet class
+ *
+ * @param String
+ * fieldName
* @return Integer - number of bits of the requested field
*/
- public int getfieldnumBits(String fieldName) throws Exception {
+ public int getfieldnumBits(String fieldName) {
return (((Pair<Integer, Integer>) hdrFieldCoordMap.get(fieldName))
.getRight());
}
} else if (entry.getValue().length == 4) {
try {
ret.append(InetAddress.getByAddress(entry.getValue())
- .getHostAddress()
- + " ");
+ .getHostAddress() + " ");
} catch (UnknownHostException e) {
- logger.error("",e);
+ logger.error("", e);
}
} else {
ret.append(((Long) BitBufferHelper.getLong(entry.getValue()))
- .toString()
- + " ");
+ .toString() + " ");
}
}
return ret.toString();
/**
* Returns true if the packet is corrupted
+ *
* @return boolean
*/
protected boolean isPacketCorrupted() {
--- /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.sal.packet;
+
+/**
+ * Describes an exception that is raised when the process of serializing or
+ * deserializing a network packet/stream fails. This generally happens when the
+ * packet/stream is malformed.
+ *
+ */
+public class PacketException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public PacketException(String message) {
+ super(message);
+ }
+}
byte protocol = ip.getProtocol();
Assert.assertTrue(protocol == 1);
- Class<? extends Packet> clazz = ip.protocolClassMap.get(protocol);
+ Class<? extends Packet> clazz = IPv4.protocolClassMap.get(protocol);
System.out.printf("clazz = %s\n", clazz.getName());
Assert.assertTrue(clazz == ICMP.class);
}
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.packet.Ethernet;
try {
res.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
} catch (Exception e) {
- logger.warn("", e);
+ logger.warn("Failed to decode packet: {}", e.getMessage());
}
return res;
}
}
}
+ @Override
+ public void flowErrorReported(Node node, long rid, Object err) {
+ logger.error("Got error {} for message rid {} from node {}",
+ new Object[] { err, rid, node });
+
+ for (IFlowProgrammerListener l : listener) {
+ l.flowErrorReported(node, rid, err);
+ }
+ }
+
// ---------------- OSGI TEST CODE ------------------------------//
private void registerWithOSGIConsole() {
return flow;
}
- /*
+ /**
* This Request ID generator starts with 1. Each aysnc message is
* associated with an unique Request ID (!= 0).
+ *
+ * @return Request ID
*/
private long getNextRid() {
return seq.getAndIncrement();
+++ /dev/null
-***************
-*** 29,35 ****
- import org.opendaylight.controller.switchmanager.SwitchConfig;
- import org.opendaylight.controller.usermanager.IUserManager;
- import org.opendaylight.controller.web.IOneWeb;
-- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
---- 31,36 ----
- import org.opendaylight.controller.switchmanager.SwitchConfig;
- import org.opendaylight.controller.usermanager.IUserManager;
- import org.opendaylight.controller.web.IOneWeb;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
-***************
-*** 182,189 ****
- @RequestMapping(value = "/flow", method = RequestMethod.POST)
- @ResponseBody
- public String actionFlow(@RequestParam(required = true) String action,
-- @RequestParam(required = false) String body, @RequestParam(required = true) String nodeId) {
-- if (!authorize(UserLevel.NETWORKADMIN)) {
- return "Operation not authorized";
- }
-
---- 183,190 ----
- @RequestMapping(value = "/flow", method = RequestMethod.POST)
- @ResponseBody
- public String actionFlow(@RequestParam(required = true) String action,
-+ @RequestParam(required = false) String body, @RequestParam(required = true) String nodeId, HttpServletRequest request) {
-+ if (!authorize(UserLevel.NETWORKADMIN, request)) {
- return "Operation not authorized";
- }
-
-***************
-*** 206,213 ****
- @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
- @ResponseBody
- public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
-- @RequestParam(required = true) String action) {
-- if (!authorize(UserLevel.NETWORKADMIN)) { return "Operation not authorized"; }
-
- IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
- .getInstance(IForwardingRulesManager.class, "default", this);
---- 207,214 ----
- @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
- @ResponseBody
- public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
-+ @RequestParam(required = true) String action, HttpServletRequest request) {
-+ if (!authorize(UserLevel.NETWORKADMIN, request)) { return "Operation not authorized"; }
-
- IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
- .getInstance(IForwardingRulesManager.class, "default", this);
-***************
-*** 235,248 ****
- *
- * @param level
- */
-- private boolean authorize(UserLevel level) {
- IUserManager userManager = (IUserManager) ServiceHelper
- .getGlobalInstance(IUserManager.class, this);
- if (userManager == null) {
- return false;
- }
-
-- String username = SecurityContextHolder.getContext().getAuthentication().getName();
- UserLevel userLevel = userManager.getUserLevel(username);
- if (userLevel.toNumber() <= level.toNumber()) {
- return true;
---- 236,249 ----
- *
- * @param level
- */
-+ private boolean authorize(UserLevel level, HttpServletRequest request) {
- IUserManager userManager = (IUserManager) ServiceHelper
- .getGlobalInstance(IUserManager.class, this);
- if (userManager == null) {
- return false;
- }
-
-+ String username = request.getUserPrincipal().getName();
- UserLevel userLevel = userManager.getUserLevel(username);
- if (userLevel.toNumber() <= level.toNumber()) {
- return true;
<!-- #menu -->
<div id="menu" class="navbar navbar-fixed-top">
<div class="navbar-inner row-fluid">
- <div class="span10">
+ <div class="span9">
<a class="brand" href="/" title="${version}">${name}</a>
<ul class="nav nav-tabs">
</ul>
</div>
- <div class="span2">
+ <div class="span3">
<div id="toolbar" class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
<div class="icon-user"></div> ${username} <span class="caret"></span>
</body>
-</html>
\ No newline at end of file
+</html>
if (body.length == 0 && !(typeof thead === 'undefined')) {
var $tr = $(document.createElement('tr'));
var $td = $(document.createElement('td'));
- $td.attr("colspan", thead.length);
- $td.text("No data available");
- $td.addClass("empty");
+ $td.attr('colspan', thead.length);
+ $td.text('No data available');
+ $td.addClass('empty');
$tr.append($td);
$tbody.append($tr);
return $tbody;
// else, populate as usual
$(body).each(function(index, value) {
var $tr = $(document.createElement('tr'));
- // data-id
- if (value['id'] != undefined) {
- $tr.attr('data-id', value['id']);
- }
- // add classes
- $(value["type"]).each(function(index, value) {
- $tr.addClass(value);
- });
- // add entries
- $(value["entry"]).each(function(index, value) {
- var $td = $(document.createElement('td'));
- $td.append(value);
- $tr.append($td);
+ $.each(value, function(key, value) {
+ if (key == 'type') {
+ // add classes
+ $(value).each(function(index, value) {
+ $tr.addClass(value);
+ });
+ } else if (key == 'entry') {
+ // add entries
+ $(value).each(function(index, value) {
+ var $td = $(document.createElement('td'));
+ $td.append(value);
+ $tr.append($td);
+ });
+ } else {
+ // data field
+ $tr.attr('data-' + key, value);
+ }
+ $tbody.append($tr);
});
- $tbody.append($tr);
});
return $tbody;
}
one.lib.registry.alert = setTimeout(function() {
$("#alert").slideUp();
}, 8000);
-}
\ No newline at end of file
+}