From 8f92448e4f2f5d9c98036097bdabd1c40166908a Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Sat, 7 Nov 2015 09:43:53 -0800 Subject: Updated ONOS sources to commit ID 3f28c6803193d493b636dd3c43e08a3e6b35acca Change-Id: I08d1eb7ee31b38491b046933c502894d133b2a2d Signed-off-by: Ashlee Young --- .../org/onosproject/pim/impl/PIMInterface.java | 2 + .../org/onosproject/segmentrouting/ArpHandler.java | 15 +- .../segmentrouting/DefaultRoutingHandler.java | 23 +- .../segmentrouting/DeviceConfiguration.java | 488 --------------------- .../onosproject/segmentrouting/IcmpHandler.java | 10 +- .../org/onosproject/segmentrouting/IpHandler.java | 12 +- .../onosproject/segmentrouting/PolicyHandler.java | 1 + .../segmentrouting/RoutingRulePopulator.java | 79 +++- .../segmentrouting/SegmentRoutingManager.java | 51 ++- .../onosproject/segmentrouting/TunnelHandler.java | 1 + .../config/DeviceConfigNotFoundException.java | 32 ++ .../segmentrouting/config/DeviceConfiguration.java | 454 +++++++++++++++++++ .../segmentrouting/config/DeviceProperties.java | 96 ++++ .../grouphandler/DefaultEdgeGroupHandler.java | 1 + .../grouphandler/DefaultGroupHandler.java | 71 ++- .../grouphandler/DefaultTransitGroupHandler.java | 12 +- .../grouphandler/DeviceProperties.java | 75 ---- .../grouphandler/PolicyGroupHandler.java | 30 +- .../onosproject/vtnweb/web/PortChainCodecTest.java | 95 ++++ .../vtnweb/web/PortPairGroupCodecTest.java | 93 ++++ .../org/onosproject/vtnweb/web/portChain.json | 14 + .../org/onosproject/vtnweb/web/portPairGroup.json | 10 + 22 files changed, 1044 insertions(+), 621 deletions(-) delete mode 100644 framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java create mode 100644 framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java create mode 100644 framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java create mode 100644 framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java delete mode 100644 framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json (limited to 'framework/src/onos/apps') diff --git a/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java index 28d1e8ba..5da5c2b3 100644 --- a/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java +++ b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java @@ -65,6 +65,8 @@ public class PIMInterface { /** * Create a PIMInterface. + * + * @param intf the network interface configuration */ public PIMInterface(Interface intf) { diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java index 36563f01..96c85ba8 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java @@ -31,6 +31,8 @@ import org.onosproject.net.packet.DefaultOutboundPacket; import org.onosproject.net.packet.InboundPacket; import org.onosproject.net.HostId; import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -140,9 +142,16 @@ public class ArpHandler { * @param inPort in-port */ public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) { - - byte[] senderMacAddress = config.getDeviceMac(deviceId).toBytes(); - byte[] senderIpAddress = config.getRouterIp(deviceId).toOctets(); + byte[] senderMacAddress; + byte[] senderIpAddress; + + try { + senderMacAddress = config.getDeviceMac(deviceId).toBytes(); + senderIpAddress = config.getRouterIp(deviceId).toOctets(); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting sendArpRequest."); + return; + } ARP arpRequest = new ARP(); arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET) diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java index c4a91c75..a737339f 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java @@ -23,6 +23,8 @@ import org.onlab.packet.IpPrefix; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -449,7 +451,20 @@ public class DefaultRoutingHandler { // If both target switch and dest switch are edge routers, then set IP // rule for both subnet and router IP. - if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { + boolean targetIsEdge; + boolean destIsEdge; + Ip4Address destRouterIp; + + try { + targetIsEdge = config.isEdgeDevice(targetSw); + destIsEdge = config.isEdgeDevice(destSw); + destRouterIp = config.getRouterIp(destSw); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateEcmpRoutingRulePartial."); + return false; + } + + if (targetIsEdge && destIsEdge) { Set subnets = config.getSubnets(destSw); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", targetSw, destSw, subnets); @@ -461,7 +476,7 @@ public class DefaultRoutingHandler { return false; } - Ip4Address routerIp = config.getRouterIp(destSw); + Ip4Address routerIp = destRouterIp; IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", targetSw, destSw, routerIpPrefix); @@ -471,8 +486,8 @@ public class DefaultRoutingHandler { } // If the target switch is an edge router, then set IP rules for the router IP. - } else if (config.isEdgeDevice(targetSw)) { - Ip4Address routerIp = config.getRouterIp(destSw); + } else if (targetIsEdge) { + Ip4Address routerIp = destRouterIp; IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", targetSw, destSw, routerIpPrefix); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java deleted file mode 100644 index 828c51ce..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * 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; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onosproject.incubator.net.config.basics.ConfigException; -import org.onosproject.incubator.net.config.basics.InterfaceConfig; -import org.onosproject.incubator.net.intf.Interface; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.host.InterfaceIpAddress; -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.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Segment Routing configuration component that reads the - * segment routing related configuration from Network Configuration Manager - * component and organizes in more accessible formats. - */ -public class DeviceConfiguration implements DeviceProperties { - - private static final Logger log = LoggerFactory - .getLogger(DeviceConfiguration.class); - private final List allSegmentIds = new ArrayList<>(); - private final ConcurrentHashMap deviceConfigMap - = new ConcurrentHashMap<>(); - - private class SegmentRouterInfo { - int nodeSid; - DeviceId deviceId; - Ip4Address ip; - MacAddress mac; - boolean isEdge; - HashMap gatewayIps; - HashMap subnets; - List adjacencySids; - - public SegmentRouterInfo() { - this.gatewayIps = new HashMap<>(); - this.subnets = new HashMap<>(); - } - } - - /** - * Constructor. Reads all the configuration for all devices of type - * Segment Router and organizes into various maps for easier access. - * - * @param cfgService config service - */ - public DeviceConfiguration(NetworkConfigRegistry cfgService) { - // Read config from device subject, excluding gatewayIps and subnets. - Set deviceSubjects = - cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class); - deviceSubjects.forEach(subject -> { - SegmentRoutingConfig config = - cfgService.getConfig(subject, SegmentRoutingConfig.class); - SegmentRouterInfo info = new SegmentRouterInfo(); - info.deviceId = subject; - info.nodeSid = config.getSid(); - info.ip = config.getIp(); - info.mac = config.getMac(); - info.isEdge = config.isEdgeRouter(); - info.adjacencySids = config.getAdjacencySids(); - - this.deviceConfigMap.put(info.deviceId, info); - this.allSegmentIds.add(info.nodeSid); - }); - - // Read gatewayIps and subnets from port subject. - Set portSubjects = - cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class); - portSubjects.forEach(subject -> { - InterfaceConfig config = - cfgService.getConfig(subject, InterfaceConfig.class); - Set networkInterfaces; - try { - networkInterfaces = config.getInterfaces(); - } catch (ConfigException e) { - log.error("Error loading port configuration"); - return; - } - networkInterfaces.forEach(networkInterface -> { - DeviceId dpid = networkInterface.connectPoint().deviceId(); - PortNumber port = networkInterface.connectPoint().port(); - SegmentRouterInfo info = this.deviceConfigMap.get(dpid); - - // skip if there is no corresponding device for this ConenctPoint - if (info != null) { - Set interfaceAddresses = networkInterface.ipAddresses(); - interfaceAddresses.forEach(interfaceAddress -> { - info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); - info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); - }); - } - }); - - }); - } - - /** - * Returns the Node segment id of a segment router. - * - * @param deviceId device identifier - * @return segment id - */ - @Override - public int getSegmentId(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid); - return srinfo.nodeSid; - } else { - log.warn("getSegmentId for device {} " - + "throwing IllegalStateException " - + "because device does not exist in config", deviceId); - throw new IllegalStateException(); - } - } - - /** - * Returns the Node segment id of a segment router given its Router mac address. - * - * @param routerMac router mac address - * @return node segment id, or -1 if not found in config - */ - public int getSegmentId(MacAddress routerMac) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().mac.equals(routerMac)) { - return entry.getValue().nodeSid; - } - } - - return -1; - } - - /** - * Returns the Node segment id of a segment router given its Router ip address. - * - * @param routerAddress router ip address - * @return node segment id, or -1 if not found in config - */ - public int getSegmentId(Ip4Address routerAddress) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().ip.equals(routerAddress)) { - return entry.getValue().nodeSid; - } - } - - return -1; - } - - /** - * Returns the router mac of a segment router. - * - * @param deviceId device identifier - * @return router mac address - */ - @Override - public MacAddress getDeviceMac(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac); - return srinfo.mac; - } else { - log.warn("getDeviceMac for device {} " - + "throwing IllegalStateException " - + "because device does not exist in config", deviceId); - throw new IllegalStateException(); - } - } - - /** - * Returns the router ip address of a segment router. - * - * @param deviceId device identifier - * @return router ip address - */ - public Ip4Address getRouterIp(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip); - return srinfo.ip; - } else { - log.warn("getRouterIp for device {} " - + "throwing IllegalStateException " - + "because device does not exist in config", deviceId); - throw new IllegalStateException(); - } - } - - /** - * Indicates if the segment router is a edge router or - * a core/backbone router. - * - * @param deviceId device identifier - * @return boolean - */ - @Override - public boolean isEdgeDevice(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge); - return srinfo.isEdge; - } else { - log.warn("isEdgeDevice for device {} " - + "throwing IllegalStateException " - + "because device does not exist in config", deviceId); - throw new IllegalStateException(); - } - } - - /** - * Returns the node segment ids of all configured segment routers. - * - * @return list of node segment ids - */ - @Override - public List getAllDeviceSegmentIds() { - return allSegmentIds; - } - - @Override - public Map> getSubnetPortsMap(DeviceId deviceId) { - Map> subnetPortMap = new HashMap<>(); - - // Construct subnet-port mapping from port-subnet mapping - Map portSubnetMap = - this.deviceConfigMap.get(deviceId).subnets; - portSubnetMap.forEach((port, subnet) -> { - if (subnetPortMap.containsKey(subnet)) { - subnetPortMap.get(subnet).add(port); - } else { - ArrayList ports = new ArrayList<>(); - ports.add(port); - subnetPortMap.put(subnet, ports); - } - }); - - return subnetPortMap; - } - - /** - * Returns the device identifier or data plane identifier (dpid) - * of a segment router given its segment id. - * - * @param sid segment id - * @return deviceId device identifier - */ - public DeviceId getDeviceId(int sid) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().nodeSid == sid) { - return entry.getValue().deviceId; - } - } - - return null; - } - - /** - * Returns the device identifier or data plane identifier (dpid) - * of a segment router given its router ip address. - * - * @param ipAddress router ip address - * @return deviceId device identifier - */ - public DeviceId getDeviceId(Ip4Address ipAddress) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().ip.equals(ipAddress)) { - return entry.getValue().deviceId; - } - } - - return null; - } - - /** - * Returns the configured port ip addresses for a segment router. - * These addresses serve as gateway IP addresses for the subnets configured - * on those ports. - * - * @param deviceId device identifier - * @return immutable set of ip addresses configured on the ports or null if not found - */ - public Set getPortIPs(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSubnetGatewayIps for device{} is {}", deviceId, - srinfo.gatewayIps.values()); - return ImmutableSet.copyOf(srinfo.gatewayIps.values()); - } - return null; - } - - /** - * Returns the configured IP addresses per port - * for a segment router. - * - * @param deviceId device identifier - * @return map of port to gateway IP addresses or null if not found - */ - public Map getPortIPMap(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - return srinfo.gatewayIps; - } - return null; - } - - /** - * Returns the configured subnet prefixes for a segment router. - * - * @param deviceId device identifier - * @return list of ip prefixes or null if not found - */ - public Set getSubnets(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSubnets for device{} is {}", deviceId, - srinfo.subnets.values()); - return ImmutableSet.copyOf(srinfo.subnets.values()); - } - return null; - } - - /** - * Returns the configured subnet on the given port, or null if no - * subnet has been configured on the port. - * - * @param deviceId device identifier - * @param pnum port identifier - * @return configured subnet on port, or null - */ - public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - return srinfo.subnets.get(pnum); - } - return null; - } - - /** - * Returns the router ip address of segment router that has the - * specified ip address in its subnets. - * - * @param destIpAddress target ip address - * @return router ip address - */ - public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - for (Ip4Prefix prefix:entry.getValue().subnets.values()) { - if (prefix.contains(destIpAddress)) { - return entry.getValue().ip; - } - } - } - - log.debug("No router was found for {}", destIpAddress); - return null; - } - - /** - * Returns the router mac address of segment router that has the - * specified ip address as one of its subnet gateway ip address. - * - * @param gatewayIpAddress router gateway ip address - * @return router mac address or null if not found - */ - public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) { - for (Map.Entry entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().gatewayIps. - values().contains(gatewayIpAddress)) { - return entry.getValue().mac; - } - } - - log.debug("Cannot find a router for {}", gatewayIpAddress); - return null; - } - - - /** - * Checks if the host is in the subnet defined in the router with the - * device ID given. - * - * @param deviceId device identification of the router - * @param hostIp host IP address to check - * @return true if the host is within the subnet of the router, - * false if no subnet is defined under the router or if the host is not - * within the subnet defined in the router - */ - public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) { - - Set subnets = getSubnets(deviceId); - if (subnets == null) { - return false; - } - - for (Ip4Prefix subnet: subnets) { - if (subnet.contains(hostIp)) { - return true; - } - } - - return false; - } - - /** - * Returns the ports corresponding to the adjacency Sid given. - * - * @param deviceId device identification of the router - * @param sid adjacency Sid - * @return list of port numbers - */ - public List getPortsForAdjacencySid(DeviceId deviceId, int sid) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - for (AdjacencySid asid : srinfo.adjacencySids) { - if (asid.getAsid() == sid) { - return asid.getPorts(); - } - } - } - - return Lists.newArrayList(); - } - - /** - * Check if the Sid given is whether adjacency Sid of the router device or not. - * - * @param deviceId device identification of the router - * @param sid Sid to check - * @return true if the Sid given is the adjacency Sid of the device, - * otherwise false - */ - public boolean isAdjacencySid(DeviceId deviceId, int sid) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - if (srinfo.adjacencySids.isEmpty()) { - return false; - } else { - for (AdjacencySid asid: - srinfo.adjacencySids) { - if (asid.getAsid() == sid) { - return true; - } - } - return false; - } - } - - return false; - } -} \ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java index b3916b06..c4267ebb 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java @@ -28,6 +28,8 @@ import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.packet.DefaultOutboundPacket; import org.onosproject.net.packet.InboundPacket; import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,7 +73,13 @@ public class IcmpHandler { Ip4Address destinationAddress = Ip4Address.valueOf(ipv4.getDestinationAddress()); Set gatewayIpAddresses = config.getPortIPs(deviceId); - Ip4Address routerIp = config.getRouterIp(deviceId); + Ip4Address routerIp; + try { + routerIp = config.getRouterIp(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting processPacketIn."); + return; + } IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address(); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java index 14ce679b..b1682e77 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java @@ -26,6 +26,8 @@ import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.packet.DefaultOutboundPacket; import org.onosproject.net.packet.InboundPacket; import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -127,13 +129,19 @@ public class IpHandler { for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) { Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress()); - if (ipPacket != null && config.inSameSubnet(deviceId, destAddress)) { + if (config.inSameSubnet(deviceId, destAddress)) { ipPacket.setTtl((byte) (ipPacket.getTtl() - 1)); ipPacket.setChecksum((short) 0); for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) { Ethernet eth = new Ethernet(); eth.setDestinationMACAddress(dest.mac()); - eth.setSourceMACAddress(config.getDeviceMac(deviceId)); + try { + eth.setSourceMACAddress(config.getDeviceMac(deviceId)); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + + " Skipping forwardPackets for this destination."); + continue; + } eth.setEtherType(Ethernet.TYPE_IPV4); eth.setPayload(ipPacket); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java index 83cb7e86..0a4c26d9 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java @@ -27,6 +27,7 @@ import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flowobjective.DefaultForwardingObjective; import org.onosproject.net.flowobjective.FlowObjectiveService; import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.onosproject.store.service.EventuallyConsistentMap; import org.slf4j.Logger; diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java index d46028e7..f8274038 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java @@ -22,6 +22,8 @@ import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.MplsLabel; import org.onlab.packet.VlanId; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.onosproject.segmentrouting.grouphandler.NeighborSet; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; @@ -103,6 +105,14 @@ public class RoutingRulePopulator { */ public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, MacAddress hostMac, PortNumber outPort) { + MacAddress deviceMac; + try { + deviceMac = config.getDeviceMac(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateIpRuleForHost."); + return; + } + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); @@ -111,7 +121,7 @@ public class RoutingRulePopulator { tbuilder.deferred() .setEthDst(hostMac) - .setEthSrc(config.getDeviceMac(deviceId)) + .setEthSrc(deviceMac) .setOutput(outPort); TrafficTreatment treatment = tbuilder.build(); @@ -167,6 +177,13 @@ public class RoutingRulePopulator { public boolean populateIpRuleForRouter(DeviceId deviceId, IpPrefix ipPrefix, DeviceId destSw, Set nextHops) { + int segmentId; + try { + segmentId = config.getSegmentId(destSw); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateIpRuleForRouter."); + return false; + } TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); @@ -183,7 +200,7 @@ public class RoutingRulePopulator { ns = new NeighborSet(nextHops); } else { tbuilder.deferred().copyTtlOut(); - ns = new NeighborSet(nextHops, config.getSegmentId(destSw)); + ns = new NeighborSet(nextHops, segmentId); } TrafficTreatment treatment = tbuilder.build(); @@ -227,19 +244,26 @@ public class RoutingRulePopulator { */ public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, Set nextHops) { + int segmentId; + try { + segmentId = config.getSegmentId(destSwId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateMplsRule."); + return false; + } TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); List fwdObjBuilders = new ArrayList<>(); // TODO Handle the case of Bos == false - sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId))); + sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId)); sbuilder.matchEthType(Ethernet.MPLS_UNICAST); // If the next hop is the destination router, do PHP if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { log.debug("populateMplsRule: Installing MPLS forwarding objective for " + "label {} in switch {} with PHP", - config.getSegmentId(destSwId), + segmentId, deviceId); ForwardingObjective.Builder fwdObjBosBuilder = @@ -264,7 +288,7 @@ public class RoutingRulePopulator { } else { log.debug("Installing MPLS forwarding objective for " + "label {} in switch {} without PHP", - config.getSegmentId(destSwId), + segmentId, deviceId); ForwardingObjective.Builder fwdObjBosBuilder = @@ -310,9 +334,21 @@ public class RoutingRulePopulator { Set nextHops, boolean phpRequired, boolean isBos) { - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective .builder().withFlag(ForwardingObjective.Flag.SPECIFIC); + DeviceId nextHop = (DeviceId) nextHops.toArray()[0]; + + boolean isEdge; + MacAddress srcMac; + MacAddress dstMac; + try { + isEdge = config.isEdgeDevice(deviceId); + srcMac = config.getDeviceMac(deviceId); + dstMac = config.getDeviceMac(nextHop); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting getMplsForwardingObjective"); + return null; + } TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); @@ -329,16 +365,15 @@ public class RoutingRulePopulator { tbuilder.deferred().decMplsTtl(); } - if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) { + if (!isECMPSupportedInTransitRouter() && !isEdge) { PortNumber port = selectOnePort(deviceId, nextHops); - DeviceId nextHop = (DeviceId) nextHops.toArray()[0]; if (port == null) { log.warn("No link from {} to {}", deviceId, nextHops); return null; } tbuilder.deferred() - .setEthSrc(config.getDeviceMac(deviceId)) - .setEthDst(config.getDeviceMac(nextHop)) + .setEthSrc(srcMac) + .setEthDst(dstMac) .setOutput(port); fwdBuilder.withTreatment(tbuilder.build()); } else { @@ -372,15 +407,27 @@ public class RoutingRulePopulator { public void populateRouterMacVlanFilters(DeviceId deviceId) { log.debug("Installing per-port filtering objective for untagged " + "packets in device {}", deviceId); + + MacAddress deviceMac; + try { + deviceMac = config.getDeviceMac(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters."); + return; + } + for (Port port : srManager.deviceService.getPorts(deviceId)) { if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); VlanId assignedVlan = (portSubnet == null) ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET) : srManager.getSubnetAssignedVlanId(deviceId, portSubnet); + + + FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); fob.withKey(Criteria.matchInPort(port.number())) - .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId))) + .addCondition(Criteria.matchEthDst(deviceMac)) .addCondition(Criteria.matchVlanId(VlanId.NONE)); // vlan assignment is valid only if this instance is master if (srManager.mastershipService.isLocalMaster(deviceId)) { @@ -405,6 +452,14 @@ public class RoutingRulePopulator { * @param deviceId the switch dpid for the router */ public void populateRouterIpPunts(DeviceId deviceId) { + Ip4Address routerIp; + try { + routerIp = config.getRouterIp(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting populateRouterIpPunts."); + return; + } + if (!srManager.mastershipService.isLocalMaster(deviceId)) { log.debug("Not installing port-IP punts - not the master for dev:{} ", deviceId); @@ -412,7 +467,7 @@ public class RoutingRulePopulator { } ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder(); Set allIps = new HashSet(config.getPortIPs(deviceId)); - allIps.add(config.getRouterIp(deviceId)); + allIps.add(routerIp); for (Ip4Address ipaddr : allIps) { TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java index b82752d6..787f9347 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java @@ -38,6 +38,8 @@ 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.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.onosproject.segmentrouting.config.SegmentRoutingConfig; import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; import org.onosproject.segmentrouting.grouphandler.NeighborSet; @@ -553,7 +555,10 @@ public class SegmentRoutingManager implements SegmentRoutingService { private void processLinkAdded(Link link) { log.debug("A new link {} was added", link.toString()); - + if (!deviceConfiguration.isConfigured(link.src().deviceId())) { + log.warn("Source device of this link is not configured."); + return; + } //Irrespective whether the local is a MASTER or not for this device, //create group handler instance and push default TTP flow rules. //Because in a multi-instance setup, instances can initiate @@ -596,7 +601,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { private void processDeviceAdded(Device device) { log.debug("A new device with ID {} was added", device.id()); - if (deviceConfiguration == null) { + if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) { log.warn("Device configuration uploading. Device {} will be " + "processed after config completes.", device.id()); return; @@ -608,14 +613,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { // to the switch). To handle this, a default-group-handler instance is necessary // per switch. if (groupHandlerMap.get(device.id()) == null) { - DefaultGroupHandler groupHandler = DefaultGroupHandler. - createGroupHandler(device.id(), - appId, - deviceConfiguration, - linkService, - flowObjectiveService, - nsNextObjStore, - subnetNextObjStore); + DefaultGroupHandler groupHandler; + try { + groupHandler = DefaultGroupHandler. + createGroupHandler(device.id(), + appId, + deviceConfiguration, + linkService, + flowObjectiveService, + nsNextObjStore, + subnetNextObjStore); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting processDeviceAdded."); + return; + } groupHandlerMap.put(device.id(), groupHandler); // Also, in some cases, drivers may need extra // information to process rules (eg. Router IP/MAC); and so, we send @@ -667,12 +678,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { // to the switch). To handle this, a default-group-handler instance is necessary // per switch. if (groupHandlerMap.get(device.id()) == null) { - DefaultGroupHandler groupHandler = DefaultGroupHandler - .createGroupHandler(device.id(), appId, - deviceConfiguration, linkService, - flowObjectiveService, - nsNextObjStore, - subnetNextObjStore); + DefaultGroupHandler groupHandler; + try { + groupHandler = DefaultGroupHandler. + createGroupHandler(device.id(), + appId, + deviceConfiguration, + linkService, + flowObjectiveService, + nsNextObjStore, + subnetNextObjStore); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting configureNetwork."); + return; + } groupHandlerMap.put(device.id(), groupHandler); // Also, in some cases, drivers may need extra diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java index 820bb40a..7d025c72 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java @@ -18,6 +18,7 @@ package org.onosproject.segmentrouting; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.link.LinkService; +import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; import org.onosproject.segmentrouting.grouphandler.NeighborSet; import org.onosproject.store.service.EventuallyConsistentMap; diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java new file mode 100644 index 00000000..ae156e60 --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * Signals that an error occurred during reading device configuration. + */ +public class DeviceConfigNotFoundException extends Exception { + + /** + * Creates a new ConfigNotFoundException with the given message. + * + * @param message exception message + */ + public DeviceConfigNotFoundException(String message) { + super(message); + } +} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java new file mode 100644 index 00000000..0ad00679 --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java @@ -0,0 +1,454 @@ +/* + * 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 com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.MacAddress; +import org.onosproject.incubator.net.config.basics.ConfigException; +import org.onosproject.incubator.net.config.basics.InterfaceConfig; +import org.onosproject.incubator.net.intf.Interface; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.host.InterfaceIpAddress; +import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Segment Routing configuration component that reads the + * segment routing related configuration from Network Configuration Manager + * component and organizes in more accessible formats. + */ +public class DeviceConfiguration implements DeviceProperties { + + private static final Logger log = LoggerFactory + .getLogger(DeviceConfiguration.class); + private final List allSegmentIds = new ArrayList<>(); + private final ConcurrentHashMap deviceConfigMap + = new ConcurrentHashMap<>(); + + private class SegmentRouterInfo { + int nodeSid; + DeviceId deviceId; + Ip4Address ip; + MacAddress mac; + boolean isEdge; + HashMap gatewayIps; + HashMap subnets; + List adjacencySids; + + public SegmentRouterInfo() { + this.gatewayIps = new HashMap<>(); + this.subnets = new HashMap<>(); + } + } + + /** + * Constructor. Reads all the configuration for all devices of type + * Segment Router and organizes into various maps for easier access. + * + * @param cfgService config service + */ + public DeviceConfiguration(NetworkConfigRegistry cfgService) { + // Read config from device subject, excluding gatewayIps and subnets. + Set deviceSubjects = + cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class); + deviceSubjects.forEach(subject -> { + SegmentRoutingConfig config = + cfgService.getConfig(subject, SegmentRoutingConfig.class); + SegmentRouterInfo info = new SegmentRouterInfo(); + info.deviceId = subject; + info.nodeSid = config.getSid(); + info.ip = config.getIp(); + info.mac = config.getMac(); + info.isEdge = config.isEdgeRouter(); + info.adjacencySids = config.getAdjacencySids(); + + this.deviceConfigMap.put(info.deviceId, info); + this.allSegmentIds.add(info.nodeSid); + }); + + // Read gatewayIps and subnets from port subject. + Set portSubjects = + cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class); + portSubjects.forEach(subject -> { + InterfaceConfig config = + cfgService.getConfig(subject, InterfaceConfig.class); + Set networkInterfaces; + try { + networkInterfaces = config.getInterfaces(); + } catch (ConfigException e) { + log.error("Error loading port configuration"); + return; + } + networkInterfaces.forEach(networkInterface -> { + DeviceId dpid = networkInterface.connectPoint().deviceId(); + PortNumber port = networkInterface.connectPoint().port(); + SegmentRouterInfo info = this.deviceConfigMap.get(dpid); + + // skip if there is no corresponding device for this ConenctPoint + if (info != null) { + Set interfaceAddresses = networkInterface.ipAddresses(); + interfaceAddresses.forEach(interfaceAddress -> { + info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); + info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); + }); + } + }); + + }); + } + + @Override + public boolean isConfigured(DeviceId deviceId) { + return deviceConfigMap.get(deviceId) != null; + } + + @Override + public int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid); + return srinfo.nodeSid; + } else { + String message = "getSegmentId fails for device: " + deviceId + "."; + throw new DeviceConfigNotFoundException(message); + } + } + + /** + * Returns the Node segment id of a segment router given its Router mac address. + * + * @param routerMac router mac address + * @return node segment id, or -1 if not found in config + */ + public int getSegmentId(MacAddress routerMac) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + if (entry.getValue().mac.equals(routerMac)) { + return entry.getValue().nodeSid; + } + } + + return -1; + } + + /** + * Returns the Node segment id of a segment router given its Router ip address. + * + * @param routerAddress router ip address + * @return node segment id, or -1 if not found in config + */ + public int getSegmentId(Ip4Address routerAddress) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + if (entry.getValue().ip.equals(routerAddress)) { + return entry.getValue().nodeSid; + } + } + + return -1; + } + + @Override + public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac); + return srinfo.mac; + } else { + String message = "getDeviceMac fails for device: " + deviceId + "."; + throw new DeviceConfigNotFoundException(message); + } + } + + @Override + public Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip); + return srinfo.ip; + } else { + String message = "getRouterIp fails for device: " + deviceId + "."; + throw new DeviceConfigNotFoundException(message); + } + } + + @Override + public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge); + return srinfo.isEdge; + } else { + String message = "isEdgeDevice fails for device: " + deviceId + "."; + throw new DeviceConfigNotFoundException(message); + } + } + + @Override + public List getAllDeviceSegmentIds() { + return allSegmentIds; + } + + @Override + public Map> getSubnetPortsMap(DeviceId deviceId) { + Map> subnetPortMap = new HashMap<>(); + + // Construct subnet-port mapping from port-subnet mapping + Map portSubnetMap = + this.deviceConfigMap.get(deviceId).subnets; + portSubnetMap.forEach((port, subnet) -> { + if (subnetPortMap.containsKey(subnet)) { + subnetPortMap.get(subnet).add(port); + } else { + ArrayList ports = new ArrayList<>(); + ports.add(port); + subnetPortMap.put(subnet, ports); + } + }); + + return subnetPortMap; + } + + /** + * Returns the device identifier or data plane identifier (dpid) + * of a segment router given its segment id. + * + * @param sid segment id + * @return deviceId device identifier + */ + public DeviceId getDeviceId(int sid) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + if (entry.getValue().nodeSid == sid) { + return entry.getValue().deviceId; + } + } + + return null; + } + + /** + * Returns the device identifier or data plane identifier (dpid) + * of a segment router given its router ip address. + * + * @param ipAddress router ip address + * @return deviceId device identifier + */ + public DeviceId getDeviceId(Ip4Address ipAddress) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + if (entry.getValue().ip.equals(ipAddress)) { + return entry.getValue().deviceId; + } + } + + return null; + } + + /** + * Returns the configured port ip addresses for a segment router. + * These addresses serve as gateway IP addresses for the subnets configured + * on those ports. + * + * @param deviceId device identifier + * @return immutable set of ip addresses configured on the ports or null if not found + */ + public Set getPortIPs(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSubnetGatewayIps for device{} is {}", deviceId, + srinfo.gatewayIps.values()); + return ImmutableSet.copyOf(srinfo.gatewayIps.values()); + } + return null; + } + + /** + * Returns the configured IP addresses per port + * for a segment router. + * + * @param deviceId device identifier + * @return map of port to gateway IP addresses or null if not found + */ + public Map getPortIPMap(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + return srinfo.gatewayIps; + } + return null; + } + + /** + * Returns the configured subnet prefixes for a segment router. + * + * @param deviceId device identifier + * @return list of ip prefixes or null if not found + */ + public Set getSubnets(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSubnets for device{} is {}", deviceId, + srinfo.subnets.values()); + return ImmutableSet.copyOf(srinfo.subnets.values()); + } + return null; + } + + /** + * Returns the configured subnet on the given port, or null if no + * subnet has been configured on the port. + * + * @param deviceId device identifier + * @param pnum port identifier + * @return configured subnet on port, or null + */ + public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + return srinfo.subnets.get(pnum); + } + return null; + } + + /** + * Returns the router ip address of segment router that has the + * specified ip address in its subnets. + * + * @param destIpAddress target ip address + * @return router ip address + */ + public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + for (Ip4Prefix prefix:entry.getValue().subnets.values()) { + if (prefix.contains(destIpAddress)) { + return entry.getValue().ip; + } + } + } + + log.debug("No router was found for {}", destIpAddress); + return null; + } + + /** + * Returns the router mac address of segment router that has the + * specified ip address as one of its subnet gateway ip address. + * + * @param gatewayIpAddress router gateway ip address + * @return router mac address or null if not found + */ + public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) { + for (Map.Entry entry: + deviceConfigMap.entrySet()) { + if (entry.getValue().gatewayIps. + values().contains(gatewayIpAddress)) { + return entry.getValue().mac; + } + } + + log.debug("Cannot find a router for {}", gatewayIpAddress); + return null; + } + + + /** + * Checks if the host is in the subnet defined in the router with the + * device ID given. + * + * @param deviceId device identification of the router + * @param hostIp host IP address to check + * @return true if the host is within the subnet of the router, + * false if no subnet is defined under the router or if the host is not + * within the subnet defined in the router + */ + public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) { + + Set subnets = getSubnets(deviceId); + if (subnets == null) { + return false; + } + + for (Ip4Prefix subnet: subnets) { + if (subnet.contains(hostIp)) { + return true; + } + } + + return false; + } + + /** + * Returns the ports corresponding to the adjacency Sid given. + * + * @param deviceId device identification of the router + * @param sid adjacency Sid + * @return list of port numbers + */ + public List getPortsForAdjacencySid(DeviceId deviceId, int sid) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + for (AdjacencySid asid : srinfo.adjacencySids) { + if (asid.getAsid() == sid) { + return asid.getPorts(); + } + } + } + + return Lists.newArrayList(); + } + + /** + * Check if the Sid given is whether adjacency Sid of the router device or not. + * + * @param deviceId device identification of the router + * @param sid Sid to check + * @return true if the Sid given is the adjacency Sid of the device, + * otherwise false + */ + public boolean isAdjacencySid(DeviceId deviceId, int sid) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + if (srinfo.adjacencySids.isEmpty()) { + return false; + } else { + for (AdjacencySid asid: + srinfo.adjacencySids) { + if (asid.getAsid() == sid) { + return true; + } + } + return false; + } + } + + return false; + } +} \ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java new file mode 100644 index 00000000..a39c9567 --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java @@ -0,0 +1,96 @@ +/* + * 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 java.util.List; +import java.util.Map; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; + +/** + * Mechanism through which group handler module retrieves + * the device specific attributes such as segment ID, + * Mac address...etc from group handler applications. + */ +public interface DeviceProperties { + /** + * Checks if the device is configured. + * + * @param deviceId device identifier + * @return true if the device is configured + */ + boolean isConfigured(DeviceId deviceId); + + /** + * Returns the segment id of a device to be used in group creation. + * + * @param deviceId device identifier + * @throws DeviceConfigNotFoundException if the device configuration is not found + * @return segment id of a device + */ + int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException; + + /** + * Returns the Mac address of a device to be used in group creation. + * + * @param deviceId device identifier + * @throws DeviceConfigNotFoundException if the device configuration is not found + * @return mac address of a device + */ + MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException; + + /** + * Returns the router ip address of a segment router. + * + * @param deviceId device identifier + * @throws DeviceConfigNotFoundException if the device configuration is not found + * @return router ip address + */ + Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException; + + /** + * Indicates whether a device is edge device or transit/core device. + * + * @param deviceId device identifier + * @throws DeviceConfigNotFoundException if the device configuration is not found + * @return boolean + */ + boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException; + + /** + * Returns all segment IDs to be considered in building auto + * + * created groups. + * @return list of segment IDs + */ + List getAllDeviceSegmentIds(); + + /** + * Returns subnet-to-ports mapping of given device. + * + * For each entry of the map + * Key: a subnet + * Value: a list of ports, which are bound to the subnet + * + * @param deviceId device identifier + * @return a map that contains all subnet-to-ports mapping of given device + */ + Map> getSubnetPortsMap(DeviceId deviceId); +} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java index a5c1090f..33496bd7 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java @@ -24,6 +24,7 @@ import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.flowobjective.FlowObjectiveService; import org.onosproject.net.link.LinkService; +import org.onosproject.segmentrouting.config.DeviceProperties; import org.onosproject.store.service.EventuallyConsistentMap; /** diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java index 69a0d86f..55b556eb 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java @@ -48,6 +48,8 @@ import org.onosproject.net.flowobjective.ObjectiveError; import org.onosproject.net.group.DefaultGroupKey; import org.onosproject.net.group.GroupKey; import org.onosproject.net.link.LinkService; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceProperties; import org.onosproject.store.service.EventuallyConsistentMap; import org.slf4j.Logger; @@ -63,9 +65,9 @@ public class DefaultGroupHandler { protected final ApplicationId appId; protected final DeviceProperties deviceConfig; protected final List allSegmentIds; - protected final int nodeSegmentId; - protected final boolean isEdgeRouter; - protected final MacAddress nodeMacAddr; + protected int nodeSegmentId = -1; + protected boolean isEdgeRouter = false; + protected MacAddress nodeMacAddr = null; protected LinkService linkService; protected FlowObjectiveService flowObjectiveService; @@ -99,10 +101,15 @@ public class DefaultGroupHandler { this.appId = checkNotNull(appId); this.deviceConfig = checkNotNull(config); this.linkService = checkNotNull(linkService); - allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds()); - nodeSegmentId = config.getSegmentId(deviceId); - isEdgeRouter = config.isEdgeDevice(deviceId); - nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); + this.allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds()); + try { + this.nodeSegmentId = config.getSegmentId(deviceId); + this.isEdgeRouter = config.isEdgeDevice(deviceId); + this.nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + + " Skipping value assignment in DefaultGroupHandler"); + } this.flowObjectiveService = flowObjService; this.nsNextObjStore = nsNextObjStore; this.subnetNextObjStore = subnetNextObjStore; @@ -122,6 +129,7 @@ public class DefaultGroupHandler { * @param flowObjService flow objective service object * @param nsNextObjStore NeighborSet next objective store map * @param subnetNextObjStore subnet next objective store map + * @throws DeviceConfigNotFoundException if the device configuration is not found * @return default group handler type */ public static DefaultGroupHandler createGroupHandler(DeviceId deviceId, @@ -133,7 +141,9 @@ public class DefaultGroupHandler { NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore, EventuallyConsistentMap subnetNextObjStore) { + Integer> subnetNextObjStore) + throws DeviceConfigNotFoundException { + // handle possible exception in the caller if (config.isEdgeDevice(deviceId)) { return new DefaultEdgeGroupHandler(deviceId, appId, config, linkService, @@ -176,6 +186,14 @@ public class DefaultGroupHandler { return; } + MacAddress dstMac; + try { + dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId()); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting linkUp."); + return; + } + log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId, newLink.src().port(), newLink.dst().deviceId()); addNeighborAtPort(newLink.dst().deviceId(), @@ -202,8 +220,7 @@ public class DefaultGroupHandler { TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); tBuilder.setOutput(newLink.src().port()) - .setEthDst(deviceConfig.getDeviceMac( - newLink.dst().deviceId())) + .setEthDst(dstMac) .setEthSrc(nodeMacAddr); if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { tBuilder.pushMpls() @@ -242,6 +259,15 @@ public class DefaultGroupHandler { log.warn("portDown: unknown port"); return; } + + MacAddress dstMac; + try { + dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port)); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting portDown."); + return; + } + log.debug("Device {} portDown {} to neighbor {}", deviceId, port, portDeviceMap.get(port)); /*Set nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap @@ -263,8 +289,8 @@ public class DefaultGroupHandler { TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment .builder(); tBuilder.setOutput(port) - .setEthDst(deviceConfig.getDeviceMac(portDeviceMap - .get(port))).setEthSrc(nodeMacAddr); + .setEthDst(dstMac) + .setEthSrc(nodeMacAddr); if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns .getEdgeLabel())); @@ -432,7 +458,15 @@ public class DefaultGroupHandler { } private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) { - return (deviceConfig.getSegmentId(deviceId) == sId); + int segmentId; + try { + segmentId = deviceConfig.getSegmentId(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting isSegmentIdSameAsNodeSegmentId."); + return false; + } + + return segmentId == sId; } protected List getSegmentIdsTobePairedWithNeighborSet(Set neighbors) { @@ -487,11 +521,19 @@ public class DefaultGroupHandler { return; } + MacAddress deviceMac; + try { + deviceMac = deviceConfig.getDeviceMac(d); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets."); + return; + } + for (PortNumber sp : devicePortMap.get(d)) { TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment .builder(); tBuilder.setOutput(sp) - .setEthDst(deviceConfig.getDeviceMac(d)) + .setEthDst(deviceMac) .setEthSrc(nodeMacAddr); if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns @@ -535,6 +577,7 @@ public class DefaultGroupHandler { ports.forEach(port -> { TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + tBuilder.popVlan(); tBuilder.setOutput(port); nextObjBuilder.addTreatment(tBuilder.build()); }); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java index b009e869..8e1b6a8f 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java @@ -23,6 +23,8 @@ import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.flowobjective.FlowObjectiveService; import org.onosproject.net.link.LinkService; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceProperties; import org.onosproject.store.service.EventuallyConsistentMap; /** @@ -171,7 +173,15 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { if (deviceSubSet.size() > 1) { boolean avoidEdgeRouterPairing = true; for (DeviceId device : deviceSubSet) { - if (!deviceConfig.isEdgeDevice(device)) { + boolean isEdge; + try { + isEdge = deviceConfig.isEdgeDevice(device); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device."); + continue; + } + + if (!isEdge) { avoidEdgeRouterPairing = false; break; } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java deleted file mode 100644 index d28d38d5..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.grouphandler; - -import java.util.List; -import java.util.Map; - -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; - -/** - * Mechanism through which group handler module retrieves - * the device specific attributes such as segment ID, - * Mac address...etc from group handler applications. - */ -public interface DeviceProperties { - /** - * Returns the segment id of a device to be used in group creation. - * - * @param deviceId device identifier - * @return segment id of a device - */ - int getSegmentId(DeviceId deviceId); - - /** - * Returns the Mac address of a device to be used in group creation. - * - * @param deviceId device identifier - * @return mac address of a device - */ - MacAddress getDeviceMac(DeviceId deviceId); - - /** - * Indicates whether a device is edge device or transit/core device. - * - * @param deviceId device identifier - * @return boolean - */ - boolean isEdgeDevice(DeviceId deviceId); - - /** - * Returns all segment IDs to be considered in building auto - * - * created groups. - * @return list of segment IDs - */ - List getAllDeviceSegmentIds(); - - /** - * Returns subnet-to-ports mapping of given device. - * - * For each entry of the map - * Key: a subnet - * Value: a list of ports, which are bound to the subnet - * - * @param deviceId device identifier - * @return a map that contains all subnet-to-ports mapping of given device - */ - Map> getSubnetPortsMap(DeviceId deviceId); -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java index e47a6625..55142078 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java @@ -24,8 +24,11 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import org.onlab.packet.MacAddress; import org.onlab.packet.MplsLabel; import org.onosproject.core.ApplicationId; +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; +import org.onosproject.segmentrouting.config.DeviceProperties; import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.net.DeviceId; @@ -105,11 +108,19 @@ public class PolicyGroupHandler extends DefaultGroupHandler { PolicyGroupIdentifier(id, Collections.singletonList(param), Collections.singletonList(bucketId)); + MacAddress neighborEthDst; + try { + neighborEthDst = deviceConfig.getDeviceMac(neighbor); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + + " Skipping createPolicyGroupChain for this label."); + continue; + } + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); tBuilder.setOutput(sp) - .setEthDst(deviceConfig. - getDeviceMac(neighbor)) + .setEthDst(neighborEthDst) .setEthSrc(nodeMacAddr) .pushMpls() .setMpls(MplsLabel.mplsLabel(label)); @@ -168,14 +179,23 @@ public class PolicyGroupHandler extends DefaultGroupHandler { if (fullyResolved) { List outBuckets = new ArrayList<>(); - for (GroupBucketIdentifier bucketId:bucketIds) { + for (GroupBucketIdentifier bucketId : bucketIds) { DeviceId neighbor = portDeviceMap. get(bucketId.outPort()); + + MacAddress neighborEthDst; + try { + neighborEthDst = deviceConfig.getDeviceMac(neighbor); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + + " Skipping createPolicyGroupChain for this bucketId."); + continue; + } + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); tBuilder.setOutput(bucketId.outPort()) - .setEthDst(deviceConfig. - getDeviceMac(neighbor)) + .setEthDst(neighborEthDst) .setEthSrc(nodeMacAddr); if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) { tBuilder.pushMpls() diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java new file mode 100644 index 00000000..02681db3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java @@ -0,0 +1,95 @@ +/* + * 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.vtnweb.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Before; +import org.junit.Test; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.TenantId; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Flow rule codec unit tests. + */ +public class PortChainCodecTest { + + SfcCodecContext context; + JsonCodec portChainCodec; + /** + * Sets up for each test. Creates a context and fetches the flow rule + * codec. + */ + @Before + public void setUp() { + context = new SfcCodecContext(); + portChainCodec = context.codec(PortChain.class); + assertThat(portChainCodec, notNullValue()); + } + + /** + * Reads in a rule from the given resource and decodes it. + * + * @param resourceName resource to use to read the JSON for the rule + * @return decoded flow rule + * @throws IOException if processing the resource fails + */ + private PortChain getPortChain(String resourceName) throws IOException { + InputStream jsonStream = PortChainCodecTest.class + .getResourceAsStream(resourceName); + ObjectMapper mapper = new ObjectMapper(); + JsonNode json = mapper.readTree(jsonStream); + assertThat(json, notNullValue()); + PortChain portChain = portChainCodec.decode((ObjectNode) json, context); + assertThat(portChain, notNullValue()); + return portChain; + } + + /** + * Checks that a simple rule decodes properly. + * + * @throws IOException if the resource cannot be processed + */ + @Test + public void codecPortChainTest() throws IOException { + + PortChain portChain = getPortChain("portChain.json"); + + assertThat(portChain, notNullValue()); + + PortChainId portChainId = PortChainId.of("1278dcd4-459f-62ed-754b-87fc5e4a6751"); + TenantId tenantId = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); + + assertThat(portChain.portChainId().toString(), is(portChainId.toString())); + assertThat(portChain.name(), is("PC2")); + assertThat(portChain.tenantId().toString(), is(tenantId.toString())); + assertThat(portChain.description(), is("Two flows and two port-pair-groups")); + + assertThat(portChain.flowClassifiers(), notNullValue()); + assertThat(portChain.portPairGroups(), notNullValue()); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java new file mode 100644 index 00000000..de2ee001 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java @@ -0,0 +1,93 @@ +/* + * 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.vtnweb.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Before; +import org.junit.Test; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.TenantId; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Flow rule codec unit tests. + */ +public class PortPairGroupCodecTest { + + SfcCodecContext context; + JsonCodec portPairGroupCodec; + /** + * Sets up for each test. Creates a context and fetches the flow rule + * codec. + */ + @Before + public void setUp() { + context = new SfcCodecContext(); + portPairGroupCodec = context.codec(PortPairGroup.class); + assertThat(portPairGroupCodec, notNullValue()); + } + + /** + * Reads in a rule from the given resource and decodes it. + * + * @param resourceName resource to use to read the JSON for the rule + * @return decoded flow rule + * @throws IOException if processing the resource fails + */ + private PortPairGroup getPortPairGroup(String resourceName) throws IOException { + InputStream jsonStream = PortPairGroupCodecTest.class + .getResourceAsStream(resourceName); + ObjectMapper mapper = new ObjectMapper(); + JsonNode json = mapper.readTree(jsonStream); + assertThat(json, notNullValue()); + PortPairGroup portPairGroup = portPairGroupCodec.decode((ObjectNode) json, context); + assertThat(portPairGroup, notNullValue()); + return portPairGroup; + } + + /** + * Checks that a simple rule decodes properly. + * + * @throws IOException if the resource cannot be processed + */ + @Test + public void codecPortPairGroupTest() throws IOException { + + PortPairGroup portPairGroup = getPortPairGroup("portPairGroup.json"); + + assertThat(portPairGroup, notNullValue()); + + PortPairGroupId portPairGroupId = PortPairGroupId.of("4512d643-24fc-4fae-af4b-321c5e2eb3d1"); + TenantId tenantId = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); + + assertThat(portPairGroup.portPairGroupId().toString(), is(portPairGroupId.toString())); + assertThat(portPairGroup.name(), is("PG1")); + assertThat(portPairGroup.tenantId().toString(), is(tenantId.toString())); + assertThat(portPairGroup.description(), is("Two port-pairs")); + assertThat(portPairGroup.portPairs(), notNullValue()); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json new file mode 100644 index 00000000..07a1bc21 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json @@ -0,0 +1,14 @@ +{ + "id": "1278dcd4-459f-62ed-754b-87fc5e4a6751", + "name": "PC2", + "tenant_id": "d382007aa9904763a801f68ecf065cf5", + "description": "Two flows and two port-pair-groups", + "flow_classifiers": [ + "456a4a34-2e9c-14ae-37fb-765feae2eb05", + "4a334cd4-fe9c-4fae-af4b-321c5e2eb051" + ], + "port_pair_groups": [ + "4512d643-24fc-4fae-af4b-321c5e2eb3d1", + "4a634d49-76dc-4fae-af4b-321c5e23d651" + ] +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json new file mode 100644 index 00000000..e19a66fc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json @@ -0,0 +1,10 @@ +{ + "id": "4512d643-24fc-4fae-af4b-321c5e2eb3d1", + "name": "PG1", + "tenant_id": "d382007aa9904763a801f68ecf065cf5", + "description": "Two port-pairs", + "port_pairs": [ + "875dfeda-43ed-23fe-454b-764feab2c342", + "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae" + ] +} -- cgit