Ported PeerConnectivity onto ONOS next, and implemented a service that can
construct Interface objects based on PortAddresses from HostService.
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 99960a4..c8db20d 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -2,35 +2,40 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
+ <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.onlab.onos</groupId>
- <artifactId>onos-apps</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
+ <parent>
+ <groupId>org.onlab.onos</groupId>
+ <artifactId>onos-apps</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
- <artifactId>onos-app-sdnip</artifactId>
- <packaging>bundle</packaging>
+ <artifactId>onos-app-sdnip</artifactId>
+ <packaging>bundle</packaging>
- <description>SDN-IP peering application</description>
+ <description>SDN-IP peering application</description>
- <dependencies>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.4.2</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.4.2</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ </dependencies>
</project>
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostServiceBasedInterfaceService.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostServiceBasedInterfaceService.java
new file mode 100644
index 0000000..d6ad3c4
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostServiceBasedInterfaceService.java
@@ -0,0 +1,59 @@
+package org.onlab.onos.sdnip;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Set;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.host.PortAddresses;
+import org.onlab.onos.sdnip.config.Interface;
+import org.onlab.packet.IpAddress;
+
+import com.google.common.collect.Sets;
+
+
+
+/**
+ * Provides IntefaceService using PortAddresses data from the HostService.
+ */
+public class HostServiceBasedInterfaceService implements InterfaceService {
+
+ private final HostService hostService;
+
+ public HostServiceBasedInterfaceService(HostService hostService) {
+ this.hostService = checkNotNull(hostService);
+ }
+
+ @Override
+ public Set<Interface> getInterfaces() {
+ Set<PortAddresses> addresses = hostService.getAddressBindings();
+ Set<Interface> interfaces = Sets.newHashSetWithExpectedSize(addresses.size());
+ for (PortAddresses a : addresses) {
+ interfaces.add(new Interface(a));
+ }
+ return interfaces;
+ }
+
+ @Override
+ public Interface getInterface(ConnectPoint connectPoint) {
+ checkNotNull(connectPoint);
+
+ PortAddresses portAddresses =
+ hostService.getAddressBindingsForPort(connectPoint);
+
+ if (!portAddresses.ips().isEmpty()) {
+ return new Interface(portAddresses);
+ }
+
+ return null;
+ }
+
+ @Override
+ public Interface getMatchingInterface(IpAddress ipAddress) {
+ // TODO implement
+ throw new NotImplementedException("getMatchingInteface is not yet implemented");
+ }
+
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/InterfaceService.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/InterfaceService.java
new file mode 100644
index 0000000..f9e881f
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/InterfaceService.java
@@ -0,0 +1,37 @@
+package org.onlab.onos.sdnip;
+
+import java.util.Set;
+
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.sdnip.config.Interface;
+import org.onlab.packet.IpAddress;
+
+/**
+ * Provides information about the interfaces in the network.
+ */
+public interface InterfaceService {
+ /**
+ * Retrieves the entire set of interfaces in the network.
+ *
+ * @return the set of interfaces
+ */
+ Set<Interface> getInterfaces();
+
+ /**
+ * Retrieves the interface associated with the given connect point.
+ *
+ * @param connectPoint the connect point to retrieve interface information
+ * for
+ * @return the interface
+ */
+ Interface getInterface(ConnectPoint connectPoint);
+
+ /**
+ * Retrieves the interface that matches the given IP address. Matching
+ * means that the IP address is in one of the interface's assigned subnets.
+ *
+ * @param ipAddress IP address to match
+ * @return the matching interface
+ */
+ Interface getMatchingInterface(IpAddress ipAddress);
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/PeerConnectivity.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/PeerConnectivity.java
new file mode 100644
index 0000000..75ffd98
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/PeerConnectivity.java
@@ -0,0 +1,343 @@
+package org.onlab.onos.sdnip;
+
+import java.util.List;
+
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.flow.DefaultTrafficSelector;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.intent.IntentService;
+import org.onlab.onos.net.intent.PointToPointIntent;
+import org.onlab.onos.sdnip.config.BgpPeer;
+import org.onlab.onos.sdnip.config.BgpSpeaker;
+import org.onlab.onos.sdnip.config.Interface;
+import org.onlab.onos.sdnip.config.InterfaceAddress;
+import org.onlab.onos.sdnip.config.SdnIpConfigService;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manages the connectivity requirements between peers.
+ */
+public class PeerConnectivity {
+
+ private static final Logger log = LoggerFactory.getLogger(
+ PeerConnectivity.class);
+
+ // TODO these shouldn't be defined here
+ private static final short BGP_PORT = 179;
+ private static final int IPV4_BIT_LENGTH = 32;
+
+ private final SdnIpConfigService configInfoService;
+ private final InterfaceService interfaceService;
+ private final IntentService intentService;
+
+ // TODO this sucks.
+ private int intentId = 0;
+
+ public PeerConnectivity(SdnIpConfigService configInfoService,
+ InterfaceService interfaceService, IntentService intentService) {
+ this.configInfoService = configInfoService;
+ this.interfaceService = interfaceService;
+ this.intentService = intentService;
+ }
+
+ public void start() {
+ // TODO are any of these errors?
+ if (interfaceService.getInterfaces().isEmpty()) {
+
+ log.warn("The interface in configuration file is empty. "
+ + "Thus, the SDN-IP application can not be started.");
+ } else if (configInfoService.getBgpPeers().isEmpty()) {
+
+ log.warn("The BGP peer in configuration file is empty."
+ + "Thus, the SDN-IP application can not be started.");
+ } else if (configInfoService.getBgpSpeakers() == null) {
+
+ log.error("The BGP speaker in configuration file is empty. "
+ + "Thus, the SDN-IP application can not be started.");
+ return;
+ }
+
+ setupBgpPaths();
+ setupIcmpPaths();
+ }
+
+ /**
+ * Sets up paths for all {@link BgpSpeaker}s and all external peers.
+ * <p/>
+ * Run a loop for all BGP speakers and a loop for all BGP peers outside.
+ * Push intents for paths from each BGP speaker to all peers. Push intents
+ * for paths from all peers to each BGP speaker.
+ */
+ private void setupBgpPaths() {
+ for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
+ .values()) {
+ log.debug("Start to set up BGP paths for BGP speaker: {}",
+ bgpSpeaker);
+ ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
+
+ List<InterfaceAddress> interfaceAddresses =
+ bgpSpeaker.interfaceAddresses();
+
+ for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
+
+ log.debug("Start to set up BGP paths between BGP speaker: {} "
+ + "to BGP peer: {}", bgpSpeaker, bgpPeer);
+
+ Interface peerInterface = interfaceService.getInterface(
+ bgpPeer.connectPoint());
+ if (peerInterface == null) {
+ log.error("Can not find the corresponding Interface from "
+ + "configuration for BGP peer {}",
+ bgpPeer.ipAddress());
+ continue;
+ }
+
+ IpAddress bgpdAddress = null;
+ for (InterfaceAddress interfaceAddress : interfaceAddresses) {
+ if (interfaceAddress.connectPoint().equals(
+ peerInterface.connectPoint())) {
+ bgpdAddress = interfaceAddress.ipAddress();
+ break;
+ }
+ }
+ if (bgpdAddress == null) {
+ log.debug("There is no interface IP address for bgpPeer: {}"
+ + " on interface {}", bgpPeer, bgpPeer.connectPoint());
+ return;
+ }
+
+ IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
+ ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
+
+ // install intent for BGP path from BGPd to BGP peer matching
+ // destination TCP port 179
+
+ // TODO: The usage of PacketMatchBuilder will be improved, then we
+ // only need to new the PacketMatchBuilder once.
+ // By then, the code here will be improved accordingly.
+ /*PacketMatch packetMatch = new PacketMatchBuilder().setEtherType(
+ Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_TCP)
+ .setSrcIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstTcpPort(BGP_PORT)
+ .build();
+ */
+
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchTcpDst(BGP_PORT)
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .build();
+
+ PointToPointIntent intentMatchDstTcpPort = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdConnectPoint, bgpdPeerConnectPoint);
+ intentService.submit(intentMatchDstTcpPort);
+ log.debug("Submitted BGP path intent matching dst TCP port 179 "
+ + "from BGPd {} to peer {}: {}",
+ bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);
+
+ // install intent for BGP path from BGPd to BGP peer matching
+ // source TCP port 179
+ /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_TCP)
+ .setSrcIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setSrcTcpPort(BGP_PORT)
+ .build();*/
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchTcpSrc(BGP_PORT)
+ .build();
+
+ PointToPointIntent intentMatchSrcTcpPort = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdConnectPoint, bgpdPeerConnectPoint);
+ intentService.submit(intentMatchSrcTcpPort);
+ log.debug("Submitted BGP path intent matching src TCP port 179"
+ + "from BGPd {} to peer {}: {}",
+ bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);
+
+ // install intent for reversed BGP path from BGP peer to BGPd
+ // matching destination TCP port 179
+ /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_TCP)
+ .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstTcpPort(BGP_PORT)
+ .build();*/
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchTcpDst(BGP_PORT)
+ .build();
+
+ PointToPointIntent reversedIntentMatchDstTcpPort = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdPeerConnectPoint, bgpdConnectPoint);
+ intentService.submit(reversedIntentMatchDstTcpPort);
+ log.debug("Submitted BGP path intent matching dst TCP port 179"
+ + "from BGP peer {} to BGPd {} : {}",
+ bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);
+
+ // install intent for reversed BGP path from BGP peer to BGPd
+ // matching source TCP port 179
+ /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_TCP)
+ .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setSrcTcpPort(BGP_PORT)
+ .build();*/
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchTcpSrc(BGP_PORT)
+ .build();
+
+ PointToPointIntent reversedIntentMatchSrcTcpPort = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdPeerConnectPoint, bgpdConnectPoint);
+ intentService.submit(reversedIntentMatchSrcTcpPort);
+ log.debug("Submitted BGP path intent matching src TCP port 179"
+ + "from BGP peer {} to BGPd {} : {}",
+ bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);
+
+ }
+ }
+ }
+
+ /**
+ * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
+ * located in other external networks.
+ * <p/>
+ * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
+ * intents for paths from each BGP speaker to all peers. Push intents
+ * for paths from all peers to each BGP speaker.
+ */
+ private void setupIcmpPaths() {
+ for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
+ .values()) {
+ log.debug("Start to set up ICMP paths for BGP speaker: {}",
+ bgpSpeaker);
+ ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
+ List<InterfaceAddress> interfaceAddresses = bgpSpeaker
+ .interfaceAddresses();
+
+ for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
+
+ Interface peerInterface = interfaceService.getInterface(
+ bgpPeer.connectPoint());
+
+ if (peerInterface == null) {
+ log.error("Can not find the corresponding Interface from "
+ + "configuration for BGP peer {}",
+ bgpPeer.ipAddress());
+ continue;
+ }
+ IpAddress bgpdAddress = null;
+ for (InterfaceAddress interfaceAddress : interfaceAddresses) {
+ if (interfaceAddress.connectPoint().equals(
+ peerInterface.connectPoint())) {
+ bgpdAddress = interfaceAddress.ipAddress();
+ break;
+ }
+
+ }
+ if (bgpdAddress == null) {
+ log.debug("There is no IP address for bgpPeer: {} on "
+ + "interface port: {}", bgpPeer,
+ bgpPeer.connectPoint());
+ return;
+ }
+
+ IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
+ ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
+
+ // install intent for ICMP path from BGPd to BGP peer
+ /*PacketMatch packetMatch =
+ new PacketMatchBuilder().setEtherType(
+ Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_ICMP)
+ .setSrcIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .build();*/
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_ICMP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .build();
+
+ PointToPointIntent intent = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdConnectPoint, bgpdPeerConnectPoint);
+ intentService.submit(intent);
+ log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
+ + " {}", bgpdAddress, bgpdPeerAddress, intent);
+
+ // install intent for reversed ICMP path from BGP peer to BGPd
+ /*packetMatch = new PacketMatchBuilder().setEtherType(
+ Ethernet.TYPE_IPV4)
+ .setIpProto(PROTOCOL_ICMP)
+ .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .setDstIpNet(new Ip4Prefix(bgpdAddress,
+ (short) Ip4Address.BIT_LENGTH))
+ .build();*/
+
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_ICMP)
+ .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
+ .build();
+
+ PointToPointIntent reversedIntent = new PointToPointIntent(
+ nextIntentId(), selector, treatment,
+ bgpdPeerConnectPoint, bgpdConnectPoint);
+ intentService.submit(reversedIntent);
+ log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
+ + " {} : {}",
+ bgpdPeerAddress, bgpdAddress, reversedIntent);
+ }
+ }
+ }
+
+ private IntentId nextIntentId() {
+ return new IntentId(intentId++);
+ }
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
index a15faef..25b13f1 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
@@ -5,6 +5,10 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.sdnip.config.SdnIpConfigReader;
import org.slf4j.Logger;
@@ -16,7 +20,14 @@
private final Logger log = getLogger(getClass());
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentService intentService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
+
private SdnIpConfigReader config;
+ private PeerConnectivity peerConnectivity;
@Activate
protected void activate() {
@@ -24,6 +35,12 @@
config = new SdnIpConfigReader();
config.init();
+
+ InterfaceService interfaceService = new HostServiceBasedInterfaceService(hostService);
+
+ peerConnectivity = new PeerConnectivity(config, interfaceService, intentService);
+ peerConnectivity.start();
+
}
@Deactivate
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpPeer.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpPeer.java
index 9d014d0..3e89c58 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpPeer.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpPeer.java
@@ -8,19 +8,20 @@
import org.onlab.onos.net.PortNumber;
import org.onlab.packet.IpAddress;
+import com.google.common.base.MoreObjects;
+
/**
- * Configuration details for a BGP peer. It contains the peer's IP address and
- * an interface name which maps to the interface they are attached at.
+ * Configuration details for a BGP peer.
*/
public class BgpPeer {
private final ConnectPoint connectPoint;
private final IpAddress ipAddress;
/**
- * Class constructor, taking the interface name and IP address of the peer.
+ * Creates a new BgpPeer.
*
- * @param interfaceName the String name of the interface which can be used
- * to look up the interface this peer is attached at
+ * @param dpid the DPID of the switch the peer is attached at, as a String
+ * @param port the port the peer is attached at
* @param ipAddress the IP address of the peer as a String
*/
public BgpPeer(@JsonProperty("attachmentDpid") String dpid,
@@ -37,7 +38,7 @@
*
* @return the connection point
*/
- public ConnectPoint getConnectPoint() {
+ public ConnectPoint connectPoint() {
return connectPoint;
}
@@ -46,7 +47,7 @@
*
* @return the IP address
*/
- public IpAddress getIpAddress() {
+ public IpAddress ipAddress() {
return ipAddress;
}
@@ -69,4 +70,12 @@
return Objects.equals(this.connectPoint, that.connectPoint)
&& Objects.equals(this.ipAddress, that.ipAddress);
}
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("connectPoint", connectPoint)
+ .add("ipAddress", ipAddress)
+ .toString();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpSpeaker.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpSpeaker.java
index c7c2edd..248fc1d 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpSpeaker.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/BgpSpeaker.java
@@ -10,6 +10,8 @@
import org.onlab.onos.net.PortNumber;
import org.onlab.packet.MacAddress;
+import com.google.common.base.MoreObjects;
+
/**
* Represents a BGP daemon in SDN network.
* <p/>
@@ -23,28 +25,28 @@
* used to reference this speaker in the configuration.
*/
public class BgpSpeaker {
- private final String speakerName;
- private final ConnectPoint attachmentSwitchPort;
+ private final String name;
+ private final ConnectPoint connectPoint;
private final MacAddress macAddress;
private List<InterfaceAddress> interfaceAddresses;
/**
* Class constructor used by the JSON library to create an object.
*
- * @param speakerName the name of the BGP router inside SDN network
- * @param attachmentDpid the DPID where the BGP router is attached to
- * @param attachmentPort the port where the BGP router is attached to
- * @param macAddress the MAC address of the BGP router
+ * @param name the name of the BGP speaker inside SDN network
+ * @param attachmentDpid the DPID where the BGP speaker is attached to
+ * @param attachmentPort the port where the BGP speaker is attached to
+ * @param macAddress the MAC address of the BGP speaker
*/
@JsonCreator
- public BgpSpeaker(@JsonProperty("name") String speakerName,
+ public BgpSpeaker(@JsonProperty("name") String name,
@JsonProperty("attachmentDpid") String attachmentDpid,
@JsonProperty("attachmentPort") int attachmentPort,
@JsonProperty("macAddress") String macAddress) {
- this.speakerName = speakerName;
+ this.name = name;
this.macAddress = MacAddress.valueOf(macAddress);
- this.attachmentSwitchPort = new ConnectPoint(
+ this.connectPoint = new ConnectPoint(
DeviceId.deviceId(SdnIpConfigReader.dpidToUri(attachmentDpid)),
PortNumber.portNumber(attachmentPort));
}
@@ -67,25 +69,25 @@
*
* @return the BGP speaker name
*/
- public String getSpeakerName() {
- return speakerName;
+ public String name() {
+ return name;
}
/**
- * Gets the switch port where the BGP speaker is attached.
+ * Gets the connect point where the BGP speaker is attached.
*
- * @return the switch port where the BGP speaker is attached
+ * @return the connect point
*/
- public ConnectPoint getAttachmentSwitchPort() {
- return attachmentSwitchPort;
+ public ConnectPoint connectPoint() {
+ return connectPoint;
}
/**
* Gets the MAC address of the BGP speaker.
*
- * @return the MAC address of the BGP speaker
+ * @return the MAC address
*/
- public MacAddress getMacAddress() {
+ public MacAddress macAddress() {
return macAddress;
}
@@ -96,7 +98,7 @@
* @return a list of IP addresses of the BGP speaker configured on all
* virtual interfaces
*/
- public List<InterfaceAddress> getInterfaceAddresses() {
+ public List<InterfaceAddress> interfaceAddresses() {
return interfaceAddresses;
}
@@ -108,17 +110,27 @@
BgpSpeaker otherBgpSpeaker = (BgpSpeaker) other;
- return speakerName.equals(otherBgpSpeaker.speakerName) &&
- attachmentSwitchPort.equals(
- otherBgpSpeaker.attachmentSwitchPort) &&
+ return name.equals(otherBgpSpeaker.name) &&
+ connectPoint.equals(
+ otherBgpSpeaker.connectPoint) &&
macAddress.equals(otherBgpSpeaker.macAddress) &&
interfaceAddresses.equals(otherBgpSpeaker.interfaceAddresses);
}
@Override
public int hashCode() {
- return Objects.hash(speakerName, attachmentSwitchPort, macAddress,
+ return Objects.hash(name, connectPoint, macAddress,
interfaceAddresses);
}
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("speakerName", name)
+ .add("connectPoint", connectPoint)
+ .add("macAddress", macAddress)
+ .add("interfaceAddresses", interfaceAddresses)
+ .toString();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/Interface.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/Interface.java
index 33287ad..88de952 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/Interface.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/Interface.java
@@ -1,86 +1,78 @@
package org.onlab.onos.sdnip.config;
import java.util.Objects;
+import java.util.Set;
-import org.codehaus.jackson.annotate.JsonCreator;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.onlab.onos.net.ConnectPoint;
-import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.host.PortAddresses;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Sets;
/**
- * Represents an interface, which is an external-facing switch port that
- * connects to another network.
- * <p/>
- * SDN-IP treats external-facing ports similarly to router ports. Logically, it
- * assigns an IP subnetwork prefix and several IP addresses to each port which
- * are used for communication with the BGP peers located in other networks, for
- * example, the BGP peering sessions. The peers in other networks will be
- * configured to peer with the IP addresses (logically) assigned to the
- * interface. The logical {@code Interface} construct maps on to a physical
- * port in the data plane, which of course has no notion of IP addresses.
- * <p/>
- * Each interface has a name, which is a unique identifying String that is used
- * to reference this interface in the configuration (for example, to map
- * {@link BgpPeer}s to {@code Interfaces}.
+ * An Interface is a set of addresses that are logically mapped to a switch
+ * port in the network.
*/
public class Interface {
- private final String name;
- private final ConnectPoint switchPort;
- private final IpPrefix ip4Prefix;
+ private final ConnectPoint connectPoint;
+ private final Set<IpPrefix> ipAddresses;
+ private final MacAddress macAddress;
/**
- * Class constructor used by the JSON library to create an object.
+ * Creates an Interface based on a connection point, a set of IP addresses
+ * and a MAC address.
*
- * @param name the name of the interface
- * @param dpid the dpid of the switch
- * @param port the port on the switch
- * @param prefixAddress the network prefix address logically assigned to the
- * interface
- * @param prefixLength the length of the network prefix of the IP address
+ * @param connectPoint the connect point this interface is mapped to
+ * @param prefixAddress the IP addresses for the interface
+ * @param macAddress the MAC address of the interface
*/
- @JsonCreator
- public Interface(@JsonProperty("name") String name,
- @JsonProperty("dpid") String dpid,
- @JsonProperty("port") int port,
- @JsonProperty("ipAddress") String prefixAddress,
- @JsonProperty("prefixLength") short prefixLength) {
- this.name = name;
- this.switchPort = new ConnectPoint(
- DeviceId.deviceId(SdnIpConfigReader.dpidToUri(dpid)),
- PortNumber.portNumber(port));
- this.ip4Prefix = IpPrefix.valueOf(prefixAddress + "/" + prefixLength);
+ public Interface(ConnectPoint connectPoint, Set<IpPrefix> prefixAddress,
+ MacAddress macAddress) {
+ this.connectPoint = connectPoint;
+ this.ipAddresses = Sets.newHashSet(prefixAddress);
+ this.macAddress = macAddress;
}
/**
- * Gets the name of the interface.
+ * Creates an Interface based on a PortAddresses object.
*
- * @return the name of the interface
+ * @param portAddresses the PortAddresses object to turn into an Interface
*/
- public String getName() {
- return name;
+ public Interface(PortAddresses portAddresses) {
+ connectPoint = portAddresses.connectPoint();
+ ipAddresses = Sets.newHashSet(portAddresses.ips());
+ macAddress = portAddresses.mac();
}
/**
- * Gets the {@link SwitchPort} that this interface maps to.
+ * Retrieves the connection point that this interface maps to.
*
- * @return the switch port
+ * @return the connection point
*/
- public ConnectPoint getSwitchPort() {
- return switchPort;
+ public ConnectPoint connectPoint() {
+ return connectPoint;
}
/**
- * Gets the IP prefix of the subnetwork which is logically assigned
- * to the switch port.
+ * Retrieves the set of IP addresses that are assigned to the interface.
*
- * @return the IP prefix
+ * @return the set of IP addresses
*/
- public IpPrefix getIp4Prefix() {
- return ip4Prefix;
+ public Set<IpPrefix> ips() {
+ return ipAddresses;
}
+ /**
+ * Retrieves the MAC address that is assigned to the interface.
+ *
+ * @return the MAC address
+ */
+ public MacAddress mac() {
+ return macAddress;
+ }
+
@Override
public boolean equals(Object other) {
if (!(other instanceof Interface)) {
@@ -89,13 +81,22 @@
Interface otherInterface = (Interface) other;
- return name.equals(otherInterface.name) &&
- switchPort.equals(otherInterface.switchPort) &&
- ip4Prefix.equals(otherInterface.ip4Prefix);
+ return connectPoint.equals(otherInterface.connectPoint) &&
+ ipAddresses.equals(otherInterface.ipAddresses) &&
+ macAddress.equals(otherInterface.macAddress);
}
@Override
public int hashCode() {
- return Objects.hash(name, switchPort, ip4Prefix);
+ return Objects.hash(connectPoint, ipAddresses, macAddress);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("connectPoint", connectPoint)
+ .add("ipAddresses", ipAddresses)
+ .add("macAddress", macAddress)
+ .toString();
}
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/InterfaceAddress.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/InterfaceAddress.java
index 4b423a7..1ae204f 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/InterfaceAddress.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/InterfaceAddress.java
@@ -8,6 +8,8 @@
import org.onlab.onos.net.PortNumber;
import org.onlab.packet.IpAddress;
+import com.google.common.base.MoreObjects;
+
/**
* Represents an address of a {@link BgpSpeaker} configured on an
* {@link Interface}.
@@ -19,10 +21,10 @@
private final IpAddress ipAddress;
/**
- * Class constructor used by the JSON library to create an object.
+ * Creates an InterfaceAddress object.
*
- * @param interfaceName the interface name for which an IP address of a BGP
- * router is configured
+ * @param dpid the DPID of the interface as a String
+ * @param port the port of the interface
* @param ipAddress the IP address of a {@link BgpSpeaker} configured on
* the interface
*/
@@ -40,7 +42,7 @@
*
* @return the connection point
*/
- public ConnectPoint getConnectPoint() {
+ public ConnectPoint connectPoint() {
return connectPoint;
}
@@ -49,7 +51,7 @@
*
* @return the IP address
*/
- public IpAddress getIpAddress() {
+ public IpAddress ipAddress() {
return ipAddress;
}
@@ -72,4 +74,12 @@
return Objects.equals(this.connectPoint, that.connectPoint)
&& Objects.equals(this.ipAddress, that.ipAddress);
}
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("connectPoint", connectPoint)
+ .add("ipAddress", ipAddress)
+ .toString();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
index f98cd15..50034ed 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/config/SdnIpConfigReader.java
@@ -50,11 +50,11 @@
}*/
bgpSpeakers = new ConcurrentHashMap<>();
for (BgpSpeaker speaker : config.getBgpSpeakers()) {
- bgpSpeakers.put(speaker.getSpeakerName(), speaker);
+ bgpSpeakers.put(speaker.name(), speaker);
}
bgpPeers = new ConcurrentHashMap<>();
for (BgpPeer peer : config.getPeers()) {
- bgpPeers.put(peer.getIpAddress(), peer);
+ bgpPeers.put(peer.ipAddress(), peer);
}
} catch (IOException e) {
log.error("Error reading JSON file", e);
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
index 9568f1f..c1c56c3 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
@@ -161,10 +161,10 @@
switch (l3m.subtype()) {
case IP_DST:
ip = (ModIPInstruction) i;
- return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
+ return factory.actions().setNwDst(IPv4Address.of(ip.ip().toRealInt()));
case IP_SRC:
ip = (ModIPInstruction) i;
- return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
+ return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toRealInt()));
default:
log.warn("Unimplemented action type {}.", l3m.subtype());
break;
@@ -220,21 +220,21 @@
case IPV4_DST:
ip = (IPCriterion) c;
if (ip.ip().isMasked()) {
- Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
- IPv4Address.of(ip.ip().netmask().toInt()));
+ Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()),
+ IPv4Address.of(ip.ip().netmask().toRealInt()));
mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
} else {
- mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
+ mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toRealInt()));
}
break;
case IPV4_SRC:
ip = (IPCriterion) c;
if (ip.ip().isMasked()) {
- Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
- IPv4Address.of(ip.ip().netmask().toInt()));
+ Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()),
+ IPv4Address.of(ip.ip().netmask().toRealInt()));
mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
} else {
- mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
+ mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toRealInt()));
}
break;
case IP_PROTO:
diff --git a/utils/misc/src/main/java/org/onlab/packet/IpAddress.java b/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
index 44a018e..fef0cfd 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
@@ -181,6 +181,15 @@
return address;
}
+ public int toRealInt() {
+ int val = 0;
+ for (int i = 0; i < octets.length; i++) {
+ val <<= 8;
+ val |= octets[i] & 0xff;
+ }
+ return val;
+ }
+
/**
* Helper for computing the mask value from CIDR.
*