Jonathan Hart

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
Showing 52 changed files with 1085 additions and 523 deletions
......@@ -46,6 +46,8 @@
<module>oecfg</module>
<module>demo</module>
<module>election</module>
<module>routing</module>
<module>routing-api</module>
</modules>
<properties>
......
<?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>
/*
* 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();
}
......@@ -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 class FibEntry {
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();
}
}
......
......@@ -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;
......
......@@ -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 class FibUpdate {
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();
}
}
......
......@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.sdnip;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Objects;
package org.onosproject.routingapi;
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 @@ public class RouteEntry {
* @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 "";
}
......
......@@ -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;
......
......@@ -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.
......
/*
* 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();
}
......@@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.sdnip;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
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;
/**
* Unit tests for the RouteEntry class.
*/
......@@ -139,8 +140,8 @@ public class RouteEntryTest {
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)));
}
/**
......
<?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>
......@@ -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.common.KeyValuePair;
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;
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.ExecutorService;
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 @@ public class Router implements RouteListener {
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 @@ public class Router implements RouteListener {
});
}
/**
* Stops the router.
*/
@Override
public void stop() {
bgpService.stop();
this.hostService.removeListener(hostListener);
// Stop the thread(s)
......@@ -137,8 +155,12 @@ public class Router implements RouteListener {
}
}
@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,9 +316,11 @@ public class Router implements RouteListener {
withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate(
FibUpdate.Type.DELETE, new FibEntry(p, null, null))));
if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) {
fibComponent.update(fibUpdates, fibWithdraws);
}
}
}
/**
* Processes adding a route entry.
......@@ -486,4 +510,14 @@ public class Router implements RouteListener {
}
}
}
/**
* Listener for route events.
*/
private class InternalRouteListener implements RouteListener {
@Override
public void update(Collection<RouteUpdate> routeUpdates) {
Router.this.update(routeUpdates);
}
}
}
......
......@@ -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.
......
......@@ -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 @@ class BgpFrameDecoder extends FrameDecoder {
// 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 @@ class BgpFrameDecoder extends FrameDecoder {
// 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 =
......
/*
* 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();
}
......@@ -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;
......
......@@ -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;
......
......@@ -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 @@ final class BgpNotification {
* @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);
......
......@@ -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 @@ public class BgpRouteEntry extends RouteEntry {
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 @@ public class BgpRouteEntry extends RouteEntry {
// 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 @@ public class BgpRouteEntry extends RouteEntry {
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 @@ public class BgpRouteEntry extends RouteEntry {
// 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 @@ public class BgpRouteEntry extends RouteEntry {
@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 @@ public class BgpRouteEntry extends RouteEntry {
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 @@ public class BgpRouteEntry extends RouteEntry {
.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)
......
......@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.sdnip.bgp;
import java.util.Collection;
import java.util.LinkedList;
package org.onosproject.routing.bgp;
import org.onlab.packet.IpPrefix;
import org.onosproject.sdnip.RouteUpdate;
import org.onosproject.routingapi.RouteUpdate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.LinkedList;
/**
* Class to receive and process the BGP routes from each BGP Session/Peer.
*/
......
......@@ -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.HashedWheelTimer;
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 @@ public class BgpSession extends SimpleChannelHandler {
// 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);
......
......@@ -13,11 +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 java.net.SocketAddress;
import org.onlab.packet.Ip4Address;
import java.net.SocketAddress;
/**
* Class for keeping information about a BGP session.
*
......
......@@ -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.Ip4Address;
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 @@ import static org.onlab.util.Tools.namedThreads;
/**
* 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 @@ public class BgpSessionManager {
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 @@ public class BgpSessionManager {
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 @@ public class BgpSessionManager {
}
}
/**
* Stops the BGP Session Manager operation.
*/
@Override
public void stop() {
isShutdown = true;
allChannels.close().awaitUninterruptibly();
......
......@@ -17,4 +17,4 @@
/**
* Implementation of the BGP protocol.
*/
package org.onosproject.sdnip.bgp;
package org.onosproject.routing.bgp;
......
......@@ -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 com.fasterxml.jackson.databind.node.ObjectNode;
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 @@ public class BgpNeighborsListCommand extends AbstractShellCommand {
@Override
protected void execute() {
SdnIpService service = get(SdnIpService.class);
BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
Collection<BgpSession> bgpSessions = service.getBgpSessions();
if (bgpNeighbor != null) {
......
......@@ -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 com.fasterxml.jackson.databind.node.ObjectNode;
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 @@ public class BgpRoutesListCommand extends AbstractShellCommand {
@Override
protected void execute() {
SdnIpService service = get(SdnIpService.class);
BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
// Print summary of the routes
if (routesSummary) {
......
......@@ -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 com.fasterxml.jackson.databind.node.ObjectNode;
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 @@ public class RoutesListCommand extends AbstractShellCommand {
@Override
protected void execute() {
SdnIpService service = get(SdnIpService.class);
RoutingService service = AbstractShellCommand.get(RoutingService.class);
// Print summary of the routes
if (routesSummary) {
......
<!--
~ 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>
/*
* 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);
}
}
/*
* 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);
}
}
......@@ -13,15 +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 static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Test;
import java.util.ArrayList;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
/**
* Unit tests for the BgpRouteEntry.AsPath class.
......@@ -211,7 +212,7 @@ public class AsPathTest {
//
BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments);
assertThat(asPath1, is(not(asPath2)));
assertThat(asPath1, Matchers.is(not(asPath2)));
}
/**
......
......@@ -13,22 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.sdnip.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;
package org.onosproject.routing.bgp;
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 @@ public class BgpRouteEntryTest {
@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 @@ public class BgpRouteEntryTest {
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 @@ public class BgpRouteEntryTest {
localPref);
bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
assertThat(bgpRouteEntry1, is(not(bgpRouteEntry2)));
assertThat(bgpRouteEntry1, Matchers.is(not(bgpRouteEntry2)));
}
/**
......
......@@ -13,22 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.sdnip.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;
package org.onosproject.routing.bgp;
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.Before;
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 @@ public class BgpSessionManagerTest {
// 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,
......
......@@ -13,15 +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 static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Test;
import java.util.ArrayList;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
/**
* Unit tests for the BgpRouteEntry.PathSegment class.
......@@ -113,7 +114,7 @@ public class PathSegmentTest {
BgpRouteEntry.PathSegment pathSegment2 =
new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
assertThat(pathSegment1, is(not(pathSegment2)));
assertThat(pathSegment1, Matchers.is(not(pathSegment2)));
}
/**
......
......@@ -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.jboss.netty.channel.SimpleChannelHandler;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import java.util.Collection;
/**
* Class for handling the remote BGP Peer session.
*/
......
......@@ -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.channel.ChannelHandlerContext;
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.
......
......@@ -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>
......
......@@ -36,6 +36,8 @@ import org.onosproject.net.intent.IntentService;
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;
......
......@@ -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.DefaultTrafficTreatment;
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.onosproject.sdnip.config.SdnIpConfigurationService;
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 @@ public class PeerConnectivityManager {
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 @@ public class PeerConnectivityManager {
bgpdAddress,
bgpdPeerAddress,
null,
(short) BgpConstants.BGP_PORT);
BGP_PORT);
intents.add(new PointToPointIntent(appId, selector, treatment,
bgpdConnectPoint, bgpdPeerConnectPoint));
......@@ -200,7 +201,7 @@ public class PeerConnectivityManager {
selector = buildSelector(tcpProtocol,
bgpdAddress,
bgpdPeerAddress,
(short) BgpConstants.BGP_PORT,
BGP_PORT,
null);
intents.add(new PointToPointIntent(appId, selector, treatment,
......@@ -211,7 +212,7 @@ public class PeerConnectivityManager {
bgpdPeerAddress,
bgpdAddress,
null,
(short) BgpConstants.BGP_PORT);
BGP_PORT);
intents.add(new PointToPointIntent(appId, selector, treatment,
bgpdPeerConnectPoint, bgpdConnectPoint));
......@@ -220,7 +221,7 @@ public class PeerConnectivityManager {
selector = buildSelector(tcpProtocol,
bgpdPeerAddress,
bgpdAddress,
(short) BgpConstants.BGP_PORT,
BGP_PORT,
null);
intents.add(new PointToPointIntent(appId, selector, treatment,
......
......@@ -32,14 +32,11 @@ import org.onosproject.core.ApplicationId;
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 @@ public class SdnIp implements SdnIpService {
@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 @@ public class SdnIp implements SdnIpService {
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 @@ public class SdnIp implements SdnIpService {
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 @@ public class SdnIp implements SdnIpService {
}
@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);
}
......
......@@ -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
......
......@@ -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>
......
......@@ -41,7 +41,6 @@ import org.onosproject.net.intent.Intent;
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 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest {
*/
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(
......
/*
* 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) {
}
}
......@@ -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"
......