mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-12-16 23:01:28 +01:00
Fix for CVE-2018-1000155
Denial of Service, Improper Authentication and Authorization, and Covert Channel in the OpenFlow 1.0+ handshake Change-Id: Ifd285208266a1f331f3b802cb656349aad1782a9
This commit is contained in:
parent
4ef245e8ea
commit
f69e3e3409
@ -23,9 +23,9 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.PublicKey;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -241,19 +241,15 @@ public class NettyMessagingManager implements MessagingService {
|
|||||||
try {
|
try {
|
||||||
for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) {
|
for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) {
|
||||||
String alias = e.nextElement();
|
String alias = e.nextElement();
|
||||||
Key key = ks.getKey(alias, ksPwd);
|
Certificate cert = ks.getCertificate(alias);
|
||||||
Certificate[] certs = ks.getCertificateChain(alias);
|
if (cert == null) {
|
||||||
log.debug("{} -> {}", alias, certs);
|
log.info("No certificate for alias {}", alias);
|
||||||
final byte[] encodedKey;
|
continue;
|
||||||
if (certs != null && certs.length > 0) {
|
|
||||||
encodedKey = certs[0].getEncoded();
|
|
||||||
} else {
|
|
||||||
log.info("Could not find cert chain for {}, using fingerprint of key instead...", alias);
|
|
||||||
encodedKey = key.getEncoded();
|
|
||||||
}
|
}
|
||||||
|
PublicKey key = cert.getPublicKey();
|
||||||
// Compute the certificate's fingerprint (use the key if certificate cannot be found)
|
// Compute the certificate's fingerprint (use the key if certificate cannot be found)
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||||
digest.update(encodedKey);
|
digest.update(key.getEncoded());
|
||||||
StringJoiner fingerprint = new StringJoiner(":");
|
StringJoiner fingerprint = new StringJoiner(":");
|
||||||
for (byte b : digest.digest()) {
|
for (byte b : digest.digest()) {
|
||||||
fingerprint.add(String.format("%02X", b));
|
fingerprint.add(String.format("%02X", b));
|
||||||
|
|||||||
@ -9,6 +9,7 @@ COMPILE_DEPS = [
|
|||||||
'//lib:netty-handler',
|
'//lib:netty-handler',
|
||||||
'//lib:netty-transport',
|
'//lib:netty-transport',
|
||||||
'//lib:netty-transport-native-epoll',
|
'//lib:netty-transport-native-epoll',
|
||||||
|
'//lib:JACKSON',
|
||||||
]
|
]
|
||||||
|
|
||||||
TEST_DEPS = [
|
TEST_DEPS = [
|
||||||
|
|||||||
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-present Open Networking Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.onosproject.openflow.config;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import org.onosproject.net.DeviceId;
|
||||||
|
import org.onosproject.net.config.Config;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for OpenFlow devices.
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class OpenFlowDeviceConfig extends Config<DeviceId> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netcfg ConfigKey.
|
||||||
|
*/
|
||||||
|
public static final String CONFIG_KEY = "openflow";
|
||||||
|
|
||||||
|
public static final String CLIENT_KEY_ALIAS = "keyAlias";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
return hasOnlyFields(CLIENT_KEY_ALIAS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the certFile for the switch.
|
||||||
|
*
|
||||||
|
* @return cert file
|
||||||
|
*/
|
||||||
|
public Optional<String> keyAlias() {
|
||||||
|
String keyAlias = get(CLIENT_KEY_ALIAS, "");
|
||||||
|
return (keyAlias.isEmpty() ? Optional.empty() : Optional.ofNullable(keyAlias));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key alias for the Device.
|
||||||
|
*
|
||||||
|
* @param keyAlias key alias as string
|
||||||
|
* @return instance for chaining
|
||||||
|
*/
|
||||||
|
public OpenFlowDeviceConfig setKeyAlias(String keyAlias) {
|
||||||
|
return (OpenFlowDeviceConfig) setOrClear(CLIENT_KEY_ALIAS, keyAlias);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-present Open Networking Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the OpenFlow controller IO subsystem.
|
||||||
|
*/
|
||||||
|
package org.onosproject.openflow.config;
|
||||||
@ -30,10 +30,12 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
import org.onlab.util.ItemNotFoundException;
|
import org.onlab.util.ItemNotFoundException;
|
||||||
import org.onosproject.net.DeviceId;
|
import org.onosproject.net.DeviceId;
|
||||||
|
import org.onosproject.net.config.NetworkConfigRegistry;
|
||||||
import org.onosproject.net.driver.DefaultDriverData;
|
import org.onosproject.net.driver.DefaultDriverData;
|
||||||
import org.onosproject.net.driver.DefaultDriverHandler;
|
import org.onosproject.net.driver.DefaultDriverHandler;
|
||||||
import org.onosproject.net.driver.Driver;
|
import org.onosproject.net.driver.Driver;
|
||||||
import org.onosproject.net.driver.DriverService;
|
import org.onosproject.net.driver.DriverService;
|
||||||
|
import org.onosproject.openflow.config.OpenFlowDeviceConfig;
|
||||||
import org.onosproject.openflow.controller.Dpid;
|
import org.onosproject.openflow.controller.Dpid;
|
||||||
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
|
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
|
||||||
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
|
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
|
||||||
@ -54,11 +56,14 @@ import java.security.KeyStore;
|
|||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.Dictionary;
|
import java.util.Dictionary;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -99,12 +104,14 @@ public class Controller {
|
|||||||
protected char[] ksPwd;
|
protected char[] ksPwd;
|
||||||
protected char[] tsPwd;
|
protected char[] tsPwd;
|
||||||
protected SSLContext sslContext;
|
protected SSLContext sslContext;
|
||||||
|
protected KeyStore keyStore;
|
||||||
|
|
||||||
// Perf. related configuration
|
// Perf. related configuration
|
||||||
protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
|
protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||||
|
|
||||||
private DriverService driverService;
|
private DriverService driverService;
|
||||||
private boolean enableOfTls = TLS_DISABLED;
|
private boolean enableOfTls = TLS_DISABLED;
|
||||||
|
private NetworkConfigRegistry netCfgService;
|
||||||
|
|
||||||
// **************
|
// **************
|
||||||
// Initialization
|
// Initialization
|
||||||
@ -241,9 +248,9 @@ public class Controller {
|
|||||||
tmFactory.init(ts);
|
tmFactory.init(ts);
|
||||||
|
|
||||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||||
KeyStore ks = KeyStore.getInstance("JKS");
|
keyStore = KeyStore.getInstance("JKS");
|
||||||
ks.load(new FileInputStream(ksLocation), ksPwd);
|
keyStore.load(new FileInputStream(ksLocation), ksPwd);
|
||||||
kmf.init(ks, ksPwd);
|
kmf.init(keyStore, ksPwd);
|
||||||
|
|
||||||
sslContext = SSLContext.getInstance("TLS");
|
sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null);
|
sslContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null);
|
||||||
@ -275,6 +282,36 @@ public class Controller {
|
|||||||
return (this.systemStartTime);
|
return (this.systemStartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isValidCertificate(Long dpid, Certificate peerCert) {
|
||||||
|
if (netCfgService == null) {
|
||||||
|
// netcfg service not available; accept any cert
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceId deviceId = DeviceId.deviceId(Dpid.uri(new Dpid(dpid)));
|
||||||
|
OpenFlowDeviceConfig config =
|
||||||
|
netCfgService.getConfig(deviceId, OpenFlowDeviceConfig.class);
|
||||||
|
if (config == null) {
|
||||||
|
// Config not set for device, accept any certificate
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<String> alias = config.keyAlias();
|
||||||
|
if (!alias.isPresent()) {
|
||||||
|
// Config for device does not specify a certificate chain, accept any cert
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Certificate configuredCert = keyStore.getCertificate(alias.get());
|
||||||
|
//FIXME there's probably a better way to compare these
|
||||||
|
return Objects.deepEquals(peerCert, configuredCert);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
log.info("failed to load key", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward to the driver-manager to get an IOFSwitch instance.
|
* Forward to the driver-manager to get an IOFSwitch instance.
|
||||||
*
|
*
|
||||||
@ -317,10 +354,17 @@ public class Controller {
|
|||||||
return ofSwitchDriver;
|
return ofSwitchDriver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void start(OpenFlowAgent ag, DriverService driverService) {
|
public void start(OpenFlowAgent ag, DriverService driverService) {
|
||||||
|
start(ag, driverService, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(OpenFlowAgent ag, DriverService driverService,
|
||||||
|
NetworkConfigRegistry netCfgService) {
|
||||||
log.info("Starting OpenFlow IO");
|
log.info("Starting OpenFlow IO");
|
||||||
this.agent = ag;
|
this.agent = ag;
|
||||||
this.driverService = driverService;
|
this.driverService = driverService;
|
||||||
|
this.netCfgService = netCfgService;
|
||||||
this.init();
|
this.init();
|
||||||
this.run();
|
this.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -36,6 +37,7 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import org.onlab.packet.IpAddress;
|
import org.onlab.packet.IpAddress;
|
||||||
import org.onosproject.openflow.controller.Dpid;
|
import org.onosproject.openflow.controller.Dpid;
|
||||||
import org.onosproject.openflow.controller.OpenFlowSession;
|
import org.onosproject.openflow.controller.OpenFlowSession;
|
||||||
@ -86,10 +88,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.handler.ssl.SslHandler;
|
||||||
import io.netty.handler.timeout.IdleStateEvent;
|
import io.netty.handler.timeout.IdleStateEvent;
|
||||||
import io.netty.handler.timeout.ReadTimeoutException;
|
import io.netty.handler.timeout.ReadTimeoutException;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Channel handler deals with the switch connection and dispatches
|
* Channel handler deals with the switch connection and dispatches
|
||||||
* switch messages to the appropriate locations.
|
* switch messages to the appropriate locations.
|
||||||
@ -312,7 +317,13 @@ class OFChannelHandler extends ChannelInboundHandlerAdapter
|
|||||||
@Override
|
@Override
|
||||||
void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m)
|
void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
h.thisdpid = m.getDatapathId().getLong();
|
Long dpid = m.getDatapathId().getLong();
|
||||||
|
if (!h.setDpid(dpid, h.channel)) {
|
||||||
|
log.error("Switch presented invalid certificate for dpid {}. Disconnecting",
|
||||||
|
dpid);
|
||||||
|
h.channel.disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
log.debug("Received features reply for switch at {} with dpid {}",
|
log.debug("Received features reply for switch at {} with dpid {}",
|
||||||
h.getSwitchInfoString(), h.thisdpid);
|
h.getSwitchInfoString(), h.thisdpid);
|
||||||
|
|
||||||
@ -1505,6 +1516,25 @@ class OFChannelHandler extends ChannelInboundHandlerAdapter
|
|||||||
this.lastStateChange = System.currentTimeMillis();
|
this.lastStateChange = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean setDpid(Long dpid, Channel channel) {
|
||||||
|
ChannelHandlerContext sslContext = channel.pipeline().context(SslHandler.class);
|
||||||
|
if (sslContext != null) {
|
||||||
|
try {
|
||||||
|
SslHandler sslHandler = (SslHandler) sslContext.handler();
|
||||||
|
Certificate[] certs = sslHandler.engine().getSession().getPeerCertificates();
|
||||||
|
Certificate cert = certs.length > 0 ? certs[0] : null;
|
||||||
|
if (!controller.isValidCertificate(dpid, cert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (SSLPeerUnverifiedException e) {
|
||||||
|
log.info("Switch with dpid {} is an unverified SSL peer.", dpid, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.thisdpid = dpid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send hello message to the switch using the handshake transactions ids.
|
* Send hello message to the switch using the handshake transactions ids.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
|||||||
@ -28,7 +28,12 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
|
|||||||
import org.apache.felix.scr.annotations.Service;
|
import org.apache.felix.scr.annotations.Service;
|
||||||
import org.onosproject.cfg.ComponentConfigService;
|
import org.onosproject.cfg.ComponentConfigService;
|
||||||
import org.onosproject.core.CoreService;
|
import org.onosproject.core.CoreService;
|
||||||
|
import org.onosproject.net.DeviceId;
|
||||||
|
import org.onosproject.net.config.ConfigFactory;
|
||||||
|
import org.onosproject.net.config.NetworkConfigRegistry;
|
||||||
|
import org.onosproject.net.config.basics.SubjectFactories;
|
||||||
import org.onosproject.net.driver.DriverService;
|
import org.onosproject.net.driver.DriverService;
|
||||||
|
import org.onosproject.openflow.config.OpenFlowDeviceConfig;
|
||||||
import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
|
import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
|
||||||
import org.onosproject.openflow.controller.Dpid;
|
import org.onosproject.openflow.controller.Dpid;
|
||||||
import org.onosproject.openflow.controller.OpenFlowController;
|
import org.onosproject.openflow.controller.OpenFlowController;
|
||||||
@ -107,6 +112,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
|
|||||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
protected ComponentConfigService cfgService;
|
protected ComponentConfigService cfgService;
|
||||||
|
|
||||||
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
|
protected NetworkConfigRegistry netCfgService;
|
||||||
|
|
||||||
@Property(name = "openflowPorts", value = DEFAULT_OFPORT,
|
@Property(name = "openflowPorts", value = DEFAULT_OFPORT,
|
||||||
label = "Port numbers (comma separated) used by OpenFlow protocol; default is 6633,6653")
|
label = "Port numbers (comma separated) used by OpenFlow protocol; default is 6633,6653")
|
||||||
private String openflowPorts = DEFAULT_OFPORT;
|
private String openflowPorts = DEFAULT_OFPORT;
|
||||||
@ -173,14 +181,25 @@ public class OpenFlowControllerImpl implements OpenFlowController {
|
|||||||
protected Multimap<Dpid, OFQueueStatsEntry> fullQueueStats =
|
protected Multimap<Dpid, OFQueueStatsEntry> fullQueueStats =
|
||||||
ArrayListMultimap.create();
|
ArrayListMultimap.create();
|
||||||
|
|
||||||
|
protected final ConfigFactory factory =
|
||||||
|
new ConfigFactory<DeviceId, OpenFlowDeviceConfig>(
|
||||||
|
SubjectFactories.DEVICE_SUBJECT_FACTORY,
|
||||||
|
OpenFlowDeviceConfig.class, OpenFlowDeviceConfig.CONFIG_KEY) {
|
||||||
|
@Override
|
||||||
|
public OpenFlowDeviceConfig createConfig() {
|
||||||
|
return new OpenFlowDeviceConfig();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final Controller ctrl = new Controller();
|
private final Controller ctrl = new Controller();
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public void activate(ComponentContext context) {
|
public void activate(ComponentContext context) {
|
||||||
coreService.registerApplication(APP_ID, this::cleanup);
|
coreService.registerApplication(APP_ID, this::cleanup);
|
||||||
cfgService.registerProperties(getClass());
|
cfgService.registerProperties(getClass());
|
||||||
|
netCfgService.registerConfigFactory(factory);
|
||||||
ctrl.setConfigParams(context.getProperties());
|
ctrl.setConfigParams(context.getProperties());
|
||||||
ctrl.start(agent, driverService);
|
ctrl.start(agent, driverService, netCfgService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
@ -197,13 +216,14 @@ public class OpenFlowControllerImpl implements OpenFlowController {
|
|||||||
public void deactivate() {
|
public void deactivate() {
|
||||||
cleanup();
|
cleanup();
|
||||||
cfgService.unregisterProperties(getClass(), false);
|
cfgService.unregisterProperties(getClass(), false);
|
||||||
|
netCfgService.unregisterConfigFactory(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Modified
|
@Modified
|
||||||
public void modified(ComponentContext context) {
|
public void modified(ComponentContext context) {
|
||||||
ctrl.stop();
|
ctrl.stop();
|
||||||
ctrl.setConfigParams(context.getProperties());
|
ctrl.setConfigParams(context.getProperties());
|
||||||
ctrl.start(agent, driverService);
|
ctrl.start(agent, driverService, netCfgService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.onosproject.cfg.ComponentConfigService;
|
import org.onosproject.cfg.ComponentConfigService;
|
||||||
import org.onosproject.core.CoreService;
|
import org.onosproject.core.CoreService;
|
||||||
|
import org.onosproject.net.config.NetworkConfigRegistry;
|
||||||
import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
|
import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
|
||||||
import org.onosproject.openflow.controller.Dpid;
|
import org.onosproject.openflow.controller.Dpid;
|
||||||
import org.onosproject.openflow.controller.OpenFlowSwitch;
|
import org.onosproject.openflow.controller.OpenFlowSwitch;
|
||||||
@ -149,6 +150,9 @@ public class OpenFlowControllerImplTest {
|
|||||||
controller.cfgService = mockConfigService;
|
controller.cfgService = mockConfigService;
|
||||||
replay(mockConfigService);
|
replay(mockConfigService);
|
||||||
|
|
||||||
|
NetworkConfigRegistry netConfigService = EasyMock.createMock(NetworkConfigRegistry.class);
|
||||||
|
controller.netCfgService = netConfigService;
|
||||||
|
|
||||||
ComponentContext mockContext = EasyMock.createMock(ComponentContext.class);
|
ComponentContext mockContext = EasyMock.createMock(ComponentContext.class);
|
||||||
Dictionary<String, Object> properties = new Hashtable<>();
|
Dictionary<String, Object> properties = new Hashtable<>();
|
||||||
properties.put("openflowPorts",
|
properties.put("openflowPorts",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user