From 3d1cd846102d5a5ea82b56dc50faddc92e3b2fe4 Mon Sep 17 00:00:00 2001 From: Martin Bobak Date: Tue, 2 Jun 2015 10:03:51 +0200 Subject: [PATCH] Bug 3350 - Provide override for features detected during handshake Some devices doesn't provide features considered by OF protocol as mandatory. We introduce configurable variable that overrides features check. Change-Id: I8f7fe9c31f00b785bd19b5f0e79b8162fa7a2a4b Signed-off-by: Martin Bobak (cherry picked from commit 4085d17036f47c4b9bcc5113b079309b64fbc390) --- .../api/openflow/OpenFlowPluginProvider.java | 13 ++++- .../initial/42-openflowplugin-new.xml | 1 + .../impl/OpenFlowPluginProviderImpl.java | 11 +++- .../impl/device/DeviceManagerImpl.java | 51 ++++++++++++------- .../rev150327/OpenFlowProviderModule.java | 3 +- .../src/main/yang/openflow-plugin-impl.yang | 4 ++ 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java index 83852de9da..ffbaaabccf 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java @@ -50,4 +50,15 @@ public interface OpenFlowPluginProvider extends AutoCloseable, BindingService { */ void initialize(); -} + /** + * This parameter indicates whether it is mandatory for switch to support OF1.3 features : table, flow, meter,group. + * If this is set to true and switch doesn't support these features its connection will be denied. + * @param switchFeaturesMandatory + */ + void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory); + + boolean isSwitchFeaturesMandatory(); + + + + } diff --git a/openflowplugin-controller-config/src/main/resources/initial/42-openflowplugin-new.xml b/openflowplugin-controller-config/src/main/resources/initial/42-openflowplugin-new.xml index 4e44ba4cff..e6418ad447 100644 --- a/openflowplugin-controller-config/src/main/resources/initial/42-openflowplugin-new.xml +++ b/openflowplugin-controller-config/src/main/resources/initial/42-openflowplugin-new.xml @@ -83,6 +83,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html binding-notification-publish-adapter 20000 + false diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java index 469fff3197..30173363c7 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java @@ -72,6 +72,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF private DataBroker dataBroker; private OfpRole role; private Collection switchConnectionProviders; + private boolean switchFeaturesMandatory = false; public OpenFlowPluginProviderImpl(final long rpcRequestsQuota) { Preconditions.checkArgument(rpcRequestsQuota > 0 && rpcRequestsQuota <= Integer.MAX_VALUE, "rpcRequestQuota has to be in range <1,%s>", Integer.MAX_VALUE); @@ -102,6 +103,14 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF }); } + public boolean isSwitchFeaturesMandatory() { + return switchFeaturesMandatory; + } + + public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) { + this.switchFeaturesMandatory = switchFeaturesMandatory; + } + public static MessageIntelligenceAgency getMessageIntelligenceAgency() { return OpenFlowPluginProviderImpl.messageIntelligenceAgency; } @@ -143,7 +152,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF registerMXBean(messageIntelligenceAgency); - deviceManager = new DeviceManagerImpl(dataBroker, messageIntelligenceAgency); + deviceManager = new DeviceManagerImpl(dataBroker, messageIntelligenceAgency, switchFeaturesMandatory); statisticsManager = new StatisticsManagerImpl(); rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index a2ad5528dc..4c776c5d41 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -94,6 +94,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,9 +121,11 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { private final long barrierNanos = TimeUnit.MILLISECONDS.toNanos(500); private final int maxQueueDepth = 25600; + private final boolean switchFeaturesMandatory; public DeviceManagerImpl(@Nonnull final DataBroker dataBroker, - @Nonnull final MessageIntelligenceAgency messageIntelligenceAgency) { + @Nonnull final MessageIntelligenceAgency messageIntelligenceAgency, + final boolean switchFeaturesMandatory) { this.dataBroker = Preconditions.checkNotNull(dataBroker); hashedWheelTimer = new HashedWheelTimer(TICK_DURATION, TimeUnit.MILLISECONDS, 500); /* merge empty nodes to oper DS to predict any problems with missing parent for Node */ @@ -139,8 +142,10 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { } this.messageIntelligenceAgency = messageIntelligenceAgency; + this.switchFeaturesMandatory = switchFeaturesMandatory; } + @Override public void setDeviceInitializationPhaseHandler(final DeviceInitializationPhaseHandler handler) { deviceInitPhaseHandler = handler; @@ -153,14 +158,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { try { ((DeviceContextImpl) deviceContext).initialSubmitTransaction(); deviceContext.onPublished(); - } - catch (final Exception e) { + } catch (final Exception e) { LOG.warn("Node {} can not be add to OPERATIONAL DataStore yet because {} ", deviceContext.getDeviceState().getNodeId(), e.getMessage()); LOG.trace("Problem with add node {} to OPERATIONAL DataStore", deviceContext.getDeviceState().getNodeId(), e); try { deviceContext.close(); - } - catch (final Exception e1) { + } catch (final Exception e1) { LOG.warn("Device context close FAIL - " + deviceContext.getDeviceState().getNodeId()); } } @@ -247,9 +250,7 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { Futures.addCallback(deviceFeaturesFuture, new FutureCallback>>>() { @Override public void onSuccess(final List>> result) { - deviceContext.getDeviceState().setValid(true); - deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext); - LOG.trace("Device context level up called."); + deviceCtxLevelUp(deviceContext); } @Override @@ -261,6 +262,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { }); } + private void deviceCtxLevelUp(final DeviceContext deviceContext) { + deviceContext.getDeviceState().setValid(true); + deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext); + LOG.trace("Device context level up called."); + } + private static void chainTableTrunkWriteOF10(final DeviceContext deviceContext, final ListenableFuture>>> deviceFeaturesFuture) { Futures.addCallback(deviceFeaturesFuture, new FutureCallback>>>() { @Override @@ -294,8 +301,8 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { return Futures.allAsList(Arrays.asList(replyDesc)); } - private static ListenableFuture>>> createDeviceFeaturesForOF13(final DeviceContext deviceContext, - final DeviceState deviceState) { + private ListenableFuture>>> createDeviceFeaturesForOF13(final DeviceContext deviceContext, + final DeviceState deviceState) { final ListenableFuture>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC, deviceContext, @@ -345,13 +352,19 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { deviceContext, deviceState.getNodeInstanceIdentifier(), replyPortDescription); - - - return Futures.allAsList(Arrays.asList( - replyMeterFeature, - replyGroupFeatures, -// replyTableFeatures, - replyPortDescription)); + if (switchFeaturesMandatory) { + return Futures.allAsList(Arrays.asList( + replyMeterFeature, + replyGroupFeatures, + replyTableFeatures, + replyPortDescription)); + } else { + return Futures.successfulAsList(Arrays.asList( + replyMeterFeature, + replyGroupFeatures, + replyTableFeatures, + replyPortDescription)); + } } }); @@ -402,10 +415,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { @Override public void onFailure(final Throwable t) { LOG.info("Fail response from OutboundQueue for multipart type {}.", type); - requestContext.close(); + final RpcResult> rpcResult = RpcResultBuilder.>failed().build(); + requestContext.setResult(rpcResult); if (MultipartType.OFPMPTABLEFEATURES.equals(type)) { makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext().getFeatures().getTables()); } + requestContext.close(); } }); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/config/openflow/plugin/impl/rev150327/OpenFlowProviderModule.java b/openflowplugin-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/config/openflow/plugin/impl/rev150327/OpenFlowProviderModule.java index bde4475ccf..505f7ee043 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/config/openflow/plugin/impl/rev150327/OpenFlowProviderModule.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/config/openflow/plugin/impl/rev150327/OpenFlowProviderModule.java @@ -35,8 +35,7 @@ public class OpenFlowProviderModule extends org.opendaylight.yang.gen.v1.urn.ope openflowPluginProvider.setRpcProviderRegistry(getRpcRegistryDependency()); openflowPluginProvider.setNotificationProviderService(getNotificationAdapterDependency()); openflowPluginProvider.setNotificationPublishService(getNotificationPublishAdapterDependency()); - - + openflowPluginProvider.setSwitchFeaturesMandatory(getSwitchFeaturesMandatory()); openflowPluginProvider.initialize(); return openflowPluginProvider; diff --git a/openflowplugin-impl/src/main/yang/openflow-plugin-impl.yang b/openflowplugin-impl/src/main/yang/openflow-plugin-impl.yang index 1d7e0fd1cc..9ce8fafb29 100644 --- a/openflowplugin-impl/src/main/yang/openflow-plugin-impl.yang +++ b/openflowplugin-impl/src/main/yang/openflow-plugin-impl.yang @@ -79,6 +79,10 @@ module openflow-plugin-provider-impl { type uint32; default 500; } + leaf switch-features-mandatory { + type boolean; + default false; + } } } -- 2.36.6