Charles Chan
Committed by Gerrit Code Review

[WIP][CORD-200] Improves Segment Routing using Network Configuration Subsystem

DONE
- Remove original configuration subsystem
- Implement new SegmentRoutingConfig
- Update SegmentRoutingManager and DeviceConfiguration

TODO
- Extract adjacencySid array from JsonNode
- Extract subnets and prefixes from port subject

Change-Id: Ic7fec102f4427a30eec99ebf6c7c5584652a6280
/*
* Copyright 2015 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -18,15 +18,13 @@ package org.onosproject.segmentrouting;
import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid;
import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig;
import org.onosproject.segmentrouting.config.NetworkConfigManager;
import org.onosproject.segmentrouting.config.SegmentRouterConfig;
import org.onosproject.segmentrouting.config.SegmentRouterConfig.Subnet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -36,6 +34,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Segment Routing configuration component that reads the
......@@ -50,7 +49,7 @@ public class DeviceConfiguration implements DeviceProperties {
.getLogger(DeviceConfiguration.class);
private final List<Integer> allSegmentIds = new ArrayList<>();
private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
private final NetworkConfigManager configService;
private final NetworkConfigRegistry configService;
private class SegmentRouterInfo {
int nodeSid;
......@@ -60,48 +59,39 @@ public class DeviceConfiguration implements DeviceProperties {
boolean isEdge;
HashMap<PortNumber, Ip4Address> gatewayIps;
HashMap<PortNumber, Ip4Prefix> subnets;
List<SegmentRouterConfig.AdjacencySid> adjacencySids;
List<AdjacencySid> adjacencySids;
}
/**
* Constructor. Reads all the configuration for all devices of type
* Segment Router and organizes into various maps for easier access.
*
* @param configService handle to network configuration manager
* @param cfgService handle to network configuration manager
* component from where the relevant configuration is retrieved.
*/
public DeviceConfiguration(NetworkConfigManager configService) {
this.configService = checkNotNull(configService);
List<SwitchConfig> allSwitchCfg =
this.configService.getConfiguredAllowedSwitches();
for (SwitchConfig cfg : allSwitchCfg) {
if (!(cfg instanceof SegmentRouterConfig)) {
continue;
}
public DeviceConfiguration(NetworkConfigRegistry cfgService) {
this.configService = checkNotNull(cfgService);
Set<DeviceId> subjectSet =
cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class);
subjectSet.forEach(subject -> {
SegmentRoutingConfig config =
cfgService.getConfig(subject, SegmentRoutingConfig.class);
SegmentRouterInfo info = new SegmentRouterInfo();
info.nodeSid = ((SegmentRouterConfig) cfg).getNodeSid();
info.deviceId = cfg.getDpid();
info.mac = MacAddress.valueOf(((
SegmentRouterConfig) cfg).getRouterMac());
String routerIp = ((SegmentRouterConfig) cfg).getRouterIp();
Ip4Prefix prefix = checkNotNull(IpPrefix.valueOf(routerIp).getIp4Prefix());
info.ip = prefix.address();
info.isEdge = ((SegmentRouterConfig) cfg).isEdgeRouter();
info.subnets = new HashMap<>();
info.nodeSid = config.getSid();
info.deviceId = subject;
info.ip = config.getIp();
info.mac = config.getMac();
info.isEdge = config.isEdgeRouter();
// TODO fecth subnet and gateway information via port subject
info.gatewayIps = new HashMap<>();
for (Subnet s: ((SegmentRouterConfig) cfg).getSubnets()) {
info.subnets.put(PortNumber.portNumber(s.getPortNo()),
Ip4Prefix.valueOf(s.getSubnetIp()));
String gatewayIp = s.getSubnetIp().
substring(0, s.getSubnetIp().indexOf('/'));
info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()),
Ip4Address.valueOf(gatewayIp));
}
info.adjacencySids = ((SegmentRouterConfig) cfg).getAdjacencySids();
info.subnets = new HashMap<>();
info.adjacencySids = config.getAdjacencySids();
this.deviceConfigMap.put(info.deviceId, info);
this.allSegmentIds.add(info.nodeSid);
}
});
}
/**
......@@ -379,8 +369,8 @@ public class DeviceConfiguration implements DeviceProperties {
*/
public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
if (deviceConfigMap.get(deviceId) != null) {
for (SegmentRouterConfig.AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
if (asid.getAdjSid() == sid) {
for (AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
if (asid.getSid() == sid) {
return asid.getPorts();
}
}
......@@ -402,9 +392,9 @@ public class DeviceConfiguration implements DeviceProperties {
if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
return false;
} else {
for (SegmentRouterConfig.AdjacencySid asid:
for (AdjacencySid asid:
deviceConfigMap.get(deviceId).adjacencySids) {
if (asid.getAdjSid() == sid) {
if (asid.getSid() == sid) {
return true;
}
}
......@@ -414,4 +404,4 @@ public class DeviceConfiguration implements DeviceProperties {
return false;
}
}
}
\ No newline at end of file
......
......@@ -27,6 +27,12 @@ import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.Event;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
import org.onosproject.segmentrouting.grouphandler.NeighborSet;
import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
......@@ -50,7 +56,6 @@ import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.segmentrouting.config.NetworkConfigManager;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapBuilder;
import org.onosproject.store.service.StorageService;
......@@ -133,7 +138,19 @@ public class SegmentRoutingManager implements SegmentRoutingService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
private NetworkConfigManager networkConfigService = new NetworkConfigManager();;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetworkConfigRegistry cfgService;
private final InternalConfigListener cfgListener = new InternalConfigListener();
private final ConfigFactory cfgFactory =
new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY,
SegmentRoutingConfig.class,
"segmentrouting") {
@Override
public SegmentRoutingConfig createConfig() {
return new SegmentRoutingConfig();
}
};
private Object threadSchedulerLock = new Object();
private static int numOfEventsQueued = 0;
......@@ -192,8 +209,10 @@ public class SegmentRoutingManager implements SegmentRoutingService {
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
networkConfigService.init();
deviceConfiguration = new DeviceConfiguration(networkConfigService);
cfgService.addListener(cfgListener);
cfgService.registerConfigFactory(cfgFactory);
deviceConfiguration = new DeviceConfiguration(cfgService);
arpHandler = new ArpHandler(this);
icmpHandler = new IcmpHandler(this);
ipHandler = new IpHandler(this);
......@@ -230,6 +249,9 @@ public class SegmentRoutingManager implements SegmentRoutingService {
@Deactivate
protected void deactivate() {
cfgService.removeListener(cfgListener);
cfgService.unregisterConfigFactory(cfgFactory);
packetService.removeProcessor(processor);
processor = null;
log.info("Stopped");
......@@ -512,6 +534,15 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
}
private class InternalConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
event.configClass().equals(SegmentRoutingConfig.class)) {
// TODO Support dynamic configuration in the future
return;
}
}
}
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.segmentrouting.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Public class corresponding to JSON described data model. Defines the network
* configuration at startup.
*/
public class NetworkConfig {
protected static final Logger log = LoggerFactory.getLogger(NetworkConfig.class);
@SuppressWarnings("unused")
private String comment;
private Boolean restrictSwitches;
private Boolean restrictLinks;
private List<SwitchConfig> switches;
private List<LinkConfig> links;
/**
* Default constructor.
*/
public NetworkConfig() {
switches = new ArrayList<>();
links = new ArrayList<>();
}
@JsonProperty("comment")
public void setComment(String c) {
log.trace("NetworkConfig: comment={}", c);
comment = c;
}
@JsonProperty("restrictSwitches")
public void setRestrictSwitches(boolean rs) {
log.trace("NetworkConfig: restrictSwitches={}", rs);
restrictSwitches = rs;
}
/**
* Returns default restrict configuration for switches.
*
* @return boolean
*/
public Boolean getRestrictSwitches() {
return restrictSwitches;
}
@JsonProperty("restrictLinks")
public void setRestrictLinks(boolean rl) {
log.trace("NetworkConfig: restrictLinks={}", rl);
restrictLinks = rl;
}
/**
* Returns default restrict configuration for links.
*
* @return boolean
*/
public Boolean getRestrictLinks() {
return restrictLinks;
}
/**
* Returns configuration for switches.
*
* @return list of switch configuration
*/
public List<SwitchConfig> getSwitchConfig() {
return switches;
}
@JsonProperty("switchConfig")
public void setSwitchConfig(List<SwitchConfig> switches2) {
log.trace("NetworkConfig: switchConfig={}", switches2);
this.switches = switches2;
}
/**
* Java class corresponding to JSON described switch
* configuration data model.
*/
public static class SwitchConfig {
protected String nodeDpid;
protected String name;
protected String type;
protected boolean allowed;
protected double latitude;
protected double longitude;
protected Map<String, JsonNode> params;
protected Map<String, String> publishAttributes;
protected DeviceId dpid;
/**
* Returns the configured "name" of a switch.
*
* @return string
*/
public String getName() {
return name;
}
@JsonProperty("name")
public void setName(String name) {
log.trace("SwitchConfig: name={}", name);
this.name = name;
}
/**
* Returns the data plane identifier of a switch.
*
* @return ONOS device identifier
*/
public DeviceId getDpid() {
return dpid;
}
public void setDpid(DeviceId dpid) {
this.dpid = dpid;
this.nodeDpid = dpid.toString();
}
/**
* Returns the data plane identifier of a switch.
*
* @return string
*/
public String getNodeDpid() {
return nodeDpid;
}
// mapper sets both DeviceId and string fields for dpid
@JsonProperty("nodeDpid")
public void setNodeDpid(String nodeDpid) {
log.trace("SwitchConfig: nodeDpid={}", nodeDpid);
this.nodeDpid = nodeDpid;
this.dpid = DeviceId.deviceId(nodeDpid);
}
/**
* Returns the type of a switch.
*
* @return string
*/
public String getType() {
return type;
}
@JsonProperty("type")
public void setType(String type) {
log.trace("SwitchConfig: type={}", type);
this.type = type;
}
/**
* Returns the latitude of a switch.
*
* @return double
*/
public double getLatitude() {
return latitude;
}
@JsonProperty("latitude")
public void setLatitude(double latitude) {
log.trace("SwitchConfig: latitude={}", latitude);
this.latitude = latitude;
}
/**
* Returns the longitude of a switch.
*
* @return double
*/
public double getLongitude() {
return longitude;
}
@JsonProperty("longitude")
public void setLongitude(double longitude) {
log.trace("SwitchConfig: longitude={}", longitude);
this.longitude = longitude;
}
/**
* Returns the allowed flag for a switch.
*
* @return boolean
*/
public boolean isAllowed() {
return allowed;
}
@JsonProperty("allowed")
public void setAllowed(boolean allowed) {
this.allowed = allowed;
}
/**
* Returns the additional configured parameters of a switch.
*
* @return key value map
*/
public Map<String, JsonNode> getParams() {
return params;
}
@JsonProperty("params")
public void setParams(Map<String, JsonNode> params) {
this.params = params;
}
/**
* Reserved for future use.
*
* @return key value map
*/
public Map<String, String> getPublishAttributes() {
return publishAttributes;
}
@JsonProperty("publishAttributes")
public void setPublishAttributes(Map<String, String> publishAttributes) {
this.publishAttributes = publishAttributes;
}
}
@JsonProperty("linkConfig")
public void setLinkConfig(List<LinkConfig> links2) {
this.links = links2;
}
/**
* Reserved for future use.
*
* @return list of configured link configuration
*/
public List<LinkConfig> getLinkConfig() {
return links;
}
/**
* Reserved for future use.
*/
public static class LinkConfig {
protected String type;
protected Boolean allowed;
protected DeviceId dpid1;
protected DeviceId dpid2;
protected String nodeDpid1;
protected String nodeDpid2;
protected Map<String, JsonNode> params;
protected Map<String, String> publishAttributes;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Boolean isAllowed() {
return allowed;
}
public void setAllowed(Boolean allowed) {
this.allowed = allowed;
}
public String getNodeDpid1() {
return nodeDpid1;
}
// mapper sets both long and string fields for dpid
public void setNodeDpid1(String nodeDpid1) {
this.nodeDpid1 = nodeDpid1;
this.dpid1 = DeviceId.deviceId(nodeDpid1);
}
public String getNodeDpid2() {
return nodeDpid2;
}
// mapper sets both long and string fields for dpid
public void setNodeDpid2(String nodeDpid2) {
this.nodeDpid2 = nodeDpid2;
this.dpid2 = DeviceId.deviceId(nodeDpid2);
}
public DeviceId getDpid1() {
return dpid1;
}
public void setDpid1(DeviceId dpid1) {
this.dpid1 = dpid1;
this.nodeDpid1 = dpid1.toString();
}
public DeviceId getDpid2() {
return dpid2;
}
public void setDpid2(DeviceId dpid2) {
this.dpid2 = dpid2;
this.nodeDpid2 = dpid2.toString();
}
public Map<String, JsonNode> getParams() {
return params;
}
public void setParams(Map<String, JsonNode> params) {
this.params = params;
}
public Map<String, String> getPublishAttributes() {
return publishAttributes;
}
public void setPublishAttributes(Map<String, String> publishAttributes) {
this.publishAttributes = publishAttributes;
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.segmentrouting.config;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* NetworkConfigExceptions specifies a set of unchecked runtime exceptions that
* can be thrown by the {@link NetworkConfigManager}. It indicates errors that
* must be fixed in the config file before controller execution can proceed.
*/
public class NetworkConfigException extends RuntimeException {
private static final long serialVersionUID = 4959684709803000652L;
protected static final Logger log = LoggerFactory
.getLogger(NetworkConfigException.class);
/**
* Exception for duplicate device identifier configuration.
*/
public static class DuplicateDpid extends RuntimeException {
private static final long serialVersionUID = 5491113234592145335L;
public DuplicateDpid(DeviceId dpid) {
super();
log.error("Duplicate dpid found in switch-config Dpid:{}",
dpid);
}
}
/**
* Exception for duplicate device name configuration.
*/
public static class DuplicateName extends RuntimeException {
private static final long serialVersionUID = -4090171438031376129L;
public DuplicateName(String name) {
super();
log.error("Duplicate name found in switch-config name:{}", name);
}
}
/**
* Exception for unspecified device identifier for a switch.
*/
public static class DpidNotSpecified extends RuntimeException {
private static final long serialVersionUID = -8494418855597117254L;
public DpidNotSpecified(String name) {
super();
log.error("Dpid not specified for switch-config name:{}", name);
}
}
/**
* Exception for unspecified device name for a switch.
*/
public static class NameNotSpecified extends RuntimeException {
private static final long serialVersionUID = -3518881744110422891L;
public NameNotSpecified(DeviceId dpid) {
super();
log.error("Name not specified for switch-config dpid:{}",
dpid);
}
}
/**
* Exception for unspecified device type for a switch.
*/
public static class SwitchTypeNotSpecified extends RuntimeException {
private static final long serialVersionUID = 2527453336226053753L;
public SwitchTypeNotSpecified(DeviceId dpid) {
super();
log.error("Switch type not specified for switch-config dpid:{}",
dpid);
}
}
/**
* Exception for unknown device type configured for a switch.
*/
public static class UnknownSwitchType extends RuntimeException {
private static final long serialVersionUID = 7758418165512249170L;
public UnknownSwitchType(String type, String name) {
super();
log.error("Unknown switch type {} for switch name:{}", type, name);
}
}
/**
* Exception for missing required parameter configuration for a switch.
*/
public static class ParamsNotSpecified extends RuntimeException {
private static final long serialVersionUID = 6247582323691265513L;
public ParamsNotSpecified(String name) {
super();
log.error("Params required - not specified for switch:{}", name);
}
}
/**
* Reserved for future use.
*/
public static class LinkTypeNotSpecified extends RuntimeException {
private static final long serialVersionUID = -2089470389588542215L;
public LinkTypeNotSpecified(String dpid1, String dpid2) {
super();
log.error("Link type not specified for link-config between "
+ "dpid1:{} and dpid2:{}", dpid1, dpid2);
}
}
/**
* Reserved for future use.
*/
public static class LinkDpidNotSpecified extends RuntimeException {
private static final long serialVersionUID = -5701825916378616004L;
public LinkDpidNotSpecified(String dpid1, String dpid2) {
super();
if (dpid1 == null) {
log.error("nodeDpid1 not specified for link-config ");
}
if (dpid2 == null) {
log.error("nodeDpid2 not specified for link-config ");
}
}
}
/**
* Reserved for future use.
*/
public static class LinkForUnknownSwitchConfig extends RuntimeException {
private static final long serialVersionUID = -2910458439881964094L;
public LinkForUnknownSwitchConfig(String dpid) {
super();
log.error("Link configuration was specified for a switch-dpid {} "
+ "that has not been configured", dpid);
}
}
/**
* Reserved for future use.
*/
public static class UnknownLinkType extends RuntimeException {
private static final long serialVersionUID = -5505376193106542305L;
public UnknownLinkType(String linktype, String dpid1, String dpid2) {
super();
log.error("unknown link type {} for links between dpid1:{} "
+ "and dpid2:{}", linktype, dpid1, dpid2);
}
}
/**
* Exception for generic configuration errors.
*/
public static class ErrorConfig extends RuntimeException {
private static final long serialVersionUID = -2827406314700193147L;
public ErrorConfig(String errorMsg) {
super();
log.error(errorMsg);
}
}
/**
* Reserved for future use.
*/
public static class SwitchDpidNotConverted extends RuntimeException {
private static final long serialVersionUID = 5640347104590170426L;
public SwitchDpidNotConverted(String name) {
super();
log.error("Switch dpid specified as a HexString {} does not match "
+ "with long value", name);
}
}
/**
* Reserved for future use.
*/
public static class LinkDpidNotConverted extends RuntimeException {
private static final long serialVersionUID = 2397245646094080774L;
public LinkDpidNotConverted(String dpid1, String dpid2) {
log.error("Dpids expressed as HexStrings for links between dpid1:{} "
+ "and dpid2:{} do not match with long values", dpid1, dpid2);
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.segmentrouting.config;
import java.util.List;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.segmentrouting.config.NetworkConfig.LinkConfig;
import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig;
/**
* Exposes methods to retrieve network configuration.
*
* TODO: currently only startup-configuration is exposed and such configuration
* cannot be changed at runtime. Need to add runtime support for changes to
* configuration (via REST/CLI) in future releases.
*
* TODO: return immutable objects or defensive copies of network config so that
* users of this API do not inadvertently or maliciously change network config.
*
* @deprecated in Drake; see org.onosproject.net.config
*/
@Deprecated
public interface NetworkConfigService {
/**
* Suggests the action to be taken by the caller given the configuration
* associated with the queried network-object (eg. switch, link etc.).
*/
enum NetworkConfigState {
/**
* Associated network object has been configured to not be allowed in
* the network.
*/
DENY,
/**
* Associated network object has been configured to be allowed in the
* network.
*/
ACCEPT,
/**
* Associated network object has been configured to be allowed in the
* network. In addition, there are configured parameters that should be
* added to the object.
*/
ACCEPT_ADD,
}
/**
* Returns the configuration outcome (accept, deny etc.), and any configured
* parameters to the caller, in response to a query for the configuration
* associated with a switch.
*/
class SwitchConfigStatus {
private NetworkConfigState configState;
private SwitchConfig switchConfig;
private String msg;
SwitchConfigStatus(NetworkConfigState configState,
SwitchConfig switchConfig, String msg) {
this.configState = configState;
this.switchConfig = switchConfig;
this.msg = msg;
}
SwitchConfigStatus(NetworkConfigState configState,
SwitchConfig switchConfig) {
this.configState = configState;
this.switchConfig = switchConfig;
this.msg = "";
}
/**
* Returns the configuration state for the switch.
*
* @return non-null NetworkConfigState
*/
public NetworkConfigState getConfigState() {
return configState;
}
/**
* Returns the switch configuration, which may be null if no
* configuration exists, or if the configuration state disallows the
* switch.
*
* @return SwitchConfig, the switch configuration, or null
*/
public SwitchConfig getSwitchConfig() {
return switchConfig;
}
/**
* User readable string typically used to specify the reason why a
* switch is being disallowed.
*
* @return A non-null but possibly empty String
*/
public String getMsg() {
return msg;
}
}
/**
* Reserved for future use.
*
* Returns the configuration outcome (accept, deny etc.), and any configured
* parameters to the caller, in response to a query for the configuration
* associated with a link.
*/
class LinkConfigStatus {
private NetworkConfigState configState;
private LinkConfig linkConfig;
private String msg;
LinkConfigStatus(NetworkConfigState configState,
LinkConfig linkConfig, String msg) {
this.configState = configState;
this.linkConfig = linkConfig;
this.msg = msg;
}
LinkConfigStatus(NetworkConfigState configState,
LinkConfig linkConfig) {
this.configState = configState;
this.linkConfig = linkConfig;
this.msg = "";
}
/**
* Returns the configuration state for the link.
*
* @return non-null NetworkConfigState
*/
public NetworkConfigState getConfigState() {
return configState;
}
/**
* Returns the link configuration, which may be null if no configuration
* exists, or if the configuration state disallows the link.
*
* @return SwitchConfig, the switch configuration, or null
*/
public LinkConfig getLinkConfig() {
return linkConfig;
}
/**
* User readable string typically used to specify the reason why a link
* is being disallowed.
*
* @return msg A non-null but possibly empty String
*/
public String getMsg() {
return msg;
}
}
/**
* Checks the switch configuration (if any) associated with the 'dpid'.
* Determines if the switch should be allowed or denied according to
* configuration rules.
*
* The method always returns a non-null SwitchConfigStatus. The enclosed
* ConfigState contains the result of the check. The enclosed SwitchConfig
* may or may not be null, depending on the outcome of the check.
*
* @param dpid device id of the switch to be queried
* @return SwitchConfigStatus with outcome of check and associated config.
*/
SwitchConfigStatus checkSwitchConfig(DeviceId dpid);
/**
* Reserved for future use.
*
* Checks the link configuration (if any) associated with the 'link'.
* Determines if the link should be allowed or denied according to
* configuration rules. Note that the 'link' is a unidirectional link which
* checked against configuration that is typically defined for a
* bidirectional link. The caller may make a second call if it wishes to
* check the 'reverse' direction.
*
* Also note that the configuration may not specify ports for a given
* bidirectional link. In such cases, the configuration applies to all links
* between the two switches. This method will check the given 'link' against
* such configuration.
* The method always returns a non-null LinkConfigStatus. The enclosed
* ConfigState contains the result of the check. The enclosed LinkConfig may
* or may not be null, depending on the outcome of the check.
*
* @param linkTuple unidirectional link to be queried
* @return LinkConfigStatus with outcome of check and associated config.
*/
LinkConfigStatus checkLinkConfig(Link linkTuple);
/**
* Retrieves a list of switches that have been configured, and have been
* determined to be 'allowed' in the network, according to configuration
* rules.
*
* Note that it is possible that there are other switches that are allowed
* in the network that have NOT been configured. Such switches will not be a
* part of the returned list.
*
* Also note that it is possible that some switches will not be discovered
* and the only way the controller can know about these switches is via
* configuration. Such switches will be included in this list. It is up to
* the caller to determine which SwitchConfig applies to non-discovered
* switches.
*
* @return a non-null List of SwitchConfig which may be empty
*/
List<SwitchConfig> getConfiguredAllowedSwitches();
/**
* Reserved for future use.
*
* Retrieves a list of links that have been configured, and have been
* determined to be 'allowed' in the network, according to configuration
* rules.
*
* Note that it is possible that there are other links that are allowed in
* the network that have NOT been configured. Such links will not be a part
* of the returned list.
*
* Also note that it is possible that some links will not be discovered and
* the only way the controller can know about these links is via
* configuration. Such links will be included in this list. It is up to the
* caller to determine which LinkConfig applies to non-discovered links.
*
* In addition, note that the LinkConfig applies to the configured
* bi-directional link, which may or may not have declared ports. The
* associated unidirectional LinkTuple can be retrieved from the
* getLinkTupleList() method in the LinkConfig object.
*
* @return a non-null List of LinkConfig which may be empty
*/
List<LinkConfig> getConfiguredAllowedLinks();
/**
* Retrieves the Dpid associated with a 'name' for a configured switch
* object. This method does not check of the switches are 'allowed' by
* config.
*
* @param name device name
* @return the Dpid corresponding to a given 'name', or null if no
* configured switch was found for the given 'name'.
*/
DeviceId getDpidForName(String name);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.segmentrouting.config;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.onosproject.net.Link;
import org.onosproject.segmentrouting.config.NetworkConfig.LinkConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Reserved for future use.
* Configuration for a link between two packet-switches.
*/
public class PktLinkConfig extends LinkConfig {
protected static final Logger log = LoggerFactory
.getLogger(PktLinkConfig.class);
private int port1;
private int port2;
private String nodeName1;
private String nodeName2;
private List<Link> linkTupleList;
public PktLinkConfig(LinkConfig lkc) {
nodeDpid1 = lkc.getNodeDpid1();
nodeDpid2 = lkc.getNodeDpid2();
dpid1 = lkc.getDpid1();
dpid2 = lkc.getDpid2();
type = lkc.getType();
allowed = lkc.isAllowed();
params = lkc.getParams();
publishAttributes = new ConcurrentHashMap<>();
parseParams();
validateParams();
setPublishAttributes();
}
// ********************
// Packet Link Configuration
// ********************
public int getPort1() {
return port1;
}
public void setPort1(int port1) {
this.port1 = port1;
}
public int getPort2() {
return port2;
}
public void setPort2(int port2) {
this.port2 = port2;
}
public String getNodeName1() {
return nodeName1;
}
public void setNodeName1(String nodeName1) {
this.nodeName1 = nodeName1;
}
public String getNodeName2() {
return nodeName2;
}
public void setNodeName2(String nodeName2) {
this.nodeName2 = nodeName2;
}
/**
* Returns the two unidirectional links corresponding to the packet-link
* configuration. It is possible that the ports in the LinkTuple have
* portnumber '0', implying that the configuration applies to all links
* between the two switches.
*
* @return a list of LinkTuple with exactly 2 unidirectional links
*/
public List<Link> getLinkTupleList() {
return linkTupleList;
}
private void setPublishAttributes() {
}
private void parseParams() {
if (params == null) {
throw new PktLinkParamsNotSpecified(nodeDpid1, nodeDpid2);
}
Set<Entry<String, JsonNode>> m = params.entrySet();
for (Entry<String, JsonNode> e : m) {
String key = e.getKey();
JsonNode j = e.getValue();
if (key.equals("nodeName1")) {
setNodeName1(j.asText());
} else if (key.equals("nodeName2")) {
setNodeName2(j.asText());
} else if (key.equals("port1")) {
setPort1(j.asInt());
} else if (key.equals("port2")) {
setPort2(j.asInt());
} else {
throw new UnknownPktLinkConfig(key, nodeDpid1, nodeDpid2);
}
}
}
private void validateParams() {
// TODO - wrong-names, duplicate links,
// duplicate use of port, is switch-allowed for which link is allowed?
// valid port numbers
}
public static class PktLinkParamsNotSpecified extends RuntimeException {
private static final long serialVersionUID = 6247582323691265513L;
public PktLinkParamsNotSpecified(String dpidA, String dpidB) {
super();
log.error("Params required for packet link - not specified "
+ "for link between switch1:{} and switch2:{}",
dpidA, dpidB);
}
}
public static class UnknownPktLinkConfig extends RuntimeException {
private static final long serialVersionUID = -5750132094884129179L;
public UnknownPktLinkConfig(String key, String dpidA, String dpidB) {
super();
log.error("Unknown packet-link config {} for link between"
+ " dpid1: {} and dpid2: {}", key,
dpidA, dpidB);
}
}
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* 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.segmentrouting.config;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.basics.BasicElementConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Configuration object for Segment Routing Application.
*/
public class SegmentRoutingConfig extends Config<DeviceId> {
private static final String NAME = "name";
private static final String IP = "routerIp";
private static final String MAC = "routerMac";
private static final String SID = "nodeSid";
private static final String EDGE = "isEdgeRouter";
public Optional<String> getName() {
String name = get(NAME, null);
return name != null ? Optional.of(name) : Optional.empty();
}
public BasicElementConfig setName(String name) {
return (BasicElementConfig) setOrClear(NAME, name);
}
public Ip4Address getIp() {
String ip = get(IP, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
}
public BasicElementConfig setIp(String ip) {
return (BasicElementConfig) setOrClear(IP, ip);
}
public MacAddress getMac() {
String mac = get(MAC, null);
return mac != null ? MacAddress.valueOf(mac) : null;
}
public BasicElementConfig setMac(String mac) {
return (BasicElementConfig) setOrClear(MAC, mac);
}
public int getSid() {
return get(SID, -1);
}
public BasicElementConfig setSid(int sid) {
return (BasicElementConfig) setOrClear(SID, sid);
}
public boolean isEdgeRouter() {
return get(EDGE, false);
}
public BasicElementConfig setEdgeRouter(boolean isEdgeRouter) {
return (BasicElementConfig) setOrClear(EDGE, isEdgeRouter);
}
// TODO extract array from JsonNode
public List<AdjacencySid> getAdjacencySids() {
return new ArrayList<AdjacencySid>();
}
public class AdjacencySid {
int sid;
List<Integer> ports;
public AdjacencySid(int sid, List<Integer> ports) {
this.sid = sid;
this.ports = ports;
}
public int getSid() {
return sid;
}
public List<Integer> getPorts() {
return ports;
}
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......
/*
* Copyright 2015 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......