Implemented CLI commands to show SDN-IP routes
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 0ad0c11..ce77bf7 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -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>
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
index 2a1a655..dc29285 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
@@ -62,10 +62,8 @@
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 @@
* 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 @@
/**
* 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 @@
/**
* 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 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 @@
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());
}
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
index 3f94cba..e7ed601 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
@@ -2,14 +2,18 @@
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.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 @@
protected void deactivate() {
log.info("Stopped");
}
+
+ @Override
+ public Collection<BgpRouteEntry> getBgpRoutes() {
+ return bgpSessionManager.getBgpRoutes();
+ }
+
+ @Override
+ public Collection<RouteEntry> getRoutes() {
+ return router.getRoutes();
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
new file mode 100644
index 0000000..187ebb2
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
@@ -0,0 +1,24 @@
+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();
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java
new file mode 100644
index 0000000..63cc305
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpRoutesListCommand.java
@@ -0,0 +1,57 @@
+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;
+ }
+
+}
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java
new file mode 100644
index 0000000..1af409a
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/RoutesListCommand.java
@@ -0,0 +1,32 @@
+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());
+ }
+ }
+}
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
new file mode 100644
index 0000000..62fccec
--- /dev/null
+++ b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,11 @@
+<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>