Moved BGP code and Router code into their own bundle.
The main goal of this is to allow routing code to be used by multiple
applications.
Changes include:
* Created an onos-app-routing bundle and moved BGP code and routing code
into it.
* Created an onos-app-routing-api bundle as a common API bundle between
onos-app-routing and onos-app-sdnip, to prevent circular dependencies.
* Moved API classes into onos-app-routing-api bundle.
* Made Router and BgpSessionManager into OSGi components. This is not quite
clean, because there is still a chain of start() method calls from SdnIp
through to BgpSessionManager to preserve startup order. This should be
revisted so components can be started using activate()
* Created BgpService and RoutingService APIs to glue different components
together.
* Many unit test changes. A lot of the previous unit tests spanned the
Router and IntentSynchronizer classes, but this is not possible any more
since these classes are in different bundles. I had to rewrite some of
these tests so that each unit test class only tests one real class. A
nice side-effect is that the tests are now simpler because each test
tests less functionality.
* Removed SdnIp test seeing as it doesn't run automatically, was already
broken and has been largely superseded by other unit tests and the nightly
functional tests.
Change-Id: I70ecf5391aa353e99e7cdcf7ed38a530c87571bb
diff --git a/apps/pom.xml b/apps/pom.xml
index ca64e5f..2746e65 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -46,6 +46,8 @@
<module>oecfg</module>
<module>demo</module>
<module>election</module>
+ <module>routing</module>
+ <module>routing-api</module>
</modules>
<properties>
diff --git a/apps/routing-api/pom.xml b/apps/routing-api/pom.xml
new file mode 100644
index 0000000..c83cb8f
--- /dev/null
+++ b/apps/routing-api/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>onos-apps</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>onos-app-routing-api</artifactId>
+
+ <packaging>bundle</packaging>
+ <description>API for routing applications</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/apps/routing-api/src/main/java/org/onosproject/routingapi/BgpService.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/BgpService.java
new file mode 100644
index 0000000..c7e58d4
--- /dev/null
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/BgpService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.routingapi;
+
+/**
+ * Provides a way of interacting with the BGP protocol component.
+ */
+public interface BgpService {
+
+ /**
+ * Starts the BGP service.
+ *
+ * @param routeListener listener to send route updates to
+ * @param bgpPort port number to listen on
+ */
+ void start(RouteListener routeListener, int bgpPort);
+
+ /**
+ * Stops the BGP service.
+ */
+ void stop();
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibEntry.java
similarity index 68%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/FibEntry.java
index 988b49a..86b40f8 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibEntry.java
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
+import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
+import java.util.Objects;
+
/**
* An entry in the Forwarding Information Base (FIB).
*/
@@ -67,4 +70,31 @@
public MacAddress nextHopMac() {
return nextHopMac;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof FibEntry)) {
+ return false;
+ }
+
+ FibEntry that = (FibEntry) o;
+
+ return Objects.equals(this.prefix, that.prefix) &&
+ Objects.equals(this.nextHopIp, that.nextHopIp) &&
+ Objects.equals(this.nextHopMac, that.nextHopMac);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(prefix, nextHopIp, nextHopMac);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("prefix", prefix)
+ .add("nextHopIp", nextHopIp)
+ .add("nextHopMac", nextHopMac)
+ .toString();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibListener.java
similarity index 96%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/FibListener.java
index 13674e3..218139e 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibListener.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
import java.util.Collection;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibUpdate.java
similarity index 70%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/FibUpdate.java
index a3d8c3c..2b0215c 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/FibUpdate.java
@@ -13,7 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
/**
* Represents a change to the Forwarding Information Base (FIB).
@@ -66,4 +70,29 @@
public FibEntry entry() {
return entry;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof FibUpdate)) {
+ return false;
+ }
+
+ FibUpdate that = (FibUpdate) o;
+
+ return Objects.equals(this.type, that.type) &&
+ Objects.equals(this.entry, that.entry);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, entry);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("type", type)
+ .add("entry", entry)
+ .toString();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteEntry.java
similarity index 96%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/RouteEntry.java
index 3cffb7e..3e861e5 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteEntry.java
@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
+import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
-import com.google.common.base.MoreObjects;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a route entry for an IP prefix.
@@ -77,7 +76,7 @@
* @param ipPrefix the IP prefix to use
* @return the binary string representation
*/
- static String createBinaryString(IpPrefix ipPrefix) {
+ public static String createBinaryString(IpPrefix ipPrefix) {
if (ipPrefix.prefixLength() == 0) {
return "";
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteListener.java
similarity index 95%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/RouteListener.java
index 2d9ddc9..55fa70d 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteListener.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
import java.util.Collection;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteUpdate.java
similarity index 98%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java
rename to apps/routing-api/src/main/java/org/onosproject/routingapi/RouteUpdate.java
index f63f214..47aa3c2 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/RouteUpdate.java
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.MoreObjects;
import java.util.Objects;
-import com.google.common.base.MoreObjects;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a change in routing information.
diff --git a/apps/routing-api/src/main/java/org/onosproject/routingapi/RoutingService.java b/apps/routing-api/src/main/java/org/onosproject/routingapi/RoutingService.java
new file mode 100644
index 0000000..e0f9383
--- /dev/null
+++ b/apps/routing-api/src/main/java/org/onosproject/routingapi/RoutingService.java
@@ -0,0 +1,50 @@
+/*
+ * 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.routingapi;
+
+import java.util.Collection;
+
+/**
+ * Provides a way of interacting with the RIB management component.
+ */
+public interface RoutingService {
+
+ /**
+ * Starts the routing service.
+ *
+ * @param listener listener to send FIB updates to
+ */
+ public void start(FibListener listener);
+
+ /**
+ * Stops the routing service.
+ */
+ public void stop();
+
+ /**
+ * Gets all IPv4 routes known to SDN-IP.
+ *
+ * @return the SDN-IP IPv4 routes
+ */
+ public Collection<RouteEntry> getRoutes4();
+
+ /**
+ * Gets all IPv6 routes known to SDN-IP.
+ *
+ * @return the SDN-IP IPv6 routes
+ */
+ public Collection<RouteEntry> getRoutes6();
+}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java b/apps/routing-api/src/test/java/org/onosproject/routingapi/RouteEntryTest.java
similarity index 95%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java
rename to apps/routing-api/src/test/java/org/onosproject/routingapi/RouteEntryTest.java
index b977917..acce45a 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java
+++ b/apps/routing-api/src/test/java/org/onosproject/routingapi/RouteEntryTest.java
@@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routingapi;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
-import org.junit.Test;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-
/**
* Unit tests for the RouteEntry class.
*/
@@ -139,8 +140,8 @@
Ip4Address nextHop3 = Ip4Address.valueOf("5.6.7.9"); // Different
RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3);
- assertThat(routeEntry1, is(not(routeEntry2)));
- assertThat(routeEntry1, is(not(routeEntry3)));
+ assertThat(routeEntry1, Matchers.is(not(routeEntry2)));
+ assertThat(routeEntry1, Matchers.is(not(routeEntry3)));
}
/**
diff --git a/apps/routing/pom.xml b/apps/routing/pom.xml
new file mode 100644
index 0000000..8656ebb
--- /dev/null
+++ b/apps/routing/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>onos-apps</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>onos-app-routing</artifactId>
+
+ <packaging>bundle</packaging>
+ <description>Libraries for routing applications</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-routing-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-cli</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-thirdparty</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java b/apps/routing/src/main/java/org/onosproject/routing/Router.java
similarity index 87%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java
rename to apps/routing/src/main/java/org/onosproject/routing/Router.java
index d19f298..494c190 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/Router.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip;
+package org.onosproject.routing;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimaps;
@@ -23,6 +23,12 @@
import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+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.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
@@ -31,6 +37,14 @@
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+import org.onosproject.routingapi.RoutingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,12 +61,16 @@
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* This class processes route updates and maintains a Routing Information Base
* (RIB). After route updates have been processed and next hops have been
* resolved, FIB updates are sent to any listening FIB components.
*/
-public class Router implements RouteListener {
+@Component(immediate = true)
+@Service
+public class Router implements RoutingService {
private static final Logger log = LoggerFactory.getLogger(Router.class);
@@ -62,52 +80,52 @@
private InvertedRadixTree<RouteEntry> ribTable6;
// Stores all incoming route updates in a queue.
- private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue;
+ private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue
+ = new LinkedBlockingQueue<>();
// Next-hop IP address to route entry mapping for next hops pending MAC resolution
- private final SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
+ private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
// The IPv4 address to MAC address mapping
- private final Map<IpAddress, MacAddress> ip2Mac;
+ private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>();
- private final FibListener fibComponent;
- private final HostService hostService;
- private final ExecutorService bgpUpdatesExecutor;
- private final HostListener hostListener;
+ private FibListener fibComponent;
- /**
- * Class constructor.
- *
- * @param fibComponent the intent synchronizer
- * @param hostService the host service
- */
- public Router(FibListener fibComponent, HostService hostService) {
- // TODO move to a listener model for adding fib listeners
- this.fibComponent = fibComponent;
- this.hostService = hostService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
- this.hostListener = new InternalHostListener();
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected BgpService bgpService;
+ private ExecutorService bgpUpdatesExecutor;
+ private final HostListener hostListener = new InternalHostListener();
+
+ @Activate
+ public void activate() {
ribTable4 = new ConcurrentInvertedRadixTree<>(
new DefaultByteArrayNodeFactory());
ribTable6 = new ConcurrentInvertedRadixTree<>(
new DefaultByteArrayNodeFactory());
- routeUpdatesQueue = new LinkedBlockingQueue<>();
routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
HashMultimap.<IpAddress, RouteEntry>create());
- ip2Mac = new ConcurrentHashMap<>();
bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder()
.setNameFormat("sdnip-bgp-updates-%d").build());
}
- /**
- * Starts the router.
- */
- public void start() {
+ @Deactivate
+ public void deactivate() {
+ log.debug("Stopped");
+ }
+
+ @Override
+ public void start(FibListener listener) {
+ this.fibComponent = checkNotNull(listener);
this.hostService.addListener(hostListener);
+ bgpService.start(new InternalRouteListener(), 2000);
+
bgpUpdatesExecutor.execute(new Runnable() {
@Override
public void run() {
@@ -116,10 +134,10 @@
});
}
- /**
- * Stops the router.
- */
+ @Override
public void stop() {
+ bgpService.stop();
+
this.hostService.removeListener(hostListener);
// Stop the thread(s)
@@ -137,8 +155,12 @@
}
}
- @Override
- public void update(Collection<RouteUpdate> routeUpdates) {
+ /**
+ * Entry point for route updates.
+ *
+ * @param routeUpdates collection of route updates to process
+ */
+ private void update(Collection<RouteUpdate> routeUpdates) {
try {
routeUpdatesQueue.put(routeUpdates);
} catch (InterruptedException e) {
@@ -294,7 +316,9 @@
withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate(
FibUpdate.Type.DELETE, new FibEntry(p, null, null))));
- fibComponent.update(fibUpdates, fibWithdraws);
+ if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) {
+ fibComponent.update(fibUpdates, fibWithdraws);
+ }
}
}
@@ -486,4 +510,14 @@
}
}
}
+
+ /**
+ * Listener for route events.
+ */
+ private class InternalRouteListener implements RouteListener {
+ @Override
+ public void update(Collection<RouteUpdate> routeUpdates) {
+ Router.this.update(routeUpdates);
+ }
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java
similarity index 99%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java
index b009c17..96d74e2 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
/**
* BGP related constants.
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java
similarity index 93%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java
index 4c9b56e..053d0bf 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java
@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,9 +85,9 @@
// ERROR: Connection Not Synchronized
//
// Send NOTIFICATION and close the connection
- int errorCode = MessageHeaderError.ERROR_CODE;
+ int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
int errorSubcode =
- MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
+ BgpConstants.Notifications.MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode,
errorSubcode,
@@ -162,8 +161,8 @@
// ERROR: Bad Message Type
//
// Send NOTIFICATION and close the connection
- int errorCode = MessageHeaderError.ERROR_CODE;
- int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE;
+ int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_TYPE;
ChannelBuffer data = ChannelBuffers.buffer(1);
data.writeByte(type);
ChannelBuffer txMessage =
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java
new file mode 100644
index 0000000..d7914e6
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java
@@ -0,0 +1,45 @@
+/*
+ * 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.routing.bgp;
+
+import java.util.Collection;
+
+/**
+ * Provides information about BGP peering and routes.
+ */
+public interface BgpInfoService {
+
+ /**
+ * Gets the BGP sessions.
+ *
+ * @return the BGP sessions
+ */
+ public Collection<BgpSession> getBgpSessions();
+
+ /**
+ * Gets the selected IPv4 BGP routes among all BGP sessions.
+ *
+ * @return the selected IPv4 BGP routes among all BGP sessions
+ */
+ public Collection<BgpRouteEntry> getBgpRoutes4();
+
+ /**
+ * Gets the selected IPv6 BGP routes among all BGP sessions.
+ *
+ * @return the selected IPv6 BGP routes among all BGP sessions
+ */
+ public Collection<BgpRouteEntry> getBgpRoutes6();
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java
similarity index 98%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java
index fe9404c..186dfeda 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java
similarity index 98%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java
index 5c7053c..63a5dbd 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java
similarity index 94%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java
index cf6bbb7..16ec951 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,8 +116,8 @@
* @return the message to transmit (BGP header included)
*/
static ChannelBuffer prepareBgpNotificationBadMessageLength(int length) {
- int errorCode = MessageHeaderError.ERROR_CODE;
- int errorSubcode = MessageHeaderError.BAD_MESSAGE_LENGTH;
+ int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_LENGTH;
ChannelBuffer data = ChannelBuffers.buffer(2);
data.writeShort(length);
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
similarity index 72%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
index 93ef852..3216aec 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
@@ -13,18 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.onlab.packet.Ip4Address;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.OpenMessageError;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.As4Octet;
-import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,8 +80,8 @@
// ERROR: Unsupported Version Number
//
// Send NOTIFICATION and close the connection
- int errorCode = OpenMessageError.ERROR_CODE;
- int errorSubcode = OpenMessageError.UNSUPPORTED_VERSION_NUMBER;
+ int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNSUPPORTED_VERSION_NUMBER;
ChannelBuffer data = ChannelBuffers.buffer(2);
data.writeShort(BgpConstants.BGP_VERSION);
ChannelBuffer txMessage =
@@ -123,8 +117,8 @@
// ERROR: Unacceptable Hold Time
//
// Send NOTIFICATION and close the connection
- int errorCode = OpenMessageError.ERROR_CODE;
- int errorSubcode = OpenMessageError.UNACCEPTABLE_HOLD_TIME;
+ int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNACCEPTABLE_HOLD_TIME;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
@@ -149,7 +143,7 @@
// Parse the Optional Parameters
try {
parseOptionalParameters(bgpSession, ctx, message);
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
// ERROR: Error parsing optional parameters
log.debug("BGP RX OPEN Error from {}: " +
"Exception parsing Optional Parameters: {}",
@@ -158,8 +152,8 @@
// ERROR: Invalid Optional Parameters: Unspecific
//
// Send NOTIFICATION and close the connection
- int errorCode = OpenMessageError.ERROR_CODE;
- int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
+ int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
@@ -202,8 +196,8 @@
// ERROR: Bad Peer AS
//
// Send NOTIFICATION and close the connection
- int errorCode = OpenMessageError.ERROR_CODE;
- int errorSubcode = OpenMessageError.BAD_PEER_AS;
+ int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.OpenMessageError.BAD_PEER_AS;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode,
errorSubcode, null);
@@ -268,12 +262,12 @@
* @param bgpSession the BGP Session to use
* @param ctx the Channel Handler Context
* @param message the message to process
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static void parseOptionalParameters(BgpSession bgpSession,
ChannelHandlerContext ctx,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
//
// Get and verify the Optional Parameters Length
@@ -284,7 +278,7 @@
String errorMsg = "Invalid Optional Parameter Length field " +
optParamLength + ". Remaining Optional Parameters " +
message.readableBytes();
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (optParamLength == 0) {
return; // No Optional Parameters
@@ -299,25 +293,25 @@
if (message.readerIndex() >= optParamEnd) {
// ERROR: Malformed Optional Parameters
String errorMsg = "Malformed Optional Parameters";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
int paramLen = message.readUnsignedByte();
if (message.readerIndex() + paramLen > optParamEnd) {
// ERROR: Malformed Optional Parameters
String errorMsg = "Malformed Optional Parameters";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
//
// Extract the Optional Parameter Value based on the Parameter Type
//
switch (paramType) {
- case Capabilities.TYPE:
+ case BgpConstants.Open.Capabilities.TYPE:
// Optional Parameter Type: Capabilities
- if (paramLen < Capabilities.MIN_LENGTH) {
+ if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) {
// ERROR: Malformed Capability
String errorMsg = "Malformed Capability Type " + paramType;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
int capabEnd = message.readerIndex() + paramLen;
int capabCode = message.readUnsignedByte();
@@ -325,16 +319,16 @@
if (message.readerIndex() + capabLen > capabEnd) {
// ERROR: Malformed Capability
String errorMsg = "Malformed Capability Type " + paramType;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
switch (capabCode) {
- case MultiprotocolExtensions.CODE:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE:
// Multiprotocol Extensions Capabilities (RFC 4760)
- if (capabLen != MultiprotocolExtensions.LENGTH) {
+ if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) {
// ERROR: Multiprotocol Extension Length Error
String errorMsg = "Multiprotocol Extension Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// Decode the AFI (2 octets) and SAFI (1 octet)
int afi = message.readUnsignedShort();
@@ -348,20 +342,20 @@
// NOTE: For now we just copy the remote AFI/SAFI setting
// to the local configuration.
//
- if (afi == MultiprotocolExtensions.AFI_IPV4 &&
- safi == MultiprotocolExtensions.SAFI_UNICAST) {
+ if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
+ safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
bgpSession.remoteInfo().setIpv4Unicast();
bgpSession.localInfo().setIpv4Unicast();
- } else if (afi == MultiprotocolExtensions.AFI_IPV4 &&
- safi == MultiprotocolExtensions.SAFI_MULTICAST) {
+ } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
+ safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
bgpSession.remoteInfo().setIpv4Multicast();
bgpSession.localInfo().setIpv4Multicast();
- } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
- safi == MultiprotocolExtensions.SAFI_UNICAST) {
+ } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
+ safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
bgpSession.remoteInfo().setIpv6Unicast();
bgpSession.localInfo().setIpv6Unicast();
- } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
- safi == MultiprotocolExtensions.SAFI_MULTICAST) {
+ } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
+ safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
bgpSession.remoteInfo().setIpv6Multicast();
bgpSession.localInfo().setIpv6Multicast();
} else {
@@ -370,12 +364,12 @@
}
break;
- case Capabilities.As4Octet.CODE:
+ case BgpConstants.Open.Capabilities.As4Octet.CODE:
// Support for 4-octet AS Number Capabilities (RFC 6793)
- if (capabLen != Capabilities.As4Octet.LENGTH) {
+ if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) {
// ERROR: 4-octet AS Number Capability Length Error
String errorMsg = "4-octet AS Number Capability Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
long as4Number = message.readUnsignedInt();
@@ -430,56 +424,72 @@
// IPv4 unicast
if (localInfo.ipv4Unicast()) {
- message.writeByte(Capabilities.TYPE); // Param type
- message.writeByte(Capabilities.MIN_LENGTH +
- MultiprotocolExtensions.LENGTH); // Param len
- message.writeByte(MultiprotocolExtensions.CODE); // Capab. code
- message.writeByte(MultiprotocolExtensions.LENGTH); // Capab. len
- message.writeShort(MultiprotocolExtensions.AFI_IPV4);
+ message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type
+ message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len
+ message.writeShort(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4);
message.writeByte(0); // Reserved field
- message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
}
// IPv4 multicast
if (localInfo.ipv4Multicast()) {
- message.writeByte(Capabilities.TYPE); // Param type
- message.writeByte(Capabilities.MIN_LENGTH +
- MultiprotocolExtensions.LENGTH); // Param len
- message.writeByte(MultiprotocolExtensions.CODE); // Capab. code
- message.writeByte(MultiprotocolExtensions.LENGTH); // Capab. len
- message.writeShort(MultiprotocolExtensions.AFI_IPV4);
+ message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type
+ message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len
+ message.writeShort(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4);
message.writeByte(0); // Reserved field
- message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST);
}
// IPv6 unicast
if (localInfo.ipv6Unicast()) {
- message.writeByte(Capabilities.TYPE); // Param type
- message.writeByte(Capabilities.MIN_LENGTH +
- MultiprotocolExtensions.LENGTH); // Param len
- message.writeByte(MultiprotocolExtensions.CODE); // Capab. code
- message.writeByte(MultiprotocolExtensions.LENGTH); // Capab. len
- message.writeShort(MultiprotocolExtensions.AFI_IPV6);
+ message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type
+ message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len
+ message.writeShort(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6);
message.writeByte(0); // Reserved field
- message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
}
// IPv6 multicast
if (localInfo.ipv6Multicast()) {
- message.writeByte(Capabilities.TYPE); // Param type
- message.writeByte(Capabilities.MIN_LENGTH +
- MultiprotocolExtensions.LENGTH); // Param len
- message.writeByte(MultiprotocolExtensions.CODE); // Capab. code
- message.writeByte(MultiprotocolExtensions.LENGTH); // Capab. len
- message.writeShort(MultiprotocolExtensions.AFI_IPV6);
+ message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type
+ message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len
+ message.writeShort(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6);
message.writeByte(0); // Reserved field
- message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
+ message.writeByte(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST);
}
// 4 octet AS path capability
if (localInfo.as4OctetCapability()) {
- message.writeByte(Capabilities.TYPE); // Param type
- message.writeByte(Capabilities.MIN_LENGTH +
- As4Octet.LENGTH); // Param len
- message.writeByte(As4Octet.CODE); // Capab. code
- message.writeByte(As4Octet.LENGTH); // Capab. len
+ message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type
+ message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+ BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Param len
+ message.writeByte(BgpConstants.Open.Capabilities.As4Octet.CODE); // Capab. code
+ message.writeByte(BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Capab. len
message.writeInt((int) localInfo.as4Number());
}
return message;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java
similarity index 93%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java
index 3abdc79..e7e7f3c 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java
@@ -13,20 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.routingapi.RouteEntry;
import java.util.ArrayList;
import java.util.Objects;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.Ip4Address;
-import org.onosproject.sdnip.RouteEntry;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-
-import com.google.common.base.MoreObjects;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a route in BGP.
@@ -37,7 +35,7 @@
private final byte origin; // Route ORIGIN: IGP, EGP, INCOMPLETE
private final AsPath asPath; // The AS Path
private final long localPref; // The local preference for the route
- private long multiExitDisc = Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
+ private long multiExitDisc = BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
/**
* Class constructor.
@@ -129,8 +127,8 @@
// Find the first Path Segment by ignoring the AS_CONFED_* segments
for (PathSegment pathSegment : asPath.getPathSegments()) {
- if ((pathSegment.getType() == Update.AsPath.AS_SET) ||
- (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) {
+ if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) ||
+ (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) {
firstPathSegment = pathSegment;
break;
}
@@ -139,7 +137,7 @@
return true; // Local route: no path segments
}
// If the first path segment is AS_SET, the route is considered local
- if (firstPathSegment.getType() == Update.AsPath.AS_SET) {
+ if (firstPathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) {
return true;
}
@@ -164,8 +162,8 @@
// Find the first Path Segment by ignoring the AS_CONFED_* segments
for (PathSegment pathSegment : asPath.getPathSegments()) {
- if ((pathSegment.getType() == Update.AsPath.AS_SET) ||
- (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) {
+ if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) ||
+ (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) {
firstPathSegment = pathSegment;
break;
}
@@ -340,7 +338,7 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("type", Update.AsPath.typeToString(type))
+ .add("type", BgpConstants.Update.AsPath.typeToString(type))
.add("segmentAsNumbers", this.segmentAsNumbers)
.toString();
}
@@ -370,16 +368,16 @@
int pl = 0;
for (PathSegment pathSegment : pathSegments) {
switch (pathSegment.getType()) {
- case Update.AsPath.AS_SET:
+ case BgpConstants.Update.AsPath.AS_SET:
pl++; // AS_SET counts as 1
break;
- case Update.AsPath.AS_SEQUENCE:
+ case BgpConstants.Update.AsPath.AS_SEQUENCE:
// Count each AS number
pl += pathSegment.getSegmentAsNumbers().size();
break;
- case Update.AsPath.AS_CONFED_SEQUENCE:
+ case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
break; // Ignore
- case Update.AsPath.AS_CONFED_SET:
+ case BgpConstants.Update.AsPath.AS_CONFED_SET:
break; // Ignore
default:
// NOTE: What to do if the Path Segment type is unknown?
@@ -487,7 +485,7 @@
.add("prefix", prefix())
.add("nextHop", nextHop())
.add("bgpId", bgpSession.remoteInfo().bgpId())
- .add("origin", Update.Origin.typeToString(origin))
+ .add("origin", BgpConstants.Update.Origin.typeToString(origin))
.add("asPath", asPath)
.add("localPref", localPref)
.add("multiExitDisc", multiExitDisc)
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java
similarity index 98%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java
index 1569c07..e95aaff 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.routingapi.RouteUpdate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.LinkedList;
-import org.onlab.packet.IpPrefix;
-import org.onosproject.sdnip.RouteUpdate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* Class to receive and process the BGP routes from each BGP Session/Peer.
*/
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java
similarity index 97%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java
index ace6b53..e0a2617 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java
@@ -13,15 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandlerContext;
@@ -32,15 +24,21 @@
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.Timer;
import org.jboss.netty.util.TimerTask;
-import org.onlab.packet.IpPrefix;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Prefix;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired;
+import org.onlab.packet.IpPrefix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
/**
* Class for handling the BGP peer sessions.
* There is one instance per each BGP peer session.
@@ -463,8 +461,8 @@
// ERROR: Invalid Optional Parameter Length field: Unspecific
//
// Send NOTIFICATION and close the connection
- int errorCode = HoldTimerExpired.ERROR_CODE;
- int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
+ int errorCode = BgpConstants.Notifications.HoldTimerExpired.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java
similarity index 99%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java
index a492d80..a127455 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
+
+import org.onlab.packet.Ip4Address;
import java.net.SocketAddress;
-import org.onlab.packet.Ip4Address;
/**
* Class for keeping information about a BGP session.
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
similarity index 93%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
index 2ca2972..cfd0081 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelException;
@@ -29,7 +31,8 @@
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Prefix;
import org.onlab.packet.IpPrefix;
-import org.onosproject.sdnip.RouteListener;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.RouteListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,7 +50,9 @@
/**
* BGP Session Manager class.
*/
-public class BgpSessionManager {
+@Component(immediate = true)
+@Service
+public class BgpSessionManager implements BgpInfoService, BgpService {
private static final Logger log =
LoggerFactory.getLogger(BgpSessionManager.class);
@@ -65,16 +70,7 @@
private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 =
new ConcurrentHashMap<>();
- private final RouteListener routeListener;
-
- /**
- * Constructor for given route listener.
- *
- * @param routeListener the route listener to use
- */
- public BgpSessionManager(RouteListener routeListener) {
- this.routeListener = checkNotNull(routeListener);
- }
+ private RouteListener routeListener;
/**
* Checks whether the BGP Session Manager is shutdown.
@@ -248,16 +244,13 @@
return bgpRouteSelector;
}
- /**
- * Starts up BGP Session Manager operation.
- *
- * @param listenPortNumber the port number to listen on. By default
- * it should be BgpConstants.BGP_PORT (179)
- */
- public void start(int listenPortNumber) {
+ @Override
+ public void start(RouteListener routeListener, int listenPortNumber) {
log.debug("BGP Session Manager start.");
isShutdown = false;
+ this.routeListener = checkNotNull(routeListener);
+
ChannelFactory channelFactory = new NioServerSocketChannelFactory(
newCachedThreadPool(namedThreads("onos-bgp-sm-boss-%d")),
newCachedThreadPool(namedThreads("onos-bgp-sm-worker-%d")));
@@ -294,9 +287,7 @@
}
}
- /**
- * Stops the BGP Session Manager operation.
- */
+ @Override
public void stop() {
isShutdown = true;
allChannels.close().awaitUninterruptibly();
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java
similarity index 87%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java
index 2068324..e9abd9c 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java
@@ -13,12 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+package org.onosproject.routing.bgp;
import org.apache.commons.lang3.tuple.Pair;
import org.jboss.netty.buffer.ChannelBuffer;
@@ -28,14 +23,14 @@
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.Ip6Prefix;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-import org.onosproject.sdnip.bgp.BgpConstants.Update.AsPath;
-import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* A class for handling BGP UPDATE messages.
*/
@@ -102,7 +97,7 @@
try {
withdrawnPrefixes = parsePackedIp4Prefixes(withdrawnRoutesLength,
message);
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
// ERROR: Invalid Network Field
log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
bgpSession.remoteInfo().bgpId(), e);
@@ -124,7 +119,7 @@
//
try {
parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes);
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
log.debug("Exception parsing Path Attributes from BGP peer {}: ",
bgpSession.remoteInfo().bgpId(), e);
// NOTE: The session was already closed, so nothing else to do
@@ -179,7 +174,7 @@
* @param decodedBgpRoutes the container to store the decoded BGP Route
* Entries. It might already contain some route entries such as withdrawn
* IPv4 prefixes
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
// CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
private static void parsePathAttributes(
@@ -187,7 +182,7 @@
ChannelHandlerContext ctx,
ChannelBuffer message,
DecodedBgpRoutes decodedBgpRoutes)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
//
// Parsed values
@@ -195,10 +190,11 @@
Short origin = -1; // Mandatory
BgpRouteEntry.AsPath asPath = null; // Mandatory
// Legacy NLRI (RFC 4271). Mandatory NEXT_HOP if legacy NLRI is used
- MpNlri legacyNlri = new MpNlri(MultiprotocolExtensions.AFI_IPV4,
- MultiprotocolExtensions.SAFI_UNICAST);
+ MpNlri legacyNlri = new MpNlri(
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4,
+ BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
long multiExitDisc = // Optional
- Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
+ BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
Long localPref = null; // Mandatory
Long aggregatorAsNumber = null; // Optional: unused
Ip4Address aggregatorIpAddress = null; // Optional: unused
@@ -213,7 +209,7 @@
// ERROR: Malformed Attribute List
actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
String errorMsg = "Malformed Attribute List";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (pathAttributeLength == 0) {
return;
@@ -229,7 +225,7 @@
// ERROR: Malformed Attribute List
actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
String errorMsg = "Malformed Attribute List";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
int attrTypeCode = message.readUnsignedByte();
@@ -249,7 +245,7 @@
// ERROR: Malformed Attribute List
actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
String errorMsg = "Malformed Attribute List";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (extendedLengthBit) {
attrLen = message.readUnsignedShort();
@@ -260,7 +256,7 @@
// ERROR: Malformed Attribute List
actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
String errorMsg = "Malformed Attribute List";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// Verify the Attribute Flags
@@ -272,21 +268,21 @@
//
switch (attrTypeCode) {
- case Update.Origin.TYPE:
+ case BgpConstants.Update.Origin.TYPE:
// Attribute Type Code ORIGIN
origin = parseAttributeTypeOrigin(bgpSession, ctx,
attrTypeCode, attrLen,
attrFlags, message);
break;
- case Update.AsPath.TYPE:
+ case BgpConstants.Update.AsPath.TYPE:
// Attribute Type Code AS_PATH
asPath = parseAttributeTypeAsPath(bgpSession, ctx,
attrTypeCode, attrLen,
attrFlags, message);
break;
- case Update.NextHop.TYPE:
+ case BgpConstants.Update.NextHop.TYPE:
// Attribute Type Code NEXT_HOP
legacyNlri.nextHop4 =
parseAttributeTypeNextHop(bgpSession, ctx,
@@ -294,7 +290,7 @@
attrFlags, message);
break;
- case Update.MultiExitDisc.TYPE:
+ case BgpConstants.Update.MultiExitDisc.TYPE:
// Attribute Type Code MULTI_EXIT_DISC
multiExitDisc =
parseAttributeTypeMultiExitDisc(bgpSession, ctx,
@@ -302,7 +298,7 @@
attrFlags, message);
break;
- case Update.LocalPref.TYPE:
+ case BgpConstants.Update.LocalPref.TYPE:
// Attribute Type Code LOCAL_PREF
localPref =
parseAttributeTypeLocalPref(bgpSession, ctx,
@@ -310,7 +306,7 @@
attrFlags, message);
break;
- case Update.AtomicAggregate.TYPE:
+ case BgpConstants.Update.AtomicAggregate.TYPE:
// Attribute Type Code ATOMIC_AGGREGATE
parseAttributeTypeAtomicAggregate(bgpSession, ctx,
attrTypeCode, attrLen,
@@ -318,7 +314,7 @@
// Nothing to do: this attribute is primarily informational
break;
- case Update.Aggregator.TYPE:
+ case BgpConstants.Update.Aggregator.TYPE:
// Attribute Type Code AGGREGATOR
Pair<Long, Ip4Address> aggregator =
parseAttributeTypeAggregator(bgpSession, ctx,
@@ -328,7 +324,7 @@
aggregatorIpAddress = aggregator.getRight();
break;
- case Update.MpReachNlri.TYPE:
+ case BgpConstants.Update.MpReachNlri.TYPE:
// Attribute Type Code MP_REACH_NLRI
MpNlri mpNlriReach =
parseAttributeTypeMpReachNlri(bgpSession, ctx,
@@ -340,7 +336,7 @@
}
break;
- case Update.MpUnreachNlri.TYPE:
+ case BgpConstants.Update.MpUnreachNlri.TYPE:
// Attribute Type Code MP_UNREACH_NLRI
MpNlri mpNlriUnreach =
parseAttributeTypeMpUnreachNlri(bgpSession, ctx,
@@ -360,7 +356,7 @@
message);
String errorMsg = "Unrecognized Well-known Attribute: " +
attrTypeCode;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// Skip the data from the unrecognized attribute
@@ -381,7 +377,7 @@
parsePackedIp4Prefixes(nlriLength, message);
// Store it inside the legacy NLRI wrapper
legacyNlri.nlri4 = addedPrefixes4;
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
// ERROR: Invalid Network Field
log.debug("Exception parsing NLRI from BGP peer {}: ",
bgpSession.remoteInfo().bgpId(), e);
@@ -486,7 +482,7 @@
* @param legacyNlri the legacy NLRI. Encapsulates the NEXT_HOP well-known
* mandatory attribute (mandatory if legacy NLRI is used).
* @param mpNlriReachList the Multiprotocol NLRI attributes
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static void verifyBgpUpdateWellKnownAttributes(
BgpSession bgpSession,
@@ -496,7 +492,7 @@
Long localPref,
MpNlri legacyNlri,
Collection<MpNlri> mpNlriReachList)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
boolean hasNlri = false;
boolean hasLegacyNlri = false;
@@ -525,32 +521,32 @@
//
if (hasNlri && ((origin == null) || (origin == -1))) {
// Missing Attribute Type Code ORIGIN
- int type = Update.Origin.TYPE;
+ int type = BgpConstants.Update.Origin.TYPE;
actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
String errorMsg = "Missing Well-known Attribute: ORIGIN";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (hasNlri && (asPath == null)) {
// Missing Attribute Type Code AS_PATH
- int type = Update.AsPath.TYPE;
+ int type = BgpConstants.Update.AsPath.TYPE;
actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
String errorMsg = "Missing Well-known Attribute: AS_PATH";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (hasNlri && (localPref == null)) {
// Missing Attribute Type Code LOCAL_PREF
// NOTE: Required for iBGP
- int type = Update.LocalPref.TYPE;
+ int type = BgpConstants.Update.LocalPref.TYPE;
actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
String errorMsg = "Missing Well-known Attribute: LOCAL_PREF";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
if (hasLegacyNlri && (legacyNlri.nextHop4 == null)) {
// Missing Attribute Type Code NEXT_HOP
- int type = Update.NextHop.TYPE;
+ int type = BgpConstants.Update.NextHop.TYPE;
actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
String errorMsg = "Missing Well-known Attribute: NEXT_HOP";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
}
@@ -563,7 +559,7 @@
* @param attrLen the attribute length (in octets)
* @param attrFlags the attribute flags
* @param message the message to parse
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static void verifyBgpUpdateAttributeFlags(
BgpSession bgpSession,
@@ -572,7 +568,7 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
//
// Assign the Attribute Type Name and the Well-known flag
@@ -580,39 +576,39 @@
String typeName = "UNKNOWN";
boolean isWellKnown = false;
switch (attrTypeCode) {
- case Update.Origin.TYPE:
+ case BgpConstants.Update.Origin.TYPE:
isWellKnown = true;
typeName = "ORIGIN";
break;
- case Update.AsPath.TYPE:
+ case BgpConstants.Update.AsPath.TYPE:
isWellKnown = true;
typeName = "AS_PATH";
break;
- case Update.NextHop.TYPE:
+ case BgpConstants.Update.NextHop.TYPE:
isWellKnown = true;
typeName = "NEXT_HOP";
break;
- case Update.MultiExitDisc.TYPE:
+ case BgpConstants.Update.MultiExitDisc.TYPE:
isWellKnown = false;
typeName = "MULTI_EXIT_DISC";
break;
- case Update.LocalPref.TYPE:
+ case BgpConstants.Update.LocalPref.TYPE:
isWellKnown = true;
typeName = "LOCAL_PREF";
break;
- case Update.AtomicAggregate.TYPE:
+ case BgpConstants.Update.AtomicAggregate.TYPE:
isWellKnown = true;
typeName = "ATOMIC_AGGREGATE";
break;
- case Update.Aggregator.TYPE:
+ case BgpConstants.Update.Aggregator.TYPE:
isWellKnown = false;
typeName = "AGGREGATOR";
break;
- case Update.MpReachNlri.TYPE:
+ case BgpConstants.Update.MpReachNlri.TYPE:
isWellKnown = false;
typeName = "MP_REACH_NLRI";
break;
- case Update.MpUnreachNlri.TYPE:
+ case BgpConstants.Update.MpUnreachNlri.TYPE:
isWellKnown = false;
typeName = "MP_UNREACH_NLRI";
break;
@@ -643,7 +639,7 @@
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Flags Error for " + typeName + ": " +
attrFlags;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
}
@@ -657,7 +653,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed ORIGIN value
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static short parseAttributeTypeOrigin(
BgpSession bgpSession,
@@ -666,25 +662,25 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.Origin.LENGTH) {
+ if (attrLen != BgpConstants.Update.Origin.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.markReaderIndex();
short origin = message.readUnsignedByte();
switch (origin) {
- case Update.Origin.IGP:
+ case BgpConstants.Update.Origin.IGP:
// FALLTHROUGH
- case Update.Origin.EGP:
+ case BgpConstants.Update.Origin.EGP:
// FALLTHROUGH
- case Update.Origin.INCOMPLETE:
+ case BgpConstants.Update.Origin.INCOMPLETE:
break;
default:
// ERROR: Invalid ORIGIN Attribute
@@ -693,7 +689,7 @@
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
origin);
String errorMsg = "Invalid ORIGIN Attribute: " + origin;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
return origin;
@@ -709,7 +705,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed AS Path
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static BgpRouteEntry.AsPath parseAttributeTypeAsPath(
BgpSession bgpSession,
@@ -718,7 +714,7 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
//
@@ -729,7 +725,7 @@
// ERROR: Malformed AS_PATH
actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
String errorMsg = "Malformed AS Path";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// Get the Path Segment Type and Length (in number of ASes)
short pathSegmentType = message.readUnsignedByte();
@@ -738,13 +734,13 @@
// Verify the Path Segment Type
switch (pathSegmentType) {
- case Update.AsPath.AS_SET:
+ case BgpConstants.Update.AsPath.AS_SET:
// FALLTHROUGH
- case Update.AsPath.AS_SEQUENCE:
+ case BgpConstants.Update.AsPath.AS_SEQUENCE:
// FALLTHROUGH
- case Update.AsPath.AS_CONFED_SEQUENCE:
+ case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
// FALLTHROUGH
- case Update.AsPath.AS_CONFED_SET:
+ case BgpConstants.Update.AsPath.AS_CONFED_SET:
break;
default:
// ERROR: Invalid Path Segment Type
@@ -756,15 +752,15 @@
actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
String errorMsg =
"Invalid AS Path Segment Type: " + pathSegmentType;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// 4-octet AS number handling.
int asPathLen;
if (bgpSession.isAs4OctetCapable()) {
- asPathLen = AsPath.AS_4OCTET_LENGTH;
+ asPathLen = BgpConstants.Update.AsPath.AS_4OCTET_LENGTH;
} else {
- asPathLen = AsPath.AS_LENGTH;
+ asPathLen = BgpConstants.Update.AsPath.AS_LENGTH;
}
// Parse the AS numbers
@@ -772,13 +768,13 @@
// ERROR: Malformed AS_PATH
actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
String errorMsg = "Malformed AS Path";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
attrLen -= (asPathLen * pathSegmentLength);
ArrayList<Long> segmentAsNumbers = new ArrayList<>();
while (pathSegmentLength-- > 0) {
long asNumber;
- if (asPathLen == AsPath.AS_4OCTET_LENGTH) {
+ if (asPathLen == BgpConstants.Update.AsPath.AS_4OCTET_LENGTH) {
asNumber = message.readUnsignedInt();
} else {
asNumber = message.readUnsignedShort();
@@ -805,7 +801,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed NEXT_HOP value
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static Ip4Address parseAttributeTypeNextHop(
BgpSession bgpSession,
@@ -814,15 +810,15 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.NextHop.LENGTH) {
+ if (attrLen != BgpConstants.Update.NextHop.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.markReaderIndex();
@@ -845,7 +841,7 @@
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
nextHopAddress);
String errorMsg = "Invalid NEXT_HOP Attribute: " + nextHopAddress;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
return nextHopAddress;
@@ -861,7 +857,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed MULTI_EXIT_DISC value
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static long parseAttributeTypeMultiExitDisc(
BgpSession bgpSession,
@@ -870,15 +866,15 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.MultiExitDisc.LENGTH) {
+ if (attrLen != BgpConstants.Update.MultiExitDisc.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
long multiExitDisc = message.readUnsignedInt();
@@ -895,7 +891,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed LOCAL_PREF value
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static long parseAttributeTypeLocalPref(
BgpSession bgpSession,
@@ -904,15 +900,15 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.LocalPref.LENGTH) {
+ if (attrLen != BgpConstants.Update.LocalPref.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
long localPref = message.readUnsignedInt();
@@ -928,7 +924,7 @@
* @param attrLen the attribute length (in octets)
* @param attrFlags the attribute flags
* @param message the message to parse
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static void parseAttributeTypeAtomicAggregate(
BgpSession bgpSession,
@@ -937,15 +933,15 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.AtomicAggregate.LENGTH) {
+ if (attrLen != BgpConstants.Update.AtomicAggregate.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// Nothing to do: this attribute is primarily informational
@@ -961,7 +957,7 @@
* @param attrFlags the attribute flags
* @param message the message to parse
* @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address>
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static Pair<Long, Ip4Address> parseAttributeTypeAggregator(
BgpSession bgpSession,
@@ -970,15 +966,15 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
// Check the Attribute Length
- if (attrLen != Update.Aggregator.LENGTH) {
+ if (attrLen != BgpConstants.Update.Aggregator.LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// The AGGREGATOR AS number
@@ -1003,7 +999,7 @@
* @param message the message to parse
* @return the parsed MP_REACH_NLRI information if recognized, otherwise
* null
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static MpNlri parseAttributeTypeMpReachNlri(
BgpSession bgpSession,
@@ -1012,16 +1008,16 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
int attributeEnd = message.readerIndex() + attrLen;
// Check the Attribute Length
- if (attrLen < Update.MpReachNlri.MIN_LENGTH) {
+ if (attrLen < BgpConstants.Update.MpReachNlri.MIN_LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.markReaderIndex();
@@ -1033,9 +1029,9 @@
// Verify the AFI/SAFI, and skip the attribute if not recognized.
// NOTE: Currently, we support only IPv4/IPv6 UNICAST
//
- if (((afi != MultiprotocolExtensions.AFI_IPV4) &&
- (afi != MultiprotocolExtensions.AFI_IPV6)) ||
- (safi != MultiprotocolExtensions.SAFI_UNICAST)) {
+ if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) &&
+ (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) ||
+ (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) {
// Skip the attribute
message.resetReaderIndex();
message.skipBytes(attrLen);
@@ -1047,10 +1043,10 @@
//
int expectedNextHopLen = 0;
switch (afi) {
- case MultiprotocolExtensions.AFI_IPV4:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
expectedNextHopLen = Ip4Address.BYTE_LENGTH;
break;
- case MultiprotocolExtensions.AFI_IPV6:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
expectedNextHopLen = Ip6Address.BYTE_LENGTH;
break;
default:
@@ -1064,7 +1060,7 @@
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Invalid next-hop network address length. " +
"Received " + nextHopLen + " expected " + expectedNextHopLen;
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
// NOTE: We use "+ 1" to take into account the Reserved field (1 octet)
if (message.readerIndex() + nextHopLen + 1 >= attributeEnd) {
@@ -1073,7 +1069,7 @@
actionsBgpUpdateOptionalAttributeError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Malformed next-hop network address";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
//
@@ -1085,7 +1081,7 @@
MpNlri mpNlri = new MpNlri(afi, safi);
try {
switch (afi) {
- case MultiprotocolExtensions.AFI_IPV4:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
// The next-hop address
mpNlri.nextHop4 = Ip4Address.valueOf(nextHopBuffer);
// The NLRI
@@ -1093,7 +1089,7 @@
attributeEnd - message.readerIndex(),
message);
break;
- case MultiprotocolExtensions.AFI_IPV6:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
// The next-hop address
mpNlri.nextHop6 = Ip6Address.valueOf(nextHopBuffer);
// The NLRI
@@ -1105,13 +1101,13 @@
// UNREACHABLE
break;
}
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
// ERROR: Optional Attribute Error
message.resetReaderIndex();
actionsBgpUpdateOptionalAttributeError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Malformed network layer reachability information";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
return mpNlri;
@@ -1128,7 +1124,7 @@
* @param message the message to parse
* @return the parsed MP_UNREACH_NLRI information if recognized, otherwise
* null
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static MpNlri parseAttributeTypeMpUnreachNlri(
BgpSession bgpSession,
@@ -1137,16 +1133,16 @@
int attrLen,
int attrFlags,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
int attributeEnd = message.readerIndex() + attrLen;
// Check the Attribute Length
- if (attrLen < Update.MpUnreachNlri.MIN_LENGTH) {
+ if (attrLen < BgpConstants.Update.MpUnreachNlri.MIN_LENGTH) {
// ERROR: Attribute Length Error
actionsBgpUpdateAttributeLengthError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Attribute Length Error";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.markReaderIndex();
@@ -1157,9 +1153,9 @@
// Verify the AFI/SAFI, and skip the attribute if not recognized.
// NOTE: Currently, we support only IPv4/IPv6 UNICAST
//
- if (((afi != MultiprotocolExtensions.AFI_IPV4) &&
- (afi != MultiprotocolExtensions.AFI_IPV6)) ||
- (safi != MultiprotocolExtensions.SAFI_UNICAST)) {
+ if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) &&
+ (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) ||
+ (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) {
// Skip the attribute
message.resetReaderIndex();
message.skipBytes(attrLen);
@@ -1172,13 +1168,13 @@
MpNlri mpNlri = new MpNlri(afi, safi);
try {
switch (afi) {
- case MultiprotocolExtensions.AFI_IPV4:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
// The Withdrawn Routes
mpNlri.nlri4 = parsePackedIp4Prefixes(
attributeEnd - message.readerIndex(),
message);
break;
- case MultiprotocolExtensions.AFI_IPV6:
+ case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
// The Withdrawn Routes
mpNlri.nlri6 = parsePackedIp6Prefixes(
attributeEnd - message.readerIndex(),
@@ -1188,13 +1184,13 @@
// UNREACHABLE
break;
}
- } catch (BgpParseException e) {
+ } catch (BgpMessage.BgpParseException e) {
// ERROR: Optional Attribute Error
message.resetReaderIndex();
actionsBgpUpdateOptionalAttributeError(
bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
String errorMsg = "Malformed withdrawn routes";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
return mpNlri;
@@ -1211,12 +1207,12 @@
* @param totalLength the total length of the data to parse
* @param message the message with data to parse
* @return a collection of parsed IPv4 network prefixes
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static Collection<Ip4Prefix> parsePackedIp4Prefixes(
int totalLength,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
Collection<Ip4Prefix> result = new ArrayList<>();
if (totalLength == 0) {
@@ -1231,7 +1227,7 @@
int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up
if (message.readerIndex() + prefixBytelen > dataEnd) {
String errorMsg = "Malformed Network Prefixes";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.readBytes(buffer, 0, prefixBytelen);
@@ -1254,12 +1250,12 @@
* @param totalLength the total length of the data to parse
* @param message the message with data to parse
* @return a collection of parsed IPv6 network prefixes
- * @throws BgpParseException
+ * @throws BgpMessage.BgpParseException
*/
private static Collection<Ip6Prefix> parsePackedIp6Prefixes(
int totalLength,
ChannelBuffer message)
- throws BgpParseException {
+ throws BgpMessage.BgpParseException {
Collection<Ip6Prefix> result = new ArrayList<>();
if (totalLength == 0) {
@@ -1274,7 +1270,7 @@
int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up
if (message.readerIndex() + prefixBytelen > dataEnd) {
String errorMsg = "Malformed Network Prefixes";
- throw new BgpParseException(errorMsg);
+ throw new BgpMessage.BgpParseException(errorMsg);
}
message.readBytes(buffer, 0, prefixBytelen);
@@ -1303,8 +1299,8 @@
// ERROR: Invalid Network Field
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.INVALID_NETWORK_FIELD;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NETWORK_FIELD;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
@@ -1329,8 +1325,8 @@
// ERROR: Malformed Attribute List
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.MALFORMED_ATTRIBUTE_LIST;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_ATTRIBUTE_LIST;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
@@ -1358,8 +1354,8 @@
// ERROR: Missing Well-known Attribute
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE;
ChannelBuffer data = ChannelBuffers.buffer(1);
data.writeByte(missingAttrTypeCode);
ChannelBuffer txMessage =
@@ -1396,8 +1392,8 @@
// ERROR: Invalid ORIGIN Attribute
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1433,8 +1429,8 @@
// ERROR: Attribute Flags Error
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.ATTRIBUTE_FLAGS_ERROR;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_FLAGS_ERROR;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1473,8 +1469,8 @@
// ERROR: Invalid NEXT_HOP Attribute
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1512,9 +1508,9 @@
// ERROR: Unrecognized Well-known Attribute
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
int errorSubcode =
- UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE;
+ BgpConstants.Notifications.UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1551,9 +1547,9 @@
// ERROR: Optional Attribute Error
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
int errorSubcode =
- UpdateMessageError.OPTIONAL_ATTRIBUTE_ERROR;
+ BgpConstants.Notifications.UpdateMessageError.OPTIONAL_ATTRIBUTE_ERROR;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1589,8 +1585,8 @@
// ERROR: Attribute Length Error
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.ATTRIBUTE_LENGTH_ERROR;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_LENGTH_ERROR;
ChannelBuffer data =
prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
attrFlags, message);
@@ -1618,8 +1614,8 @@
// ERROR: Malformed AS_PATH
//
// Send NOTIFICATION and close the connection
- int errorCode = UpdateMessageError.ERROR_CODE;
- int errorSubcode = UpdateMessageError.MALFORMED_AS_PATH;
+ int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+ int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_AS_PATH;
ChannelBuffer txMessage =
BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
null);
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java
similarity index 94%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java
rename to apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java
index 9e1b5d2..e4259b6 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java
@@ -17,4 +17,4 @@
/**
* Implementation of the BGP protocol.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java
similarity index 96%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
rename to apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java
index fe2a4a4..b3cb6d0 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java
@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.cli;
-
-import java.util.Collection;
+package org.onosproject.routing.cli;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -24,8 +22,10 @@
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.SdnIpService;
-import org.onosproject.sdnip.bgp.BgpSession;
+import org.onosproject.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpSession;
+
+import java.util.Collection;
/**
* Command to show the BGP neighbors.
@@ -53,7 +53,7 @@
@Override
protected void execute() {
- SdnIpService service = get(SdnIpService.class);
+ BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
Collection<BgpSession> bgpSessions = service.getBgpSessions();
if (bgpNeighbor != null) {
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
similarity index 96%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
rename to apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
index a3b19df..3b032c0 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
@@ -13,10 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.cli;
-
-import java.util.ArrayList;
-import java.util.Collection;
+package org.onosproject.routing.cli;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -25,10 +22,13 @@
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.SdnIpService;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
+import org.onosproject.routing.bgp.BgpConstants.Update;
+import org.onosproject.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpRouteEntry;
+import org.onosproject.routing.bgp.BgpSession;
+
+import java.util.ArrayList;
+import java.util.Collection;
/**
* Command to show the routes learned through BGP.
@@ -59,7 +59,7 @@
@Override
protected void execute() {
- SdnIpService service = get(SdnIpService.class);
+ BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
// Print summary of the routes
if (routesSummary) {
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java
similarity index 95%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java
rename to apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java
index cebbc43..6c9d688 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java
@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.cli;
-
-import java.util.Collection;
+package org.onosproject.routing.cli;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -24,8 +22,10 @@
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.RouteEntry;
-import org.onosproject.sdnip.SdnIpService;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RoutingService;
+
+import java.util.Collection;
/**
* Command to show the list of routes in SDN-IP's routing table.
@@ -49,7 +49,7 @@
@Override
protected void execute() {
- SdnIpService service = get(SdnIpService.class);
+ RoutingService service = AbstractShellCommand.get(RoutingService.class);
// Print summary of the routes
if (routesSummary) {
diff --git a/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..5ef971d
--- /dev/null
+++ b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,29 @@
+<!--
+ ~ 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.
+ -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+ <command>
+ <action class="org.onosproject.routing.cli.BgpNeighborsListCommand"/>
+ </command>
+ <command>
+ <action class="org.onosproject.routing.cli.BgpRoutesListCommand"/>
+ </command>
+ <command>
+ <action class="org.onosproject.routing.cli.RoutesListCommand"/>
+ </command>
+ </command-bundle>
+</blueprint>
diff --git a/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java b/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java
new file mode 100644
index 0000000..d9a5ce9
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2014 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.routing;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routing.Router.InternalHostListener;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+
+/**
+* This class tests adding a route and updating a route.
+* The HostService module answers the MAC address asynchronously.
+*/
+public class RouterAsyncArpTest {
+
+ private HostService hostService;
+ private FibListener fibListener;
+
+ private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000001"),
+ PortNumber.portNumber(1));
+
+ private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000002"),
+ PortNumber.portNumber(1));
+
+ private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000003"),
+ PortNumber.portNumber(1));
+
+ private Router router;
+ private InternalHostListener internalHostListener;
+
+ @Before
+ public void setUp() throws Exception {
+ hostService = createMock(HostService.class);
+
+ BgpService bgpService = createMock(BgpService.class);
+ bgpService.start(anyObject(RouteListener.class), anyInt());
+ bgpService.stop();
+ replay(bgpService);
+
+ fibListener = createMock(FibListener.class);
+
+ router = new Router();
+ router.hostService = hostService;
+ router.bgpService = bgpService;
+ router.activate();
+
+ router.start(fibListener);
+
+ internalHostListener = router.new InternalHostListener();
+ }
+
+ @After
+ public void tearDown() {
+ // Called during shutdown
+ reset(hostService);
+ hostService.removeListener(anyObject(HostListener.class));
+
+ router.stop();
+ }
+
+ /**
+ * Tests adding a route entry with asynchronous HostService replies.
+ */
+ @Test
+ public void testRouteAdd() {
+ // Construct a route entry
+ IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+ IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
+
+ RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+ // Host service will reply with no hosts when asked
+ reset(hostService);
+ expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
+ Collections.emptySet()).anyTimes();
+ hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
+ replay(hostService);
+
+
+ // Initially when we add the route, no FIB update will be sent
+ replay(fibListener);
+
+ router.processRouteUpdates(Collections.singletonList(
+ new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+ verify(fibListener);
+
+
+ // Now when we send the event, we expect the FIB update to be sent
+ reset(fibListener);
+ FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+ MacAddress.valueOf("00:00:00:00:00:01"));
+
+ fibListener.update(Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+ replay(fibListener);
+
+ Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
+ MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
+ new HostLocation(
+ SW1_ETH1.deviceId(),
+ SW1_ETH1.port(), 1),
+ Sets.newHashSet(IpAddress.valueOf("192.168.10.1")));
+
+ // Send in the host event
+ internalHostListener.event(
+ new HostEvent(HostEvent.Type.HOST_ADDED, host));
+
+ verify(fibListener);
+ }
+
+ /**
+ * Tests updating a route entry with asynchronous HostService replies.
+ */
+ @Test
+ public void testRouteUpdate() {
+ // Add a route
+ testRouteAdd();
+
+ // Construct a route entry
+ IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+ IpAddress nextHopIp = Ip4Address.valueOf("192.168.20.1");
+
+ RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+ // Host service will reply with no hosts when asked
+ reset(hostService);
+ expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
+ Collections.emptySet()).anyTimes();
+ hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
+ replay(hostService);
+
+
+ // Initially when we add the route, the DELETE FIB update will be sent
+ // but the UPDATE FIB update will come later when the MAC is resolved
+ reset(fibListener);
+
+ fibListener.update(Collections.emptyList(), Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.DELETE, new FibEntry(prefix, null, null))));
+ replay(fibListener);
+
+ router.processRouteUpdates(Collections.singletonList(
+ new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+ verify(fibListener);
+
+
+ // Now when we send the event, we expect the FIB update to be sent
+ reset(fibListener);
+ FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+ MacAddress.valueOf("00:00:00:00:00:02"));
+
+ fibListener.update(Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+ replay(fibListener);
+
+ Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
+ MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
+ new HostLocation(
+ SW1_ETH1.deviceId(),
+ SW1_ETH1.port(), 1),
+ Sets.newHashSet(IpAddress.valueOf("192.168.20.1")));
+
+ // Send in the host event
+ internalHostListener.event(
+ new HostEvent(HostEvent.Type.HOST_ADDED, host));
+
+ verify(fibListener);
+ }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java b/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java
new file mode 100644
index 0000000..176c159
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 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.routing;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This class tests adding a route, updating a route, deleting a route,
+ * and adding a route whose next hop is the local BGP speaker.
+ * <p/>
+ * The HostService answers requests synchronously.
+ */
+public class RouterTest {
+
+ private HostService hostService;
+
+ private FibListener fibListener;
+
+ private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000001"),
+ PortNumber.portNumber(1));
+
+ private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000002"),
+ PortNumber.portNumber(1));
+
+ private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000003"),
+ PortNumber.portNumber(1));
+
+ private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000004"),
+ PortNumber.portNumber(1));
+
+ private Router router;
+
+ @Before
+ public void setUp() throws Exception {
+ setUpHostService();
+
+ BgpService bgpService = createMock(BgpService.class);
+ bgpService.start(anyObject(RouteListener.class), anyInt());
+ bgpService.stop();
+ replay(bgpService);
+
+ fibListener = createMock(FibListener.class);
+
+ router = new Router();
+ router.hostService = hostService;
+ router.bgpService = bgpService;
+ router.activate();
+
+ router.start(fibListener);
+ }
+
+ @After
+ public void tearDown() {
+ router.stop();
+ }
+
+ /**
+ * Sets up the host service with details of some hosts.
+ */
+ private void setUpHostService() {
+ hostService = createMock(HostService.class);
+
+ hostService.addListener(anyObject(HostListener.class));
+ expectLastCall().anyTimes();
+
+ IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
+ Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+ MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
+ new HostLocation(SW1_ETH1, 1),
+ Sets.newHashSet(host1Address));
+
+ expect(hostService.getHostsByIp(host1Address))
+ .andReturn(Sets.newHashSet(host1)).anyTimes();
+ hostService.startMonitoringIp(host1Address);
+ expectLastCall().anyTimes();
+
+
+ IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
+ Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+ MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
+ new HostLocation(SW2_ETH1, 1),
+ Sets.newHashSet(host2Address));
+
+ expect(hostService.getHostsByIp(host2Address))
+ .andReturn(Sets.newHashSet(host2)).anyTimes();
+ hostService.startMonitoringIp(host2Address);
+ expectLastCall().anyTimes();
+
+ // Next hop on a VLAN
+ IpAddress host3Address = IpAddress.valueOf("192.168.40.1");
+ Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+ MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1),
+ new HostLocation(SW4_ETH1, 1),
+ Sets.newHashSet(host3Address));
+
+ expect(hostService.getHostsByIp(host3Address))
+ .andReturn(Sets.newHashSet(host3)).anyTimes();
+ hostService.startMonitoringIp(host3Address);
+ expectLastCall().anyTimes();
+
+ // Called during shutdown
+ hostService.removeListener(anyObject(HostListener.class));
+
+ replay(hostService);
+ }
+
+ /**
+ * Tests adding a route entry.
+ */
+ @Test
+ public void testRouteAdd() {
+ // Construct a route entry
+ IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+ IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
+
+ RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+ // Expected FIB entry
+ FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+ MacAddress.valueOf("00:00:00:00:00:01"));
+
+ fibListener.update(Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+
+ replay(fibListener);
+
+ router.processRouteUpdates(Collections.singletonList(
+ new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+ verify(fibListener);
+ }
+
+ /**
+ * Tests updating a route entry.
+ */
+ @Test
+ public void testRouteUpdate() {
+ // Firstly add a route
+ testRouteAdd();
+
+ // Route entry with updated next hop for the original prefix
+ RouteEntry routeEntryUpdate = new RouteEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("192.168.20.1"));
+
+ // The old FIB entry will be withdrawn
+ FibEntry withdrawFibEntry = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+ // A new FIB entry will be added
+ FibEntry updateFibEntry = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("192.168.20.1"),
+ MacAddress.valueOf("00:00:00:00:00:02"));
+
+ reset(fibListener);
+ fibListener.update(Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.UPDATE, updateFibEntry)),
+ Collections.singletonList(new FibUpdate(
+ FibUpdate.Type.DELETE, withdrawFibEntry)));
+
+ replay(fibListener);
+
+ router.processRouteUpdates(Collections.singletonList(new RouteUpdate(
+ RouteUpdate.Type.UPDATE, routeEntryUpdate)));
+
+ verify(fibListener);
+ }
+
+ /**
+ * Tests deleting a route entry.
+ */
+ @Test
+ public void testRouteDelete() {
+ // Firstly add a route
+ testRouteAdd();
+
+ RouteEntry deleteRouteEntry = new RouteEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("192.168.10.1"));
+
+ FibEntry deleteFibEntry = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+ reset(fibListener);
+ fibListener.update(Collections.emptyList(), Collections.singletonList(
+ new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry)));
+
+ replay(fibListener);
+
+ router.processRouteUpdates(Collections.singletonList(
+ new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry)));
+
+ verify(fibListener);
+ }
+
+ /**
+ * Tests adding a route whose next hop is the local BGP speaker.
+ */
+ @Test
+ public void testLocalRouteAdd() {
+ // Construct a route entry, the next hop is the local BGP speaker
+ RouteEntry routeEntry = new RouteEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("0.0.0.0"));
+
+ // No methods on the FIB listener should be called
+ replay(fibListener);
+
+ // Call the processRouteUpdates() method in Router class
+ RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
+ routeEntry);
+ router.processRouteUpdates(Collections.singletonList(routeUpdate));
+
+ // Verify
+ assertEquals(1, router.getRoutes4().size());
+ assertTrue(router.getRoutes4().contains(routeEntry));
+ verify(fibListener);
+ }
+}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
similarity index 98%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
index 481ca43..2414eb2 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
@@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
-import java.util.ArrayList;
-
-import org.junit.Test;
-
/**
* Unit tests for the BgpRouteEntry.AsPath class.
*/
@@ -211,7 +212,7 @@
//
BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments);
- assertThat(asPath1, is(not(asPath2)));
+ assertThat(asPath1, Matchers.is(not(asPath2)));
}
/**
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
similarity index 94%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
index d53eb59..ab72b6f 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
@@ -13,22 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-
+import org.easymock.EasyMock;
+import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
/**
* Unit tests for the BgpRouteEntry class.
*/
@@ -63,9 +62,9 @@
@Before
public void setUp() throws Exception {
// Mock objects for testing
- bgpSession = createMock(BgpSession.class);
- bgpSession2 = createMock(BgpSession.class);
- bgpSession3 = createMock(BgpSession.class);
+ bgpSession = EasyMock.createMock(BgpSession.class);
+ bgpSession2 = EasyMock.createMock(BgpSession.class);
+ bgpSession3 = EasyMock.createMock(BgpSession.class);
// Setup the BGP Sessions
remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS);
@@ -75,16 +74,16 @@
remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2);
remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3);
- expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes();
- expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes();
- expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes();
- expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes();
- expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes();
- expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes();
+ EasyMock.expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes();
+ EasyMock.expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes();
+ EasyMock.expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes();
+ EasyMock.expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes();
+ EasyMock.expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes();
+ EasyMock.expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes();
- replay(bgpSession);
- replay(bgpSession2);
- replay(bgpSession3);
+ EasyMock.replay(bgpSession);
+ EasyMock.replay(bgpSession2);
+ EasyMock.replay(bgpSession3);
}
/**
@@ -500,7 +499,7 @@
localPref);
bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
- assertThat(bgpRouteEntry1, is(not(bgpRouteEntry2)));
+ assertThat(bgpRouteEntry1, Matchers.is(not(bgpRouteEntry2)));
}
/**
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
similarity index 98%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
index 7ae8658..c73eaff 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
@@ -13,22 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
+import com.google.common.net.InetAddresses;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.jboss.netty.bootstrap.ClientBootstrap;
@@ -44,12 +31,24 @@
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onosproject.sdnip.RouteListener;
-import org.onosproject.sdnip.RouteUpdate;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
-import com.google.common.net.InetAddresses;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
/**
* Unit tests for the BgpSessionManager class.
@@ -251,9 +250,9 @@
// Setup the BGP Session Manager to test, and start listening for BGP
// connections.
//
- bgpSessionManager = new BgpSessionManager(dummyRouteListener);
+ bgpSessionManager = new BgpSessionManager();
// NOTE: We use port 0 to bind on any available port
- bgpSessionManager.start(0);
+ bgpSessionManager.start(dummyRouteListener, 0);
// Get the port number the BGP Session Manager is listening on
Channel serverChannel = TestUtils.getField(bgpSessionManager,
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
similarity index 96%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
index e8f2ddc..4c6c5fc 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
@@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
+package org.onosproject.routing.bgp;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
-import java.util.ArrayList;
-
-import org.junit.Test;
-
/**
* Unit tests for the BgpRouteEntry.PathSegment class.
*/
@@ -113,7 +114,7 @@
BgpRouteEntry.PathSegment pathSegment2 =
new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
- assertThat(pathSegment1, is(not(pathSegment2)));
+ assertThat(pathSegment1, Matchers.is(not(pathSegment2)));
}
/**
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
similarity index 99%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
index 979a1ed..ac887aa 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
-
-import java.util.Collection;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
@@ -25,6 +23,8 @@
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
+import java.util.Collection;
+
/**
* Class for handling the remote BGP Peer session.
*/
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
similarity index 98%
rename from apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java
rename to apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
index 4f39547..9747ea9 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.sdnip.bgp;
-
-import java.util.concurrent.CountDownLatch;
+package org.onosproject.routing.bgp;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
@@ -23,6 +21,8 @@
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.onlab.packet.Ip4Address;
+import java.util.concurrent.CountDownLatch;
+
/**
* Class for handling the decoding of the BGP messages at the remote
* BGP peer session.
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 920b5e5..925bc58 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -61,11 +61,6 @@
<dependency>
<groupId>org.onosproject</groupId>
- <artifactId>onlab-thirdparty</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
<artifactId>onlab-misc</artifactId>
</dependency>
@@ -85,13 +80,13 @@
<dependency>
<groupId>org.onosproject</groupId>
- <artifactId>onos-cli</artifactId>
+ <artifactId>onos-app-routing-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
- <artifactId>onos-core-dist</artifactId>
+ <artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
@@ -107,11 +102,6 @@
</dependency>
<dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
-
- <dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index 9f3c872..698a2d6 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -36,6 +36,8 @@
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
import org.onosproject.sdnip.config.BgpPeer;
import org.onosproject.sdnip.config.Interface;
import org.onosproject.sdnip.config.SdnIpConfigurationService;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index 59ff346..93b442d 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -15,15 +15,11 @@
*/
package org.onosproject.sdnip;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IPv6;
-import org.onlab.packet.IpAddress;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
@@ -32,7 +28,6 @@
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.sdnip.bgp.BgpConstants;
import org.onosproject.sdnip.config.BgpPeer;
import org.onosproject.sdnip.config.BgpSpeaker;
import org.onosproject.sdnip.config.Interface;
@@ -41,6 +36,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
/**
* Manages the connectivity requirements between peers.
*/
@@ -49,6 +48,8 @@
private static final Logger log = LoggerFactory.getLogger(
PeerConnectivityManager.class);
+ private static final short BGP_PORT = 179;
+
private final IntentSynchronizer intentSynchronizer;
private final SdnIpConfigurationService configService;
private final InterfaceService interfaceService;
@@ -191,7 +192,7 @@
bgpdAddress,
bgpdPeerAddress,
null,
- (short) BgpConstants.BGP_PORT);
+ BGP_PORT);
intents.add(new PointToPointIntent(appId, selector, treatment,
bgpdConnectPoint, bgpdPeerConnectPoint));
@@ -200,7 +201,7 @@
selector = buildSelector(tcpProtocol,
bgpdAddress,
bgpdPeerAddress,
- (short) BgpConstants.BGP_PORT,
+ BGP_PORT,
null);
intents.add(new PointToPointIntent(appId, selector, treatment,
@@ -211,7 +212,7 @@
bgpdPeerAddress,
bgpdAddress,
null,
- (short) BgpConstants.BGP_PORT);
+ BGP_PORT);
intents.add(new PointToPointIntent(appId, selector, treatment,
bgpdPeerConnectPoint, bgpdConnectPoint));
@@ -220,7 +221,7 @@
selector = buildSelector(tcpProtocol,
bgpdPeerAddress,
bgpdAddress,
- (short) BgpConstants.BGP_PORT,
+ BGP_PORT,
null);
intents.add(new PointToPointIntent(appId, selector, treatment,
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
index 0b921ff..b375852 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
@@ -32,14 +32,11 @@
import org.onosproject.core.CoreService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.IntentService;
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
-import org.onosproject.sdnip.bgp.BgpSessionManager;
+import org.onosproject.routingapi.RoutingService;
import org.onosproject.sdnip.config.SdnIpConfigurationReader;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
-import java.util.Collection;
import java.util.Dictionary;
import static org.slf4j.LoggerFactory.getLogger;
@@ -69,8 +66,11 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LeadershipService leadershipService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RoutingService routingService;
+
//
- // NOTE: Unused reference - needed to guarentee that the
+ // NOTE: Unused reference - needed to guarantee that the
// NetworkConfigReader component is activated and the network configuration
// is read.
//
@@ -83,8 +83,7 @@
private IntentSynchronizer intentSynchronizer;
private SdnIpConfigurationReader config;
private PeerConnectivityManager peerConnectivity;
- private Router router;
- private BgpSessionManager bgpSessionManager;
+
private LeadershipEventListener leadershipEventListener =
new InnerLeadershipEventListener();
private ApplicationId appId;
@@ -114,23 +113,18 @@
interfaceService);
peerConnectivity.start();
- router = new Router(intentSynchronizer, hostService);
- router.start();
+ routingService.start(intentSynchronizer);
leadershipService.addListener(leadershipEventListener);
leadershipService.runForLeadership(appId.name());
log.info("Starting BGP with port {}", bgpPort);
-
- bgpSessionManager = new BgpSessionManager(router);
- bgpSessionManager.start(bgpPort);
+ // TODO feed port information through to the BgpService
}
@Deactivate
protected void deactivate() {
-
- bgpSessionManager.stop();
- router.stop();
+ routingService.stop();
peerConnectivity.stop();
intentSynchronizer.stop();
@@ -168,31 +162,6 @@
}
@Override
- public Collection<BgpSession> getBgpSessions() {
- return bgpSessionManager.getBgpSessions();
- }
-
- @Override
- public Collection<BgpRouteEntry> getBgpRoutes4() {
- return bgpSessionManager.getBgpRoutes4();
- }
-
- @Override
- public Collection<BgpRouteEntry> getBgpRoutes6() {
- return bgpSessionManager.getBgpRoutes6();
- }
-
- @Override
- public Collection<RouteEntry> getRoutes4() {
- return router.getRoutes4();
- }
-
- @Override
- public Collection<RouteEntry> getRoutes6() {
- return router.getRoutes6();
- }
-
- @Override
public void modifyPrimary(boolean isPrimary) {
intentSynchronizer.leaderChanged(isPrimary);
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
index aa71f02..dbb0d88 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
@@ -15,49 +15,10 @@
*/
package org.onosproject.sdnip;
-import java.util.Collection;
-
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
-
/**
* Service interface exported by SDN-IP.
*/
public interface SdnIpService {
- /**
- * Gets the BGP sessions.
- *
- * @return the BGP sessions
- */
- public Collection<BgpSession> getBgpSessions();
-
- /**
- * Gets the selected IPv4 BGP routes among all BGP sessions.
- *
- * @return the selected IPv4 BGP routes among all BGP sessions
- */
- public Collection<BgpRouteEntry> getBgpRoutes4();
-
- /**
- * Gets the selected IPv6 BGP routes among all BGP sessions.
- *
- * @return the selected IPv6 BGP routes among all BGP sessions
- */
- public Collection<BgpRouteEntry> getBgpRoutes6();
-
- /**
- * Gets all IPv4 routes known to SDN-IP.
- *
- * @return the SDN-IP IPv4 routes
- */
- public Collection<RouteEntry> getRoutes4();
-
- /**
- * Gets all IPv6 routes known to SDN-IP.
- *
- * @return the SDN-IP IPv6 routes
- */
- public Collection<RouteEntry> getRoutes6();
/**
* Changes whether this SDN-IP instance is the primary or not based on the
diff --git a/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index dd33f73..3be1c79 100644
--- a/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -17,15 +17,6 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
- <action class="org.onosproject.sdnip.cli.BgpNeighborsListCommand"/>
- </command>
- <command>
- <action class="org.onosproject.sdnip.cli.BgpRoutesListCommand"/>
- </command>
- <command>
- <action class="org.onosproject.sdnip.cli.RoutesListCommand"/>
- </command>
- <command>
<action class="org.onosproject.sdnip.cli.PrimaryChangeCommand"/>
</command>
</command-bundle>
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
index e4808f7..d13aa2a 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
@@ -16,9 +16,8 @@
package org.onosproject.sdnip;
import com.google.common.collect.Sets;
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+import org.easymock.EasyMock;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
@@ -32,18 +31,12 @@
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.intent.AbstractIntentTest;
import org.onosproject.net.intent.Intent;
@@ -51,10 +44,18 @@
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
+import org.onosproject.sdnip.config.BgpPeer;
import org.onosproject.sdnip.config.Interface;
+import org.onosproject.sdnip.config.SdnIpConfigurationService;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -71,9 +72,9 @@
*/
public class IntentSyncTest extends AbstractIntentTest {
+ private SdnIpConfigurationService sdnIpConfigService;
private InterfaceService interfaceService;
private IntentService intentService;
- private HostService hostService;
private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
@@ -87,8 +88,11 @@
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber(1));
+ private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000004"),
+ PortNumber.portNumber(1));
+
private IntentSynchronizer intentSynchronizer;
- private Router router;
private static final ApplicationId APPID = new ApplicationId() {
@Override
@@ -106,12 +110,42 @@
public void setUp() throws Exception {
super.setUp();
setUpInterfaceService();
- setUpHostService();
+
+ setUpBgpPeers();
intentService = createMock(IntentService.class);
intentSynchronizer = new IntentSynchronizer(APPID, intentService,
- null, interfaceService);
- router = new Router(intentSynchronizer, hostService);
+ sdnIpConfigService, interfaceService);
+ }
+
+ /**
+ * Sets up BGP peers in external networks.
+ */
+ private void setUpBgpPeers() {
+
+ Map<IpAddress, BgpPeer> peers = new HashMap<>();
+
+ String peerSw1Eth1 = "192.168.10.1";
+ peers.put(IpAddress.valueOf(peerSw1Eth1),
+ new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
+
+ // Two BGP peers are connected to switch 2 port 1.
+ String peer1Sw2Eth1 = "192.168.20.1";
+ peers.put(IpAddress.valueOf(peer1Sw2Eth1),
+ new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
+
+ String peer2Sw2Eth1 = "192.168.20.2";
+ peers.put(IpAddress.valueOf(peer2Sw2Eth1),
+ new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
+
+ String peer1Sw4Eth1 = "192.168.40.1";
+ peers.put(IpAddress.valueOf(peer1Sw4Eth1),
+ new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
+
+ sdnIpConfigService = createMock(SdnIpConfigurationService.class);
+ expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
+ EasyMock.replay(sdnIpConfigService);
+
}
/**
@@ -133,80 +167,279 @@
interfaces.add(sw1Eth1);
Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
- interfaceIpAddresses2.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.20.101"),
- IpPrefix.valueOf("192.168.20.0/24")));
+ interfaceIpAddresses2.add(
+ new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
+ IpPrefix.valueOf("192.168.20.0/24")));
Interface sw2Eth1 = new Interface(SW2_ETH1,
interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
VlanId.NONE);
interfaces.add(sw2Eth1);
Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
- interfaceIpAddresses3.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.30.101"),
- IpPrefix.valueOf("192.168.30.0/24")));
+ interfaceIpAddresses3.add(
+ new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
+ IpPrefix.valueOf("192.168.30.0/24")));
Interface sw3Eth1 = new Interface(SW3_ETH1,
interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
VlanId.NONE);
interfaces.add(sw3Eth1);
+ InterfaceIpAddress interfaceIpAddress4 =
+ new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
+ IpPrefix.valueOf("192.168.40.0/24"));
+ Interface sw4Eth1 = new Interface(SW4_ETH1,
+ Sets.newHashSet(interfaceIpAddress4),
+ MacAddress.valueOf("00:00:00:00:00:04"),
+ VlanId.vlanId((short) 1));
+
+ expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
+ interfaces.add(sw4Eth1);
+
expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
sw1Eth1).anyTimes();
expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
sw2Eth1).anyTimes();
expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
sw3Eth1).anyTimes();
- expect(interfaceService.getInterfaces()).andReturn(
- interfaces).anyTimes();
+ expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
replay(interfaceService);
}
/**
- * Sets up the host service with details of hosts.
+ * Tests adding a FIB entry to the IntentSynchronizer.
+ *
+ * We verify that the synchronizer records the correct state and that the
+ * correct intent is submitted to the IntentService.
+ *
+ * @throws TestUtilsException
*/
- private void setUpHostService() {
- hostService = createMock(HostService.class);
+ @Test
+ public void testFibAdd() throws TestUtilsException {
+ FibEntry fibEntry = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("192.168.10.1"),
+ MacAddress.valueOf("00:00:00:00:00:01"));
- hostService.addListener(anyObject(HostListener.class));
- expectLastCall().anyTimes();
+ // Construct a MultiPointToSinglePointIntent intent
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+ fibEntry.prefix());
- IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
- Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
- new HostLocation(SW1_ETH1, 1),
- Sets.newHashSet(host1Address));
+ TrafficTreatment.Builder treatmentBuilder =
+ DefaultTrafficTreatment.builder();
+ treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
- expect(hostService.getHostsByIp(host1Address))
- .andReturn(Sets.newHashSet(host1)).anyTimes();
- hostService.startMonitoringIp(host1Address);
- expectLastCall().anyTimes();
+ Set<ConnectPoint> ingressPoints = new HashSet<>();
+ ingressPoints.add(SW2_ETH1);
+ ingressPoints.add(SW3_ETH1);
+ ingressPoints.add(SW4_ETH1);
+
+ MultiPointToSinglePointIntent intent =
+ new MultiPointToSinglePointIntent(APPID,
+ selectorBuilder.build(), treatmentBuilder.build(),
+ ingressPoints, SW1_ETH1);
+
+ // Setup the expected intents
+ IntentOperations.Builder builder = IntentOperations.builder(APPID);
+ builder.addSubmitOperation(intent);
+ intentService.execute(TestIntentServiceHelper.eqExceptId(
+ builder.build()));
+ replay(intentService);
+
+ intentSynchronizer.leaderChanged(true);
+ TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+
+ FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
+ fibEntry);
+ intentSynchronizer.update(Collections.singleton(fibUpdate),
+ Collections.emptyList());
+
+ Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+ Intent firstIntent =
+ intentSynchronizer.getRouteIntents().iterator().next();
+ IntentKey firstIntentKey = new IntentKey(firstIntent);
+ IntentKey intentKey = new IntentKey(intent);
+ assertTrue(firstIntentKey.equals(intentKey));
+ verify(intentService);
+ }
+
+ /**
+ * Tests adding a FIB entry with to a next hop in a VLAN.
+ *
+ * We verify that the synchronizer records the correct state and that the
+ * correct intent is submitted to the IntentService.
+ *
+ * @throws TestUtilsException
+ */
+ @Test
+ public void testFibAddWithVlan() throws TestUtilsException {
+ FibEntry fibEntry = new FibEntry(
+ Ip4Prefix.valueOf("3.3.3.0/24"),
+ Ip4Address.valueOf("192.168.40.1"),
+ MacAddress.valueOf("00:00:00:00:00:04"));
+
+ // Construct a MultiPointToSinglePointIntent intent
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(fibEntry.prefix())
+ .matchVlanId(VlanId.ANY);
+
+ TrafficTreatment.Builder treatmentBuilder =
+ DefaultTrafficTreatment.builder();
+ treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
+ .setVlanId(VlanId.vlanId((short) 1));
+
+ Set<ConnectPoint> ingressPoints = new HashSet<>();
+ ingressPoints.add(SW1_ETH1);
+ ingressPoints.add(SW2_ETH1);
+ ingressPoints.add(SW3_ETH1);
+
+ MultiPointToSinglePointIntent intent =
+ new MultiPointToSinglePointIntent(APPID,
+ selectorBuilder.build(), treatmentBuilder.build(),
+ ingressPoints, SW4_ETH1);
+
+ // Setup the expected intents
+ IntentOperations.Builder builder = IntentOperations.builder(APPID);
+ builder.addSubmitOperation(intent);
+ intentService.execute(
+ TestIntentServiceHelper.eqExceptId(builder.build()));
+ replay(intentService);
+
+ // Run the test
+ intentSynchronizer.leaderChanged(true);
+ TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+ FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
+
+ intentSynchronizer.update(Collections.singleton(fibUpdate),
+ Collections.emptyList());
+
+ // Verify
+ Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+ Intent firstIntent =
+ intentSynchronizer.getRouteIntents().iterator().next();
+ IntentKey firstIntentKey = new IntentKey(firstIntent);
+ IntentKey intentKey = new IntentKey(intent);
+ assertTrue(firstIntentKey.equals(intentKey));
+ verify(intentService);
+ }
+
+ /**
+ * Tests updating a FIB entry.
+ *
+ * We verify that the synchronizer records the correct state and that the
+ * correct intent is submitted to the IntentService.
+ *
+ * @throws TestUtilsException
+ */
+ @Test
+ public void testFibUpdate() throws TestUtilsException {
+ // Firstly add a route
+ testFibAdd();
+
+ Intent addedIntent =
+ intentSynchronizer.getRouteIntents().iterator().next();
+
+ // Start to construct a new route entry and new intent
+ FibEntry fibEntryUpdate = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"),
+ Ip4Address.valueOf("192.168.20.1"),
+ MacAddress.valueOf("00:00:00:00:00:02"));
+
+ // Construct a new MultiPointToSinglePointIntent intent
+ TrafficSelector.Builder selectorBuilderNew =
+ DefaultTrafficSelector.builder();
+ selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+ fibEntryUpdate.prefix());
+
+ TrafficTreatment.Builder treatmentBuilderNew =
+ DefaultTrafficTreatment.builder();
+ treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
- IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
- Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
- new HostLocation(SW2_ETH1, 1),
- Sets.newHashSet(host2Address));
+ Set<ConnectPoint> ingressPointsNew = new HashSet<>();
+ ingressPointsNew.add(SW1_ETH1);
+ ingressPointsNew.add(SW3_ETH1);
+ ingressPointsNew.add(SW4_ETH1);
- expect(hostService.getHostsByIp(host2Address))
- .andReturn(Sets.newHashSet(host2)).anyTimes();
- hostService.startMonitoringIp(host2Address);
- expectLastCall().anyTimes();
+ MultiPointToSinglePointIntent intentNew =
+ new MultiPointToSinglePointIntent(APPID,
+ selectorBuilderNew.build(),
+ treatmentBuilderNew.build(),
+ ingressPointsNew, SW2_ETH1);
+ // Set up test expectation
+ reset(intentService);
+ // Setup the expected intents
+ IntentOperations.Builder builder = IntentOperations.builder(APPID);
+ builder.addWithdrawOperation(addedIntent.id());
+ intentService.execute(TestIntentServiceHelper.eqExceptId(
+ builder.build()));
+ builder = IntentOperations.builder(APPID);
+ builder.addSubmitOperation(intentNew);
+ intentService.execute(TestIntentServiceHelper.eqExceptId(
+ builder.build()));
+ replay(intentService);
- IpAddress host3Address = IpAddress.valueOf("192.168.30.1");
- Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE,
- new HostLocation(SW3_ETH1, 1),
- Sets.newHashSet(host3Address));
+ // Call the update() method in IntentSynchronizer class
+ intentSynchronizer.leaderChanged(true);
+ TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+ FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
+ fibEntryUpdate);
+ intentSynchronizer.update(Collections.singletonList(fibUpdate),
+ Collections.emptyList());
- expect(hostService.getHostsByIp(host3Address))
- .andReturn(Sets.newHashSet(host3)).anyTimes();
- hostService.startMonitoringIp(host3Address);
- expectLastCall().anyTimes();
+ // Verify
+ Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+ Intent firstIntent =
+ intentSynchronizer.getRouteIntents().iterator().next();
+ IntentKey firstIntentKey = new IntentKey(firstIntent);
+ IntentKey intentNewKey = new IntentKey(intentNew);
+ assertTrue(firstIntentKey.equals(intentNewKey));
+ verify(intentService);
+ }
+ /**
+ * Tests deleting a FIB entry.
+ *
+ * We verify that the synchronizer records the correct state and that the
+ * correct intent is withdrawn from the IntentService.
+ *
+ * @throws TestUtilsException
+ */
+ @Test
+ public void testFibDelete() throws TestUtilsException {
+ // Firstly add a route
+ testFibAdd();
- replay(hostService);
+ Intent addedIntent =
+ intentSynchronizer.getRouteIntents().iterator().next();
+
+ // Construct the existing route entry
+ FibEntry fibEntry = new FibEntry(
+ Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+ // Set up expectation
+ reset(intentService);
+ // Setup the expected intents
+ IntentOperations.Builder builder = IntentOperations.builder(APPID);
+ builder.addWithdrawOperation(addedIntent.id());
+ intentService.execute(TestIntentServiceHelper.eqExceptId(
+ builder.build()));
+ replay(intentService);
+
+ // Call the update() method in IntentSynchronizer class
+ intentSynchronizer.leaderChanged(true);
+ TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+ FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
+ intentSynchronizer.update(Collections.emptyList(),
+ Collections.singletonList(fibUpdate));
+
+ // Verify
+ Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
+ verify(intentService);
}
/**
@@ -287,25 +520,7 @@
MultiPointToSinglePointIntent intent6 = intentBuilder(
routeEntry6.prefix(), "00:00:00:00:00:01", SW1_ETH1);
- // Set up the ribTable field in Router class and routeIntents fields
- // in IntentSynchronizer class
- InvertedRadixTree<RouteEntry> ribTable =
- new ConcurrentInvertedRadixTree<>(
- new DefaultByteArrayNodeFactory());
- ribTable.put(RouteEntry.createBinaryString(routeEntry1.prefix()),
- routeEntry1);
- ribTable.put(RouteEntry.createBinaryString(routeEntry3.prefix()),
- routeEntry3);
- ribTable.put(RouteEntry.createBinaryString(routeEntry4Update.prefix()),
- routeEntry4Update);
- ribTable.put(RouteEntry.createBinaryString(routeEntry5.prefix()),
- routeEntry5);
- ribTable.put(RouteEntry.createBinaryString(routeEntry6.prefix()),
- routeEntry6);
- ribTable.put(RouteEntry.createBinaryString(routeEntry7.prefix()),
- routeEntry7);
- TestUtils.setField(router, "ribTable4", ribTable);
-
+ // Set up the routeIntents field in IntentSynchronizer class
ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
routeIntents = new ConcurrentHashMap<>();
routeIntents.put(routeEntry1.prefix(), intent1);
@@ -353,20 +568,9 @@
// Start the test
intentSynchronizer.leaderChanged(true);
- /*
- TestUtils.callMethod(intentSynchronizer, "synchronizeIntents",
- new Class<?>[] {});
- */
intentSynchronizer.synchronizeIntents();
// Verify
- assertEquals(router.getRoutes4().size(), 6);
- assertTrue(router.getRoutes4().contains(routeEntry1));
- assertTrue(router.getRoutes4().contains(routeEntry3));
- assertTrue(router.getRoutes4().contains(routeEntry4Update));
- assertTrue(router.getRoutes4().contains(routeEntry5));
- assertTrue(router.getRoutes4().contains(routeEntry6));
-
assertEquals(intentSynchronizer.getRouteIntents().size(), 6);
assertTrue(intentSynchronizer.getRouteIntents().contains(intent1));
assertTrue(intentSynchronizer.getRouteIntents().contains(intent3));
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index 5311a72..298972d 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -41,7 +41,6 @@
import org.onosproject.net.intent.IntentOperations;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.sdnip.bgp.BgpConstants;
import org.onosproject.sdnip.config.BgpPeer;
import org.onosproject.sdnip.config.BgpSpeaker;
import org.onosproject.sdnip.config.Interface;
@@ -302,7 +301,7 @@
*/
private void setUpBgpIntents() {
- Short bgpPort = Short.valueOf((short) BgpConstants.BGP_PORT);
+ Short bgpPort = 179;
// Start to build intents between BGP speaker1 and BGP peer1
bgpPathintentConstructor(
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java
deleted file mode 100644
index 4d14228..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright 2014 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.sdnip;
-
-import com.google.common.collect.Sets;
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentOperations;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
-import org.onosproject.sdnip.Router.InternalHostListener;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * This class tests adding a route, updating a route, deleting a route, and
- * the ARP module answers the MAC address asynchronously.
- */
-public class RouterAsyncArpTest extends AbstractIntentTest {
-
- private SdnIpConfigurationService sdnIpConfigService;
- private InterfaceService interfaceService;
- private IntentService intentService;
- private HostService hostService;
-
- private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000001"),
- PortNumber.portNumber(1));
-
- private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000002"),
- PortNumber.portNumber(1));
-
- private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000003"),
- PortNumber.portNumber(1));
-
- private IntentSynchronizer intentSynchronizer;
- private Router router;
- private InternalHostListener internalHostListener;
-
- private static final ApplicationId APPID = new ApplicationId() {
- @Override
- public short id() {
- return 1;
- }
-
- @Override
- public String name() {
- return "SDNIP";
- }
- };
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- setUpSdnIpConfigService();
- setUpInterfaceService();
- hostService = createMock(HostService.class);
- intentService = createMock(IntentService.class);
-
- intentSynchronizer = new IntentSynchronizer(APPID, intentService,
- sdnIpConfigService,
- interfaceService);
- router = new Router(intentSynchronizer, hostService);
- internalHostListener = router.new InternalHostListener();
- }
-
- /**
- * Sets up SdnIpConfigService.
- */
- private void setUpSdnIpConfigService() {
-
- sdnIpConfigService = createMock(SdnIpConfigurationService.class);
-
- Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
- String peerSw1Eth1 = "192.168.10.1";
- peers.put(IpAddress.valueOf(peerSw1Eth1),
- new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
- // Two BGP peers are connected to switch 2 port 1.
- String peer1Sw2Eth1 = "192.168.20.1";
- peers.put(IpAddress.valueOf(peer1Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
- String peer2Sw2Eth1 = "192.168.20.2";
- peers.put(IpAddress.valueOf(peer2Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
- expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
- replay(sdnIpConfigService);
- }
-
- /**
- * Sets up InterfaceService.
- */
- private void setUpInterfaceService() {
-
- interfaceService = createMock(InterfaceService.class);
-
- Set<Interface> interfaces = Sets.newHashSet();
-
- Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
- interfaceIpAddresses1.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.10.101"),
- IpPrefix.valueOf("192.168.10.0/24")));
- Interface sw1Eth1 = new Interface(SW1_ETH1,
- interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
- VlanId.NONE);
- interfaces.add(sw1Eth1);
-
- Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
- interfaceIpAddresses2.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.20.101"),
- IpPrefix.valueOf("192.168.20.0/24")));
- Interface sw2Eth1 = new Interface(SW2_ETH1,
- interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
- VlanId.NONE);
- interfaces.add(sw2Eth1);
-
- Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
- interfaceIpAddresses3.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.30.101"),
- IpPrefix.valueOf("192.168.30.0/24")));
- Interface sw3Eth1 = new Interface(SW3_ETH1,
- interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
- VlanId.NONE);
- interfaces.add(sw3Eth1);
-
- expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
- expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
- expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
- expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
- replay(interfaceService);
- }
-
- /**
- * This method tests adding a route entry.
- */
- @Test
- public void testRouteAdd() throws TestUtilsException {
-
- // Construct a route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.10.1"));
-
- // Construct a route intent
- MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
- // Set up test expectation
- reset(hostService);
- expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
- new HashSet<Host>()).anyTimes();
- hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
- replay(hostService);
-
- reset(intentService);
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addSubmitOperation(intent);
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
- new HostLocation(
- SW1_ETH1.deviceId(),
- SW1_ETH1.port(), 1),
- Sets.newHashSet(IpAddress.valueOf("192.168.10.1")));
- internalHostListener.event(
- new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntry));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
- Intent firstIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
- IntentKey firstIntentKey = new IntentKey(firstIntent);
- IntentKey intentKey = new IntentKey(intent);
- assertTrue(firstIntentKey.equals(intentKey));
- verify(intentService);
- verify(hostService);
-
- }
-
- /**
- * This method tests updating a route entry.
- *
- * @throws TestUtilsException
- */
- @Test
- public void testRouteUpdate() throws TestUtilsException {
-
- // Construct the existing route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.10.1"));
-
- // Construct the existing MultiPointToSinglePointIntent intent
- MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
- // Set up the ribTable field of Router class with existing route, and
- // routeIntents field with the corresponding existing intent
- setRibTableField(routeEntry);
- setRouteIntentsField(routeEntry, intent);
-
- // Start to construct a new route entry and new intent
- RouteEntry routeEntryUpdate = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.20.1"));
-
- // Construct a new MultiPointToSinglePointIntent intent
- TrafficSelector.Builder selectorBuilderNew =
- DefaultTrafficSelector.builder();
- selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
- routeEntryUpdate.prefix());
-
- TrafficTreatment.Builder treatmentBuilderNew =
- DefaultTrafficTreatment.builder();
- treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
- Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
- ingressPointsNew.add(SW1_ETH1);
- ingressPointsNew.add(SW3_ETH1);
-
- MultiPointToSinglePointIntent intentNew =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilderNew.build(),
- treatmentBuilderNew.build(),
- ingressPointsNew, SW2_ETH1);
-
- // Set up test expectation
- reset(hostService);
- expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
- new HashSet<Host>()).anyTimes();
- hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
- replay(hostService);
-
- reset(intentService);
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addWithdrawOperation(intent.id());
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- builder = IntentOperations.builder(APPID);
- builder.addSubmitOperation(intentNew);
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntryUpdate);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
- new HostLocation(
- SW2_ETH1.deviceId(),
- SW2_ETH1.port(), 1),
- Sets.newHashSet(IpAddress.valueOf("192.168.20.1")));
- internalHostListener.event(
- new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntryUpdate));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
- Intent firstIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
- IntentKey firstIntentKey = new IntentKey(firstIntent);
- IntentKey intentNewKey = new IntentKey(intentNew);
- assertTrue(firstIntentKey.equals(intentNewKey));
- verify(intentService);
- verify(hostService);
- }
-
- /**
- * This method tests deleting a route entry.
- */
- @Test
- public void testRouteDelete() throws TestUtilsException {
-
- // Construct the existing route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.10.1"));
-
- // Construct the existing MultiPointToSinglePointIntent intent
- MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
- // Set up the ribTable field of Router class with existing route, and
- // routeIntents field with the corresponding existing intent
- setRibTableField(routeEntry);
- setRouteIntentsField(routeEntry, intent);
-
- // Set up expectation
- reset(intentService);
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addWithdrawOperation(intent.id());
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 0);
- assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
- verify(intentService);
- }
-
- /**
- * Constructs a static MultiPointToSinglePointIntent.
- */
- private MultiPointToSinglePointIntent staticIntentBuilder() {
-
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder();
- selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
- IpPrefix.valueOf("1.1.1.0/24"));
-
- TrafficTreatment.Builder treatmentBuilder =
- DefaultTrafficTreatment.builder();
- treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
-
- Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
- ingressPoints.add(SW2_ETH1);
- ingressPoints.add(SW3_ETH1);
-
- MultiPointToSinglePointIntent intent =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilder.build(), treatmentBuilder.build(),
- ingressPoints, SW1_ETH1);
-
- return intent;
- }
-
- /**
- * Sets ribTable Field in Router class.
- *
- * @throws TestUtilsException
- */
- private void setRibTableField(RouteEntry routeEntry)
- throws TestUtilsException {
-
- InvertedRadixTree<RouteEntry> ribTable =
- new ConcurrentInvertedRadixTree<>(
- new DefaultByteArrayNodeFactory());
- ribTable.put(RouteEntry.createBinaryString(routeEntry.prefix()),
- routeEntry);
- TestUtils.setField(router, "ribTable4", ribTable);
- }
-
- /**
- * Sets routeIntentsField in IntentSynchronizer class.
- *
- * @throws TestUtilsException
- */
- private void setRouteIntentsField(RouteEntry routeEntry,
- MultiPointToSinglePointIntent intent)
- throws TestUtilsException {
-
- ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
- routeIntents = new ConcurrentHashMap<>();
- routeIntents.put(routeEntry.prefix(), intent);
- TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents);
- }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java
deleted file mode 100644
index a7b4cce..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright 2014 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.sdnip;
-
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentOperations;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * This class tests adding a route, updating a route, deleting a route,
- * and adding a route whose next hop is the local BGP speaker.
- * <p/>
- * ARP module answers the MAC address synchronously.
- */
-public class RouterTest extends AbstractIntentTest {
-
- private SdnIpConfigurationService sdnIpConfigService;
- private InterfaceService interfaceService;
- private IntentService intentService;
- private HostService hostService;
-
- private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000001"),
- PortNumber.portNumber(1));
-
- private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000002"),
- PortNumber.portNumber(1));
-
- private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000003"),
- PortNumber.portNumber(1));
-
- private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000004"),
- PortNumber.portNumber(1));
-
- private static final ApplicationId APPID = new ApplicationId() {
- @Override
- public short id() {
- return 1;
- }
-
- @Override
- public String name() {
- return "SDNIP";
- }
- };
-
- private IntentSynchronizer intentSynchronizer;
- private Router router;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- setUpBgpPeers();
-
- setUpInterfaceService();
- setUpHostService();
-
- intentService = createMock(IntentService.class);
-
- intentSynchronizer = new IntentSynchronizer(APPID, intentService,
- sdnIpConfigService,
- interfaceService);
- router = new Router(intentSynchronizer, hostService);
- }
-
- /**
- * Sets up BGP peers in external networks.
- */
- private void setUpBgpPeers() {
-
- Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
- String peerSw1Eth1 = "192.168.10.1";
- peers.put(IpAddress.valueOf(peerSw1Eth1),
- new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
- // Two BGP peers are connected to switch 2 port 1.
- String peer1Sw2Eth1 = "192.168.20.1";
- peers.put(IpAddress.valueOf(peer1Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
- String peer2Sw2Eth1 = "192.168.20.2";
- peers.put(IpAddress.valueOf(peer2Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
- String peer1Sw4Eth1 = "192.168.40.1";
- peers.put(IpAddress.valueOf(peer1Sw4Eth1),
- new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
-
- sdnIpConfigService = createMock(SdnIpConfigurationService.class);
- expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
- replay(sdnIpConfigService);
-
- }
-
- /**
- * Sets up logical interfaces, which emulate the configured interfaces
- * in SDN-IP application.
- */
- private void setUpInterfaceService() {
- interfaceService = createMock(InterfaceService.class);
-
- Set<Interface> interfaces = Sets.newHashSet();
-
- InterfaceIpAddress ia1 =
- new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"),
- IpPrefix.valueOf("192.168.10.0/24"));
- Interface sw1Eth1 = new Interface(SW1_ETH1,
- Sets.newHashSet(ia1),
- MacAddress.valueOf("00:00:00:00:00:01"),
- VlanId.NONE);
-
- expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
- interfaces.add(sw1Eth1);
-
- InterfaceIpAddress ia2 =
- new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
- IpPrefix.valueOf("192.168.20.0/24"));
- Interface sw2Eth1 = new Interface(SW2_ETH1,
- Sets.newHashSet(ia2),
- MacAddress.valueOf("00:00:00:00:00:02"),
- VlanId.NONE);
-
- expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
- interfaces.add(sw2Eth1);
-
- InterfaceIpAddress ia3 =
- new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
- IpPrefix.valueOf("192.168.30.0/24"));
- Interface sw3Eth1 = new Interface(SW3_ETH1,
- Sets.newHashSet(ia3),
- MacAddress.valueOf("00:00:00:00:00:03"),
- VlanId.NONE);
-
- expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
- interfaces.add(sw3Eth1);
-
- InterfaceIpAddress ia4 =
- new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
- IpPrefix.valueOf("192.168.40.0/24"));
- Interface sw4Eth1 = new Interface(SW4_ETH1,
- Sets.newHashSet(ia4),
- MacAddress.valueOf("00:00:00:00:00:04"),
- VlanId.vlanId((short) 1));
-
- expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
- interfaces.add(sw4Eth1);
-
- expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-
- replay(interfaceService);
- }
-
- /**
- * Sets up the host service with details of some hosts.
- */
- private void setUpHostService() {
- hostService = createMock(HostService.class);
-
- hostService.addListener(anyObject(HostListener.class));
- expectLastCall().anyTimes();
-
- IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
- Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
- new HostLocation(SW1_ETH1, 1),
- Sets.newHashSet(host1Address));
-
- expect(hostService.getHostsByIp(host1Address))
- .andReturn(Sets.newHashSet(host1)).anyTimes();
- hostService.startMonitoringIp(host1Address);
- expectLastCall().anyTimes();
-
-
- IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
- Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
- new HostLocation(SW2_ETH1, 1),
- Sets.newHashSet(host2Address));
-
- expect(hostService.getHostsByIp(host2Address))
- .andReturn(Sets.newHashSet(host2)).anyTimes();
- hostService.startMonitoringIp(host2Address);
- expectLastCall().anyTimes();
-
- // Next hop on a VLAN
- IpAddress host3Address = IpAddress.valueOf("192.168.40.1");
- Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
- MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1),
- new HostLocation(SW4_ETH1, 1),
- Sets.newHashSet(host3Address));
-
- expect(hostService.getHostsByIp(host3Address))
- .andReturn(Sets.newHashSet(host3)).anyTimes();
- hostService.startMonitoringIp(host3Address);
- expectLastCall().anyTimes();
-
-
- replay(hostService);
- }
-
- /**
- * This method tests adding a route entry.
- */
- @Test
- public void testRouteAdd() throws TestUtilsException {
- // Construct a route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.10.1"));
-
- // Construct a MultiPointToSinglePointIntent intent
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder();
- selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
- routeEntry.prefix());
-
- TrafficTreatment.Builder treatmentBuilder =
- DefaultTrafficTreatment.builder();
- treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
-
- Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
- ingressPoints.add(SW2_ETH1);
- ingressPoints.add(SW3_ETH1);
- ingressPoints.add(SW4_ETH1);
-
- MultiPointToSinglePointIntent intent =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilder.build(), treatmentBuilder.build(),
- ingressPoints, SW1_ETH1);
-
- // Set up test expectation
- reset(intentService);
- // Setup the expected intents
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addSubmitOperation(intent);
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntry));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
- Intent firstIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
- IntentKey firstIntentKey = new IntentKey(firstIntent);
- IntentKey intentKey = new IntentKey(intent);
- assertTrue(firstIntentKey.equals(intentKey));
- verify(intentService);
- }
-
- /**
- * This method tests adding a route entry.
- */
- @Test
- public void testRouteAddWithVlan() throws TestUtilsException {
- // Construct a route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("3.3.3.0/24"),
- Ip4Address.valueOf("192.168.40.1"));
-
- // Construct a MultiPointToSinglePointIntent intent
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder();
- selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(routeEntry.prefix())
- .matchVlanId(VlanId.ANY);
-
- TrafficTreatment.Builder treatmentBuilder =
- DefaultTrafficTreatment.builder();
- treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
- .setVlanId(VlanId.vlanId((short) 1));
-
- Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
- ingressPoints.add(SW1_ETH1);
- ingressPoints.add(SW2_ETH1);
- ingressPoints.add(SW3_ETH1);
-
- MultiPointToSinglePointIntent intent =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilder.build(), treatmentBuilder.build(),
- ingressPoints, SW4_ETH1);
-
- // Set up test expectation
- reset(intentService);
- // Setup the expected intents
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addSubmitOperation(intent);
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntry));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
- Intent firstIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
- IntentKey firstIntentKey = new IntentKey(firstIntent);
- IntentKey intentKey = new IntentKey(intent);
- assertTrue(firstIntentKey.equals(intentKey));
- verify(intentService);
- }
-
- /**
- * This method tests updating a route entry.
- *
- * @throws TestUtilsException
- */
- @Test
- public void testRouteUpdate() throws TestUtilsException {
- // Firstly add a route
- testRouteAdd();
-
- Intent addedIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
-
- // Start to construct a new route entry and new intent
- RouteEntry routeEntryUpdate = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.20.1"));
-
- // Construct a new MultiPointToSinglePointIntent intent
- TrafficSelector.Builder selectorBuilderNew =
- DefaultTrafficSelector.builder();
- selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
- routeEntryUpdate.prefix());
-
- TrafficTreatment.Builder treatmentBuilderNew =
- DefaultTrafficTreatment.builder();
- treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
-
- Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
- ingressPointsNew.add(SW1_ETH1);
- ingressPointsNew.add(SW3_ETH1);
- ingressPointsNew.add(SW4_ETH1);
-
- MultiPointToSinglePointIntent intentNew =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilderNew.build(),
- treatmentBuilderNew.build(),
- ingressPointsNew, SW2_ETH1);
-
- // Set up test expectation
- reset(intentService);
- // Setup the expected intents
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addWithdrawOperation(addedIntent.id());
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- builder = IntentOperations.builder(APPID);
- builder.addSubmitOperation(intentNew);
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntryUpdate);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntryUpdate));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
- Intent firstIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
- IntentKey firstIntentKey = new IntentKey(firstIntent);
- IntentKey intentNewKey = new IntentKey(intentNew);
- assertTrue(firstIntentKey.equals(intentNewKey));
- verify(intentService);
- }
-
- /**
- * This method tests deleting a route entry.
- */
- @Test
- public void testRouteDelete() throws TestUtilsException {
- // Firstly add a route
- testRouteAdd();
-
- Intent addedIntent =
- intentSynchronizer.getRouteIntents().iterator().next();
-
- // Construct the existing route entry
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("192.168.10.1"));
-
- // Set up expectation
- reset(intentService);
- // Setup the expected intents
- IntentOperations.Builder builder = IntentOperations.builder(APPID);
- builder.addWithdrawOperation(addedIntent.id());
- intentService.execute(TestIntentServiceHelper.eqExceptId(
- builder.build()));
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 0);
- assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
- verify(intentService);
- }
-
- /**
- * This method tests when the next hop of a route is the local BGP speaker.
- *
- * @throws TestUtilsException
- */
- @Test
- public void testLocalRouteAdd() throws TestUtilsException {
- // Construct a route entry, the next hop is the local BGP speaker
- RouteEntry routeEntry = new RouteEntry(
- Ip4Prefix.valueOf("1.1.1.0/24"),
- Ip4Address.valueOf("0.0.0.0"));
-
- // Reset intentService to check whether the submit method is called
- reset(intentService);
- replay(intentService);
-
- // Call the processRouteUpdates() method in Router class
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
- RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
- routeEntry);
- router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
- // Verify
- assertEquals(router.getRoutes4().size(), 1);
- assertTrue(router.getRoutes4().contains(routeEntry));
- assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
- verify(intentService);
- }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java
deleted file mode 100644
index 157c73f..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright 2014 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.sdnip;
-
-import com.google.common.collect.Sets;
-import org.easymock.IAnswer;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.onlab.junit.IntegrationTest;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Integration tests for the SDN-IP application.
- * <p/>
- * The tests are very coarse-grained. They feed route updates in to
- * {@link Router} (simulating routes learnt from iBGP module inside SDN-IP
- * application), then they check that the correct intents are created and
- * submitted to the intent service. The entire route processing logic of
- * Router class is tested.
- */
-@Category(IntegrationTest.class)
-public class SdnIpTest extends AbstractIntentTest {
- private static final int MAC_ADDRESS_LENGTH = 6;
- private static final int MIN_PREFIX_LENGTH = 1;
- private static final int MAX_PREFIX_LENGTH = 32;
-
- private IntentSynchronizer intentSynchronizer;
- static Router router;
-
- private SdnIpConfigurationService sdnIpConfigService;
- private InterfaceService interfaceService;
- private HostService hostService;
- private IntentService intentService;
-
- private Map<IpAddress, BgpPeer> bgpPeers;
-
- private Random random;
-
- static final ConnectPoint SW1_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000001"),
- PortNumber.portNumber(1));
-
- static final ConnectPoint SW2_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000002"),
- PortNumber.portNumber(1));
-
- static final ConnectPoint SW3_ETH1 = new ConnectPoint(
- DeviceId.deviceId("of:0000000000000003"),
- PortNumber.portNumber(1));
-
- private static final ApplicationId APPID = new ApplicationId() {
- @Override
- public short id() {
- return 1;
- }
-
- @Override
- public String name() {
- return "SDNIP";
- }
- };
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- setUpInterfaceService();
- setUpSdnIpConfigService();
-
- hostService = new TestHostService();
- intentService = createMock(IntentService.class);
- random = new Random();
-
- intentSynchronizer = new IntentSynchronizer(APPID, intentService,
- sdnIpConfigService,
- interfaceService);
- router = new Router(intentSynchronizer, hostService);
- }
-
- /**
- * Sets up InterfaceService and virtual {@link Interface}s.
- */
- private void setUpInterfaceService() {
-
- interfaceService = createMock(InterfaceService.class);
-
- Set<Interface> interfaces = Sets.newHashSet();
-
- Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
- interfaceIpAddresses1.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.10.101"),
- IpPrefix.valueOf("192.168.10.0/24")));
- Interface sw1Eth1 = new Interface(SW1_ETH1,
- interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
- VlanId.NONE);
- interfaces.add(sw1Eth1);
-
- Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
- interfaceIpAddresses2.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.20.101"),
- IpPrefix.valueOf("192.168.20.0/24")));
- Interface sw2Eth1 = new Interface(SW2_ETH1,
- interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
- VlanId.NONE);
- interfaces.add(sw2Eth1);
-
- Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
- interfaceIpAddresses3.add(new InterfaceIpAddress(
- IpAddress.valueOf("192.168.30.101"),
- IpPrefix.valueOf("192.168.30.0/24")));
- Interface sw3Eth1 = new Interface(SW3_ETH1,
- interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
- VlanId.NONE);
- interfaces.add(sw3Eth1);
-
- expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
- sw1Eth1).anyTimes();
- expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
- sw2Eth1).anyTimes();
- expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
- sw3Eth1).anyTimes();
-
- expect(interfaceService.getInterfaces()).andReturn(
- interfaces).anyTimes();
- replay(interfaceService);
- }
-
- /**
- * Sets up SdnIpConfigService and BGP peers in external networks.
- */
- private void setUpSdnIpConfigService() {
-
- sdnIpConfigService = createMock(SdnIpConfigurationService.class);
-
- bgpPeers = new HashMap<>();
-
- String peerSw1Eth1 = "192.168.10.1";
- bgpPeers.put(IpAddress.valueOf(peerSw1Eth1),
- new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
- String peer1Sw2Eth1 = "192.168.20.1";
- bgpPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
- String peer2Sw2Eth1 = "192.168.30.1";
- bgpPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:03", 1, peer2Sw2Eth1));
-
- expect(sdnIpConfigService.getBgpPeers()).andReturn(bgpPeers).anyTimes();
- replay(sdnIpConfigService);
- }
-
- /**
- * Tests adding a set of routes into {@link Router}.
- * <p/>
- * Random routes are generated and fed in to the route processing
- * logic (via processRouteAdd in Router class). We check that the correct
- * intents are generated and submitted to our mock intent service.
- *
- * @throws InterruptedException if interrupted while waiting on a latch
- * @throws TestUtilsException if exceptions when using TestUtils
- */
- @Test
- public void testAddRoutes() throws InterruptedException, TestUtilsException {
- int numRoutes = 100;
-
- final CountDownLatch latch = new CountDownLatch(numRoutes);
-
- List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);
-
- // Set up expectation
- reset(intentService);
-
- for (RouteUpdate update : routeUpdates) {
- IpAddress nextHopAddress = update.routeEntry().nextHop();
-
- // Find out the egress ConnectPoint
- ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);
-
- MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
- generateMacAddress(nextHopAddress),
- egressConnectPoint);
- intentService.submit(TestIntentServiceHelper.eqExceptId(intent));
-
- expectLastCall().andAnswer(new IAnswer<Object>() {
- @Override
- public Object answer() throws Throwable {
- latch.countDown();
- return null;
- }
- }).once();
- }
-
- replay(intentService);
-
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-
- // Add route updates
- router.processRouteUpdates(routeUpdates);
-
- latch.await(5000, TimeUnit.MILLISECONDS);
-
- assertEquals(router.getRoutes4().size(), numRoutes);
- assertEquals(intentSynchronizer.getRouteIntents().size(),
- numRoutes);
-
- verify(intentService);
- }
-
- /**
- * Tests adding then deleting a set of routes from {@link Router}.
- * <p/>
- * Random routes are generated and fed in to the route processing
- * logic (via processRouteAdd in Router class), and we check that the
- * correct intents are generated. We then delete the entire set of routes
- * (by feeding updates to processRouteDelete), and check that the correct
- * intents are withdrawn from the intent service.
- *
- * @throws InterruptedException if interrupted while waiting on a latch
- * @throws TestUtilsException exceptions when using TestUtils
- */
- @Test
- public void testDeleteRoutes() throws InterruptedException, TestUtilsException {
- int numRoutes = 100;
- List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);
-
- final CountDownLatch installCount = new CountDownLatch(numRoutes);
- final CountDownLatch deleteCount = new CountDownLatch(numRoutes);
-
- // Set up expectation
- reset(intentService);
-
- for (RouteUpdate update : routeUpdates) {
- IpAddress nextHopAddress = update.routeEntry().nextHop();
-
- // Find out the egress ConnectPoint
- ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);
- MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
- generateMacAddress(nextHopAddress),
- egressConnectPoint);
- intentService.submit(TestIntentServiceHelper.eqExceptId(intent));
- expectLastCall().andAnswer(new IAnswer<Object>() {
- @Override
- public Object answer() throws Throwable {
- installCount.countDown();
- return null;
- }
- }).once();
- intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent));
- expectLastCall().andAnswer(new IAnswer<Object>() {
- @Override
- public Object answer() throws Throwable {
- deleteCount.countDown();
- return null;
- }
- }).once();
- }
-
- replay(intentService);
-
- intentSynchronizer.leaderChanged(true);
- TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-
- // Send the add updates first
- router.processRouteUpdates(routeUpdates);
-
- // Give some time to let the intents be submitted
- installCount.await(5000, TimeUnit.MILLISECONDS);
-
- // Send the DELETE updates
- List<RouteUpdate> deleteRouteUpdates = new ArrayList<>();
- for (RouteUpdate update : routeUpdates) {
- RouteUpdate deleteUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
- update.routeEntry());
- deleteRouteUpdates.add(deleteUpdate);
- }
- router.processRouteUpdates(deleteRouteUpdates);
-
- deleteCount.await(5000, TimeUnit.MILLISECONDS);
-
- assertEquals(0, router.getRoutes4().size());
- assertEquals(0, intentSynchronizer.getRouteIntents().size());
- verify(intentService);
- }
-
- /**
- * This methods generates random route updates.
- *
- * @param numRoutes the number of route updates to generate
- * @return a list of route update
- */
- private List<RouteUpdate> generateRouteUpdates(int numRoutes) {
- List<RouteUpdate> routeUpdates = new ArrayList<>(numRoutes);
-
- Set<Ip4Prefix> prefixes = new HashSet<>();
-
- for (int i = 0; i < numRoutes; i++) {
- Ip4Prefix prefix;
- do {
- // Generate a random prefix length between MIN_PREFIX_LENGTH
- // and MAX_PREFIX_LENGTH
- int prefixLength = random.nextInt(
- (MAX_PREFIX_LENGTH - MIN_PREFIX_LENGTH) + 1)
- + MIN_PREFIX_LENGTH;
- prefix =
- Ip4Prefix.valueOf(Ip4Address.valueOf(random.nextInt()),
- prefixLength);
- // We have to ensure we don't generate the same prefix twice
- // (this is quite easy to happen with small prefix lengths).
- } while (prefixes.contains(prefix));
-
- prefixes.add(prefix);
-
- // Randomly select a peer to use as the next hop
- BgpPeer nextHop = null;
- int peerNumber = random.nextInt(sdnIpConfigService.getBgpPeers()
- .size());
- int j = 0;
- for (BgpPeer peer : sdnIpConfigService.getBgpPeers().values()) {
- if (j++ == peerNumber) {
- nextHop = peer;
- break;
- }
- }
-
- assertNotNull(nextHop);
-
- RouteUpdate update =
- new RouteUpdate(RouteUpdate.Type.UPDATE,
- new RouteEntry(prefix,
- nextHop.ipAddress().getIp4Address()));
-
- routeUpdates.add(update);
- }
-
- return routeUpdates;
- }
-
- /**
- * Generates the MultiPointToSinglePointIntent that should be
- * submitted/withdrawn for a particular RouteUpdate.
- *
- * @param update the RouteUpdate to generate an intent for
- * @param nextHopMac a MAC address to use as the dst-mac for the intent
- * @param egressConnectPoint the outgoing ConnectPoint for the intent
- * @return the generated intent
- */
- private MultiPointToSinglePointIntent getIntentForUpdate(RouteUpdate update,
- MacAddress nextHopMac, ConnectPoint egressConnectPoint) {
- IpPrefix ip4Prefix = update.routeEntry().prefix();
-
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder();
-
- selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ip4Prefix);
-
- TrafficTreatment.Builder treatmentBuilder =
- DefaultTrafficTreatment.builder();
- treatmentBuilder.setEthDst(nextHopMac);
-
- Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
- for (Interface intf : interfaceService.getInterfaces()) {
- if (!intf.connectPoint().equals(egressConnectPoint)) {
- ConnectPoint srcPort = intf.connectPoint();
- ingressPoints.add(srcPort);
- }
- }
-
- MultiPointToSinglePointIntent intent =
- new MultiPointToSinglePointIntent(APPID,
- selectorBuilder.build(), treatmentBuilder.build(),
- ingressPoints, egressConnectPoint);
-
- return intent;
- }
-
- /**
- * Generates a MAC address based on an IP address.
- * For the test we need MAC addresses but the actual values don't have any
- * meaning, so we'll just generate them based on the IP address. This means
- * we have a deterministic mapping from IP address to MAC address.
- *
- * @param ipAddress IP address used to generate a MAC address
- * @return generated MAC address
- */
- static MacAddress generateMacAddress(IpAddress ipAddress) {
- byte[] macAddress = new byte[MAC_ADDRESS_LENGTH];
- ByteBuffer bb = ByteBuffer.wrap(macAddress);
-
- // Put the IP address bytes into the lower four bytes of the MAC
- // address. Leave the first two bytes set to 0.
- bb.position(2);
- bb.put(ipAddress.toOctets());
-
- return MacAddress.valueOf(bb.array());
- }
-
- /**
- * Finds out the ConnectPoint for a BGP peer address.
- *
- * @param bgpPeerAddress the BGP peer address.
- */
- private ConnectPoint getConnectPoint(IpAddress bgpPeerAddress) {
- ConnectPoint connectPoint = null;
-
- for (BgpPeer bgpPeer: bgpPeers.values()) {
- if (bgpPeer.ipAddress().equals(bgpPeerAddress)) {
- connectPoint = bgpPeer.connectPoint();
- break;
- }
- }
- return connectPoint;
- }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java
deleted file mode 100644
index 7e84f8e..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2014 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.sdnip;
-
-import java.util.HashSet;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.PortAddresses;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.Router.InternalHostListener;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-
-import com.google.common.collect.Sets;
-
-/**
- * Test version of the HostService which is used to simulate delays in
- * receiving ARP replies, as you would see in a real system due to the time
- * it takes to proxy ARP packets to/from the host. Requests are asynchronous,
- * and replies may come back to the requestor in a different order than the
- * requests were sent, which again you would expect to see in a real system.
- */
-public class TestHostService implements HostService {
-
- /**
- * The maximum possible delay before an ARP reply is received.
- */
- private static final int MAX_ARP_REPLY_DELAY = 30; // milliseconds
-
- /**
- * The probability that we already have the MAC address cached when the
- * caller calls {@link #getHostsByIp(IpAddress ipAddress)}.
- */
- private static final float MAC_ALREADY_KNOWN_PROBABILITY = 0.3f;
-
- private final ScheduledExecutorService replyTaskExecutor;
- private final Random random;
-
- /**
- * Class constructor.
- */
- public TestHostService() {
- replyTaskExecutor = Executors.newSingleThreadScheduledExecutor();
- random = new Random();
- }
-
- /**
- * Task used to reply to ARP requests from a different thread. Replies
- * usually come on a different thread in the real system, so we need to
- * ensure we test this behavior.
- */
- private class ReplyTask implements Runnable {
- private HostListener listener;
- private IpAddress ipAddress;
-
- /**
- * Class constructor.
- *
- * @param listener the client who requests and waits the MAC address
- * @param ipAddress the target IP address of the request
- */
- public ReplyTask(InternalHostListener listener,
- IpAddress ipAddress) {
- this.listener = listener;
- this.ipAddress = ipAddress;
- }
-
- @Override
- public void run() {
- Host host = getHostsByIp(ipAddress).iterator().next();
- HostEvent hostevent =
- new HostEvent(HostEvent.Type.HOST_ADDED, host);
- listener.event(hostevent);
- }
- }
-
- @Override
- public Set<Host> getHostsByIp(IpAddress ipAddress) {
- float replyChance = random.nextFloat();
-
- // We don't care what the attachment point is in the test,
- // so for all the hosts, we use a same ConnectPoint.
- Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
- SdnIpTest.generateMacAddress(ipAddress), VlanId.NONE,
- new HostLocation(SdnIpTest.SW1_ETH1, 1),
- Sets.newHashSet(ipAddress));
-
- if (replyChance < MAC_ALREADY_KNOWN_PROBABILITY) {
- // Some percentage of the time we already know the MAC address, so
- // we reply directly when the requestor asks for the MAC address
- return Sets.newHashSet(host);
- }
- return new HashSet<Host>();
- }
-
- @Override
- public void startMonitoringIp(IpAddress ipAddress) {
-
- // Randomly select an amount of time to delay the reply coming back to
- int delay = random.nextInt(MAX_ARP_REPLY_DELAY);
- ReplyTask replyTask = new ReplyTask(
- (SdnIpTest.router.new InternalHostListener()), ipAddress);
- replyTaskExecutor.schedule(replyTask, delay, TimeUnit.MILLISECONDS);
- }
-
- @Override
- public int getHostCount() {
- return 0;
- }
-
- @Override
- public Iterable<Host> getHosts() {
- return null;
- }
-
- @Override
- public Host getHost(HostId hostId) {
- return null;
- }
-
- @Override
- public Set<Host> getHostsByVlan(VlanId vlanId) {
- return null;
- }
-
- @Override
- public Set<Host> getHostsByMac(MacAddress mac) {
- return null;
- }
-
- @Override
- public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
- return null;
- }
-
- @Override
- public Set<Host> getConnectedHosts(DeviceId deviceId) {
- return null;
- }
-
- @Override
- public void stopMonitoringIp(IpAddress ip) {
-
- }
-
- @Override
- public void requestMac(IpAddress ip) {
-
- }
-
- @Override
- public Set<PortAddresses> getAddressBindings() {
- return null;
- }
-
- @Override
- public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
- return null;
- }
-
- @Override
- public void addListener(HostListener listener) {
-
- }
-
- @Override
- public void removeListener(HostListener listener) {
-
- }
-
-}
diff --git a/features/features.xml b/features/features.xml
index 3a227a6..1d77cf9 100644
--- a/features/features.xml
+++ b/features/features.xml
@@ -216,6 +216,8 @@
<feature>onos-app-proxyarp</feature>
<feature>onos-app-config</feature>
<bundle>mvn:org.onosproject/onos-app-sdnip/@ONOS-VERSION</bundle>
+ <bundle>mvn:org.onosproject/onos-app-routing-api/@ONOS-VERSION</bundle>
+ <bundle>mvn:org.onosproject/onos-app-routing/@ONOS-VERSION</bundle>
</feature>
<feature name="onos-app-calendar" version="@FEATURE-VERSION"