Jonathan Hart

Implemented CLI commands to show SDN-IP routes

......@@ -48,6 +48,20 @@
</dependency>
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</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.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
......
......@@ -62,10 +62,8 @@ public class Router implements RouteListener {
private static final Logger log = LoggerFactory.getLogger(Router.class);
// Store all route updates in a InvertedRadixTree.
// The key in this Tree is the binary sting of prefix of route.
// The Ip4Address is the next hop address of route, and is also the value
// of each entry.
// Store all route updates in a radix tree.
// The key in this tree is the binary string of prefix of the route.
private InvertedRadixTree<RouteEntry> bgpRoutes;
// Stores all incoming route updates in a queue.
......@@ -102,7 +100,7 @@ public class Router implements RouteListener {
* Class constructor.
*
* @param intentService the intent service
* @param proxyArp the proxy ARP service
* @param hostService the host service
* @param configInfoService the configuration service
* @param interfaceService the interface service
*/
......@@ -441,8 +439,8 @@ public class Router implements RouteListener {
/**
* Processes adding a route entry.
* <p/>
* Put new route entry into InvertedRadixTree. If there was an existing
* nexthop for this prefix, but the next hop was different, then execute
* Put new route entry into the radix tree. If there was an existing
* next hop for this prefix, but the next hop was different, then execute
* deleting old route entry. If the next hop is the SDN domain, we do not
* handle it at the moment. Otherwise, execute adding a route.
*
......@@ -623,8 +621,8 @@ public class Router implements RouteListener {
/**
* Executes deleting a route entry.
* <p/>
* Removes prefix from InvertedRadixTree, if success, then try to delete
* the relative intent.
* Removes prefix from radix tree, and if successful, then try to delete
* the related intent.
*
* @param routeEntry the route entry to delete
*/
......@@ -690,9 +688,9 @@ public class Router implements RouteListener {
public void arpResponse(IpAddress ipAddress, MacAddress macAddress) {
log.debug("Received ARP response: {} => {}", ipAddress, macAddress);
// We synchronize on this to prevent changes to the InvertedRadixTree
// while we're pushing intent. If the InvertedRadixTree changes, the
// InvertedRadixTree and intent could get out of sync.
// We synchronize on this to prevent changes to the radix tree
// while we're pushing intents. If the tree changes, the
// tree and intents could get out of sync.
synchronized (this) {
Set<RouteEntry> routesToPush =
......@@ -709,14 +707,14 @@ public class Router implements RouteListener {
log.debug("Pushing prefix {} next hop {}",
routeEntry.prefix(), routeEntry.nextHop());
// We only push prefix flows if the prefix is still in the
// InvertedRadixTree and the next hop is the same as our
// radix tree and the next hop is the same as our
// update.
// The prefix could have been removed while we were waiting
// for the ARP, or the next hop could have changed.
addRouteIntentToNextHop(prefix, ipAddress, macAddress);
} else {
log.debug("Received ARP response, but {}/{} is no longer in"
+ " InvertedRadixTree", routeEntry.prefix(),
+ " the radix tree", routeEntry.prefix(),
routeEntry.nextHop());
}
}
......
......@@ -2,14 +2,18 @@ package org.onlab.onos.sdnip;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collection;
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.onos.net.host.HostService;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.sdnip.RouteUpdate.Type;
import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
import org.onlab.onos.sdnip.bgp.BgpSessionManager;
import org.onlab.onos.sdnip.config.SdnIpConfigReader;
import org.onlab.packet.IpAddress;
......@@ -17,10 +21,11 @@ import org.onlab.packet.IpPrefix;
import org.slf4j.Logger;
/**
* Placeholder SDN-IP component.
* Component for the SDN-IP peering application.
*/
@Component(immediate = true)
public class SdnIp {
@Service
public class SdnIp implements SdnIpService {
private final Logger log = getLogger(getClass());
......@@ -64,4 +69,14 @@ public class SdnIp {
protected void deactivate() {
log.info("Stopped");
}
@Override
public Collection<BgpRouteEntry> getBgpRoutes() {
return bgpSessionManager.getBgpRoutes();
}
@Override
public Collection<RouteEntry> getRoutes() {
return router.getRoutes();
}
}
......
package org.onlab.onos.sdnip;
import java.util.Collection;
import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
/**
* Service interface exported by SDN-IP.
*/
public interface SdnIpService {
/**
* Gets the BGP routes.
*
* @return the BGP routes
*/
public Collection<BgpRouteEntry> getBgpRoutes();
/**
* Gets all the routes known to SDN-IP.
*
* @return the SDN-IP routes
*/
public Collection<RouteEntry> getRoutes();
}
package org.onlab.onos.sdnip.cli;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.sdnip.SdnIpService;
import org.onlab.onos.sdnip.bgp.BgpConstants;
import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
/**
* Command to show the routes learned through BGP.
*/
@Command(scope = "onos", name = "bgp-routes",
description = "Lists all routes received from BGP")
public class BgpRoutesListCommand extends AbstractShellCommand {
private static final String FORMAT =
"prefix=%s, nexthop=%s, origin=%s, localpref=%s, med=%s, aspath=%s, bgpid=%s";
@Override
protected void execute() {
SdnIpService service = get(SdnIpService.class);
for (BgpRouteEntry route : service.getBgpRoutes()) {
printRoute(route);
}
}
private void printRoute(BgpRouteEntry route) {
if (route != null) {
print(FORMAT, route.prefix(), route.nextHop(),
originToString(route.getOrigin()), route.getLocalPref(),
route.getMultiExitDisc(), route.getAsPath(),
route.getBgpSession().getRemoteBgpId());
}
}
private static String originToString(int origin) {
String originString = "UNKNOWN";
switch (origin) {
case BgpConstants.Update.Origin.IGP:
originString = "IGP";
break;
case BgpConstants.Update.Origin.EGP:
originString = "EGP";
break;
case BgpConstants.Update.Origin.INCOMPLETE:
originString = "INCOMPLETE";
break;
default:
break;
}
return originString;
}
}
package org.onlab.onos.sdnip.cli;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.sdnip.RouteEntry;
import org.onlab.onos.sdnip.SdnIpService;
/**
* Command to show the list of routes in SDN-IP's routing table.
*/
@Command(scope = "onos", name = "routes",
description = "Lists all routes known to SDN-IP")
public class RoutesListCommand extends AbstractShellCommand {
private static final String FORMAT =
"prefix=%s, nexthop=%s";
@Override
protected void execute() {
SdnIpService service = get(SdnIpService.class);
for (RouteEntry route : service.getRoutes()) {
printRoute(route);
}
}
private void printRoute(RouteEntry route) {
if (route != null) {
print(FORMAT, route.prefix(), route.nextHop());
}
}
}
<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.onlab.onos.sdnip.cli.BgpRoutesListCommand"/>
</command>
<command>
<action class="org.onlab.onos.sdnip.cli.RoutesListCommand"/>
</command>
</command-bundle>
</blueprint>