[OPNFLWPLUG-881] Openflow plugin fails to control OF10 Switches Created: 18/Apr/17  Updated: 27/Sep/21  Resolved: 22/May/17

Status: Resolved
Project: OpenFlowPlugin
Component/s: General
Affects Version/s: None
Fix Version/s: None

Type: Bug
Reporter: Venkatrangan Govindarajan Assignee: Venkatrangan Govindarajan
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Attachments: Text File karaf.log     Text File karaf.log     Text File karaf.txt    
External issue ID: 8239

 Description   

Versions

ODL: Carbon
(build: https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/org/opendaylight/integration/distribution-karaf/0.6.0-SNAPSHOT/distribution-karaf-0.6.0-20170417.101545-4929.zip)

OVS : 2.0.2, Mininet: 2.2.1 on Ubuntu 14.0.4

Executed Mininet using the below command
sudo mn --controller 'remote,ip=<odl_ip>,port=6633' --topo tree,3 --switch ovsk,protocols=OpenFlow10

Feature Installed in ODL : odl-vtn-manager that uses odl-openflowplugin.

Problems:

a. VTN invokes statistics rpc that fails with the below Error Message

----------- start of log snippet

java.lang.IllegalArgumentException: Metadata not available for modification NodeModification [identifier=(urn:opendaylight:inventory?revision=2013-08-19)node-connector[

{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1:LOCAL}

], modificationType=TOUCH, childModification={AugmentationIdentifier

{childNames=[(urn:opendaylight:port:statistics?revision=2013-12-14)flow-capable-node-connector-statistics]}

=NodeModification [identifier=AugmentationIdentifier

{childNames=[(urn:opendaylight:port:statistics?revision=2013-12-14)flow-capable-node-connector-statistics]}

, modificationType=TOUCH, childModification={(urn:opendaylight:port:statistics?revision=2013-12-14)flow-capable-node-connector-statistics=NodeModification [identifier=(urn:opendaylight:port:statistics?revision=2013-12-14)flow-capable-node-connector-statistics, modificationType=WRITE, childModification={}]}]}]
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:145)[65:com.google.guava:18.0.0]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaAwareApplyOperation.apply(SchemaAwareApplyOperation.java:198)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.mutateChildren(AbstractNodeContainerModificationStrategy.java:139)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.applyTouch(AbstractNodeContainerModificationStrategy.java:252)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.applyMerge(AbstractNodeContainerModificationStrategy.java:170)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaAwareApplyOperation.apply(SchemaAwareApplyOperation.java:213)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.mutateChildren(AbstractNodeContainerModificationStrategy.java:139)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.applyWrite(AbstractNodeContainerModificationStrategy.java:113)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.ListEntryModificationStrategy.applyWrite(ListEntryModificationStrategy.java:48)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaAwareApplyOperation.apply(SchemaAwareApplyOperation.java:219)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.ModifiedNode.seal(ModifiedNode.java:282)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractReadyIterator.process(AbstractReadyIterator.java:56)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeModification.ready(InMemoryDataTreeModification.java:284)[101:org.opendaylight.yangtools.yang-data-impl:1.1.0.SNAPSHOT]
at org.opendaylight.controller.sal.core.spi.data.SnapshotBackedWriteTransaction.ready(SnapshotBackedWriteTransaction.java:139)[162:org.opendaylight.controller.sal-core-spi:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.LocalTransactionChain.onTransactionReady(LocalTransactionChain.java:94)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.LocalTransactionContext.ready(LocalTransactionContext.java:75)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.LocalTransactionContext.directCommit(LocalTransactionContext.java:86)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.TransactionProxy.getDirectCommitFuture(TransactionProxy.java:278)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.TransactionProxy.createSingleCommitCohort(TransactionProxy.java:265)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.TransactionProxy.ready(TransactionProxy.java:231)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.datastore.TransactionProxy.ready(TransactionProxy.java:53)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.cluster.databroker.AbstractDOMBrokerWriteTransaction.submit(AbstractDOMBrokerWriteTransaction.java:142)[204:org.opendaylight.controller.sal-distributed-datastore:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.PingPongTransactionChain.processTransaction(PingPongTransactionChain.java:235)[164:org.opendaylight.controller.sal-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.PingPongTransactionChain.processIfReady(PingPongTransactionChain.java:211)[164:org.opendaylight.controller.sal-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.PingPongTransactionChain.readyTransaction(PingPongTransactionChain.java:319)[164:org.opendaylight.controller.sal-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.PingPongTransactionChain$4.submit(PingPongTransactionChain.java:448)[164:org.opendaylight.controller.sal-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.binding.impl.AbstractWriteTransaction.doSubmit(AbstractWriteTransaction.java:134)[166:org.opendaylight.controller.sal-binding-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.binding.impl.BindingDOMWriteTransactionAdapter.submit(BindingDOMWriteTransactionAdapter.java:83)[166:org.opendaylight.controller.sal-binding-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.controller.md.sal.binding.impl.BindingDOMTransactionChainAdapter$2.submit(BindingDOMTransactionChainAdapter.java:80)[166:org.opendaylight.controller.sal-binding-broker-impl:1.5.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.device.TransactionChainManager.submitWriteTransaction(TransactionChainManager.java:175)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.device.TransactionChainManager.initialSubmitWriteTransaction(TransactionChainManager.java:95)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.device.DeviceContextImpl.initialSubmitTransaction(DeviceContextImpl.java:224)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl$5.onSuccess(StatisticsContextImpl.java:513)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl$5.onSuccess(StatisticsContextImpl.java:505)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at com.google.common.util.concurrent.Futures$6.run(Futures.java:1319)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:457)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:53)[65:com.google.guava:18.0.0]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl.statChainFuture(StatisticsContextImpl.java:283)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl.access$200(StatisticsContextImpl.java:57)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl$3.onSuccess(StatisticsContextImpl.java:295)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.statistics.StatisticsContextImpl$3.onSuccess(StatisticsContextImpl.java:292)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at com.google.common.util.concurrent.Futures$6.run(Futures.java:1319)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:457)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture$1.run(Futures.java:918)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:457)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.add(ExecutionList.java:101)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.AbstractFuture.addListener(AbstractFuture.java:170)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture.run(Futures.java:914)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:457)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185)[65:com.google.guava:18.0.0]
at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:53)[65:com.google.guava:18.0.0]
at org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext.setResult(AbstractRequestContext.java:32)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.device.listener.MultiMsgCollectorImpl.endCollecting(MultiMsgCollectorImpl.java:70)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.device.listener.MultiMsgCollectorImpl.addMultipartMsg(MultiMsgCollectorImpl.java:58)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback.onSuccess(AbstractMultipartRequestCallback.java:54)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback.onSuccess(AbstractMultipartRequestCallback.java:22)[220:org.opendaylight.openflowplugin.impl:0.4.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.OutboundQueueEntry.complete(OutboundQueueEntry.java:121)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.StackedSegment.completeEntry(StackedSegment.java:113)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.StackedSegment.pairRequest(StackedSegment.java:153)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.AbstractStackedOutboundQueue.pairRequest(AbstractStackedOutboundQueue.java:203)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.AbstractOutboundQueueManager.onMessage(AbstractOutboundQueueManager.java:208)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl.consumeDeviceMessage(ConnectionAdapterImpl.java:122)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.AbstractConnectionAdapterStatistics.consume(AbstractConnectionAdapterStatistics.java:66)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl.consume(ConnectionAdapterImpl.java:43)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at org.opendaylight.openflowjava.protocol.impl.core.DelegatingInboundHandler.channelRead(DelegatingInboundHandler.java:43)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)[139:io.netty.transport:4.1.8.Final]
at org.opendaylight.openflowjava.protocol.impl.core.connection.AbstractOutboundQueueManager.channelRead(AbstractOutboundQueueManager.java:195)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)[141:io.netty.codec:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)[141:io.netty.codec:4.1.8.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)[141:io.netty.codec:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)[141:io.netty.codec:4.1.8.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)[141:io.netty.codec:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287)[143:io.netty.handler:4.1.8.Final]
at org.opendaylight.openflowjava.protocol.impl.core.IdleHandler.channelRead(IdleHandler.java:39)[209:org.opendaylight.openflowjava.openflow-protocol-impl:0.9.0.SNAPSHOT]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)[139:io.netty.transport:4.1.8.Final]
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:1018)[144:io.netty.transport-native-epoll:4.1.8.Final]
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:394)[144:io.netty.transport-native-epoll:4.1.8.Final]
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:288)[144:io.netty.transport-native-epoll:4.1.8.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)[138:io.netty.common:4.1.8.Final]
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)[138:io.netty.common:4.1.8.Final]

---------- end of log snippet

b. openflowplugin fails to recover even after multiple mininet restarts.

karaf log has been attached.



 Comments   
Comment by Venkatrangan Govindarajan [ 18/Apr/17 ]

Attachment karaf.log has been added with description: Karaf Log with Errors.

Comment by Venkatrangan Govindarajan [ 18/Apr/17 ]

Detailed analysis of the problem for fixing

The issue occurs when statistics manager writes flow-capable-node-connector-statistics into DS before the target node-connector is created.
Since the parent node of the target node-connector doesn't exist at that time, the failure occurs.

When we use Mininet to generate switches, switches are generated without any ports firstly, then ports are generated. Therefore, the OFP needs to handle such a situation, but it doesn't right now.

When the issue happened, that is, the OFP got connected with OF 1.0 switches, the OPF worked as follows:

Step 1. Handshake with an OF 1.0 switch was done successfully. OFP got the result of the OFPT_FEATURES_REPLY. At that time, the result didn't contain port information.

The postHandshake() of the HandshakeManagerImpl.java sent the FEATURES_REQUEST after the handshake.

[openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/HandshakeManagerImpl.java]

/**

  • after handshake set features, register to session
  • @param proposedVersion proposed openflow version
  • @param xid transaction id
    */
    protected void postHandshake(final Short proposedVersion, final Long xid) {
    // set version
    version = proposedVersion;

LOG.debug("version set: {}", proposedVersion);
// request features
GetFeaturesInputBuilder featuresBuilder = new GetFeaturesInputBuilder();
featuresBuilder.setVersion(version).setXid(xid);
LOG.debug("sending feature request for version={} and xid={}", version, xid);
Future<RpcResult<GetFeaturesOutput>> featuresFuture = connectionAdapter
.getFeatures(featuresBuilder.build());

On the success, the onHandshakeSuccessful() of HandshakeListenerImpl.java was called with the result of the FEATURES_REPLY.

[impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/HandshakeListenerImpl.java]

new FutureCallback<RpcResult<GetFeaturesOutput>>() {
@Override
public void onSuccess(RpcResult<GetFeaturesOutput> rpcFeatures) {
LOG.trace("features are back");
if (rpcFeatures.isSuccessful()) {
GetFeaturesOutput featureOutput = rpcFeatures.getResult();

LOG.debug("obtained features: datapathId={}",
featureOutput.getDatapathId());
LOG.debug("obtained features: auxiliaryId={}",
featureOutput.getAuxiliaryId());
LOG.trace("handshake SETTLED: version={}, datapathId={}, auxiliaryId={}",
version, featureOutput.getDatapathId(), featureOutput.getAuxiliaryId());
handshakeListener.onHandshakeSuccessful(featureOutput, proposedVersion);

The onHandshakeSuccessful() method stored the result in ConnectionContextImpl.java.

@Override
public void onHandshakeSuccessful(final GetFeaturesOutput featureOutput, final Short version) {
if (LOG.isDebugEnabled()) {
LOG.debug("handshake succeeded: {}", connectionContext.getConnectionAdapter().getRemoteAddress());
}
this.handshakeContext.close();
connectionContext.changeStateToWorking();
connectionContext.setFeatures(featureOutput);

Step 2. Ports on the OF 1.0 switch was generated, and OFPT_PORT_STATUS was notified to the OFP. However, the initialization of the target node information in the OFP was not completed yet, the OFP didn't write node-connector to the DS.

Receiving PORT_STATUS, processPortStatusMessage() of DeviceContextImpl.java was called, and a node-connector was created.

[impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java]

@Override
public void processPortStatusMessage(final PortStatusMessage portStatus) {
messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
final FlowCapableNodeConnector flowCapableNodeConnector = portStatusTranslator.translate(portStatus, getDeviceInfo(), null);

final KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> iiToNodeConnector = provideIIToNodeConnector(portStatus.getPortNo(), portStatus.getVersion());
try {
if (portStatus.getReason().equals(PortReason.OFPPRADD) || portStatus.getReason().equals(PortReason.OFPPRMODIFY)) {
// because of ADD status node connector has to be created
final NodeConnectorBuilder nConnectorBuilder = new NodeConnectorBuilder().setKey(iiToNodeConnector.getKey());
nConnectorBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, new FlowCapableNodeConnectorStatisticsDataBuilder().build());
nConnectorBuilder.addAugmentation(FlowCapableNodeConnector.class, flowCapableNodeConnector);
writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToNodeConnector, nConnectorBuilder.build());

However, writeToTransaction() which write data into DS is implemented to do nothing when the initialized member variable is false.

@Override
public <T extends DataObject> void writeToTransaction(final LogicalDatastoreType store,
final InstanceIdentifier<T> path,
final T data){
if (initialized)

{ transactionChainManager.writeToTransaction(store, path, data, false); }

}

The initialized variable is modified to true by lazyTransactionManagerInitialization() which is called by onContextInstantiateService().

@VisibleForTesting
void lazyTransactionManagerInitialization() {
if (!this.initialized) {
if (LOG.isDebugEnabled()) {
LOG.debug("Transaction chain manager for node {} created", deviceInfo.getLOGValue());
}
this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo);
this.deviceFlowRegistry = new DeviceFlowRegistryImpl(deviceInfo.getVersion(), dataBroker, deviceInfo.getNodeInstanceIdentifier());
this.deviceGroupRegistry = new DeviceGroupRegistryImpl();
this.deviceMeterRegistry = new DeviceMeterRegistryImpl();
this.initialized = true;
}
}

Step 3. The OFP created the initial data for the OF 1.0 switch. At that time, the OFP used the result of the OFPT_FEATURES_REPLY which the OFP got immediately after handshake in order to create node-connector information. Thus, the OFP didn't create node-connector even though ports existed in the OF 1.0 switch.

The initialization for each OF 1.0 version is implemented in DeviceContextImpl.onContextInstantiateService().

try {
final java.util.Optional<AbstractDeviceInitializer> initializer = deviceInitializerProvider
.lookup(deviceInfo.getVersion());

if (initializer.isPresent())

{ final MultipartWriterProvider writerProvider = MultipartWriterProviderFactory.createDefaultProvider(this); initializer.get().initialize(this, switchFeaturesMandatory, writerProvider, convertorExecutor); }

else

{ throw new ExecutionException(new ConnectionException("Unsupported version " + deviceInfo.getVersion())); }

} catch (ExecutionException | InterruptedException e) {
LOG.warn("Device {} cannot be initialized: ", deviceInfo.getLOGValue(), e);
return false;
}

The instance of the OF10DeviceInitializer class was assigned into the initializer. (openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF10DeviceInitializer.java)
In the consequence of calling the initialize(), OF10DeviceInitializer.initializeNodeInformation() was called.

The OFPMP_DESC of multipart was acquired in OF10DeviceInitializer.initializeNodeInformation().
On success, the initialization of node-connector is executed.

return Futures.transform(future, new Function<Boolean, Void>() {
@Nullable
@Override
public Void apply(@Nullable final Boolean input)

{ writePhyPortInformation(deviceContext); return null; }

});

However, node-connector is created based on the result of FEATURES_REPLY which is stored in ConnectionContextImpl.
Therefore, node-connector is not created when the FEATURES_REPLY doesn't contain port information.

private static void writePhyPortInformation(final DeviceContext deviceContext) {
final DeviceInfo deviceInfo = deviceContext.getDeviceInfo();
final ConnectionContext connectionContext = deviceContext.getPrimaryConnectionContext();
final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext
.oook()
.lookupTranslator(new TranslatorKey(deviceInfo.getVersion(), PortGrouping.class.getName()));

connectionContext.getFeatures().getPhyPort().forEach(port -> {

Step 4. After the OFP waited the completion of the above step (step 3), its statistic manager got the initial data of statistics using OFPT_STATS_REQUEST. At this time, the OFP also got OFPST_PORT, and it wrote flow-capable-node-connector-statistics into DS.

The initialize() of the AbstractDeviceInitializer.java waits the completion of the initialization.

[openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/AbstractDeviceInitializer.java]

// Synchronously get information about device
initializeNodeInformation(deviceContext, switchFeaturesMandatory, multipartWriterProvider, convertorExecutor)
.get();

After that DeviceContextImpl.onContextInstantiateService() called onContextInstantiateService() of StatisticsContextImpl (openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java).

return this.clusterInitializationPhaseHandler.onContextInstantiateService(mastershipChangeListener);

StatisticsContextImpl.onContextInstantiateService() calls the initialization procedure for statistics.

@Override
public boolean onContextInstantiateService(final MastershipChangeListener mastershipChangeListener) {

LOG.info("Starting statistics context cluster services for node {}", deviceInfo.getLOGValue());

this.statListForCollectingInitialization();
Futures.addCallback(this.initialGatherDynamicData(), new FutureCallback<Boolean>() {

Step 5. When the OFP submitted the initial data to DS, it failed to submit, since the node-connector which was the parent of flow-capable-node-connector-statistics, which was wrote in the above step (step 4), didn't exist.

Step 6. Since the initialization of the device failed, the OFP could not control the target switch at all.

Please note that the above explanation is for the master and stable/carbon branch.
However, a very similar issue happens in the stable/boron.

On the stable/boron, the method which does specific initialization for each OF version is initializeNodeInformation() of openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java.
However, this method also used the result of FEATURES_REPLY for initialization node-connector.
Therefore, the issue occurs on the stable/boron as well.

if (OFConstants.OFP_VERSION_1_0 == version) {
final CapabilitiesV10 capabilitiesV10 = connectionContext.getFeatures().getCapabilitiesV10();

DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10);

deviceFeaturesFuture = createDeviceFeaturesForOF10(deviceContext);
// create empty tables after device description is processed
chainTableTrunkWriteOF10(deviceContext, deviceFeaturesFuture);

final short ofVersion = deviceInfo.getVersion();
final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext.oook()
.lookupTranslator(translatorKey);
final BigInteger dataPathId = deviceContext.getDeviceInfo().getDatapathId();

for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) {

Comment by Venkatrangan Govindarajan [ 18/Apr/17 ]

The problem occurs much before VTN invoking any rpc. Please check the Comment 1 for more details.

Comment by Tomas Slusny [ 19/Apr/17 ]

Isn't this really similar to OPNFLWPLUG-790? Because there I am trying to solve same issue, and that is port status messages arriving too early. I made patch that should fix this, so can you test it with this patch from Gerrit: https://git.opendaylight.org/gerrit/#/c/53905/ ?

Comment by Venkatrangan Govindarajan [ 24/Apr/17 ]

(In reply to Tomas Slusny from comment #3)
> Isn't this really similar to OPNFLWPLUG-790? Because there I am trying to solve
> same issue, and that is port status messages arriving too early. I made
> patch that should fix this, so can you test it with this patch from Gerrit:
> https://git.opendaylight.org/gerrit/#/c/53905/ ?

Hi Thomas,

Thanks for responding to the bug report. I tested the patches for OPNFLWPLUG-790, It is not fixing the issue mentioned in this bug.

Comment by Venkatrangan Govindarajan [ 24/Apr/17 ]

Please check the logs from 00:17 time. The errors weere created regularly after that time/.

Comment by Venkatrangan Govindarajan [ 24/Apr/17 ]

Attachment karaf.log has been added with description: Logs with latest stable/carbon code.

Comment by Tomas Slusny [ 24/Apr/17 ]

Can you test it with this patch? https://git.opendaylight.org/gerrit/#/c/55868/

Comment by Tomas Slusny [ 24/Apr/17 ]

Nevermind, need to make some changes on the patch.

Comment by Tomas Slusny [ 27/Apr/17 ]

GERRIT: https://git.opendaylight.org/gerrit/#/c/55868/

Comment by Arthi Bhattacharjee [ 28/Apr/17 ]

Tested the above patch in stable/carbon. Most of the time, issue is been reproduced when miminet is restarted.

Comment by Arthi Bhattacharjee [ 28/Apr/17 ]

Attachment karaf.txt has been added with description: Karaf logs

Comment by Tomas Slusny [ 10/May/17 ]

Can you try it again with latest version of patch please? Now it should handle all missed port statuses since open of connection.

Comment by Abhijit Kumbhare [ 22/May/17 ]

Closing it as it is fixed as per Tomas Slusny - please reopen it if you still see an issue.

Generated at Wed Feb 07 20:33:38 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.