aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java')
-rw-r--r--framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java283
1 files changed, 283 insertions, 0 deletions
diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
new file mode 100644
index 00000000..ab8e975a
--- /dev/null
+++ b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2014-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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+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.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpRouteEntry;
+import org.onosproject.routing.bgp.BgpSession;
+import org.onosproject.routing.bgp.BgpConstants;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Command to show the routes learned through BGP.
+ */
+@Command(scope = "onos", name = "bgp-routes",
+ description = "Lists all BGP best routes")
+public class BgpRoutesListCommand extends AbstractShellCommand {
+ @Option(name = "-s", aliases = "--summary",
+ description = "BGP routes summary",
+ required = false, multiValued = false)
+ private boolean routesSummary = false;
+
+ @Option(name = "-n", aliases = "--neighbor",
+ description = "Routes from a BGP neighbor",
+ required = false, multiValued = false)
+ private String bgpNeighbor;
+
+ private static final String FORMAT_SUMMARY_V4 =
+ "Total BGP IPv4 routes = %d";
+ private static final String FORMAT_SUMMARY_V6 =
+ "Total BGP IPv6 routes = %d";
+ private static final String FORMAT_HEADER =
+ " Network Next Hop Origin LocalPref MED BGP-ID";
+ private static final String FORMAT_ROUTE_LINE1 =
+ " %-18s %-15s %6s %9s %9s %-15s";
+ private static final String FORMAT_ROUTE_LINE2 =
+ " AsPath %s";
+
+ @Override
+ protected void execute() {
+ BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
+
+ // Print summary of the routes
+ if (routesSummary) {
+ printSummary(service.getBgpRoutes4(), service.getBgpRoutes6());
+ return;
+ }
+
+ BgpSession foundBgpSession = null;
+ if (bgpNeighbor != null) {
+ // Print the routes from a single neighbor (if found)
+ for (BgpSession bgpSession : service.getBgpSessions()) {
+ if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
+ foundBgpSession = bgpSession;
+ break;
+ }
+ }
+ if (foundBgpSession == null) {
+ print("BGP neighbor %s not found", bgpNeighbor);
+ return;
+ }
+ }
+
+ // Print the routes
+ if (foundBgpSession != null) {
+ printRoutes(foundBgpSession.getBgpRibIn4(),
+ foundBgpSession.getBgpRibIn6());
+ } else {
+ printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6());
+ }
+ }
+
+ /**
+ * Prints summary of the routes.
+ *
+ * @param routes4 the IPv4 routes
+ * @param routes6 the IPv6 routes
+ */
+ private void printSummary(Collection<BgpRouteEntry> routes4,
+ Collection<BgpRouteEntry> routes6) {
+ if (outputJson()) {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode result = mapper.createObjectNode();
+ result.put("totalRoutes4", routes4.size());
+ result.put("totalRoutes6", routes6.size());
+ print("%s", result);
+ } else {
+ print(FORMAT_SUMMARY_V4, routes4.size());
+ print(FORMAT_SUMMARY_V6, routes6.size());
+ }
+ }
+
+ /**
+ * Prints all routes.
+ *
+ * @param routes4 the IPv4 routes to print
+ * @param routes6 the IPv6 routes to print
+ */
+ private void printRoutes(Collection<BgpRouteEntry> routes4,
+ Collection<BgpRouteEntry> routes6) {
+ if (outputJson()) {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode result = mapper.createObjectNode();
+ result.set("routes4", json(routes4));
+ result.set("routes6", json(routes6));
+ print("%s", result);
+ } else {
+ // The IPv4 routes
+ print(FORMAT_HEADER);
+ for (BgpRouteEntry route : routes4) {
+ printRoute(route);
+ }
+ print(FORMAT_SUMMARY_V4, routes4.size());
+ print(""); // Empty separator line
+ // The IPv6 routes
+ print(FORMAT_HEADER);
+ for (BgpRouteEntry route : routes6) {
+ printRoute(route);
+ }
+ print(FORMAT_SUMMARY_V6, routes6.size());
+ }
+ }
+
+ /**
+ * Prints a BGP route.
+ *
+ * @param route the route to print
+ */
+ private void printRoute(BgpRouteEntry route) {
+ if (route != null) {
+ print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
+ BgpConstants.Update.Origin.typeToString(route.getOrigin()),
+ route.getLocalPref(), route.getMultiExitDisc(),
+ route.getBgpSession().remoteInfo().bgpId());
+ print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
+ }
+ }
+
+ /**
+ * Formats the AS Path as a string that can be shown on the CLI.
+ *
+ * @param asPath the AS Path to format
+ * @return the AS Path as a string
+ */
+ private String asPath4Cli(BgpRouteEntry.AsPath asPath) {
+ ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+ asPath.getPathSegments();
+
+ if (pathSegments.isEmpty()) {
+ return "[none]";
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ for (BgpRouteEntry.PathSegment pathSegment : pathSegments) {
+ String prefix = null;
+ String suffix = null;
+ switch (pathSegment.getType()) {
+ case BgpConstants.Update.AsPath.AS_SET:
+ prefix = "[AS-Set";
+ suffix = "]";
+ break;
+ case BgpConstants.Update.AsPath.AS_SEQUENCE:
+ break;
+ case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
+ prefix = "[AS-Confed-Seq";
+ suffix = "]";
+ break;
+ case BgpConstants.Update.AsPath.AS_CONFED_SET:
+ prefix = "[AS-Confed-Set";
+ suffix = "]";
+ break;
+ default:
+ builder.append(String.format("(type = %s)",
+ BgpConstants.Update.AsPath.typeToString(pathSegment.getType())));
+ break;
+ }
+
+ if (prefix != null) {
+ if (builder.length() > 0) {
+ builder.append(" "); // Separator
+ }
+ builder.append(prefix);
+ }
+ // Print the AS numbers
+ for (Long asn : pathSegment.getSegmentAsNumbers()) {
+ if (builder.length() > 0) {
+ builder.append(" "); // Separator
+ }
+ builder.append(String.format("%d", asn));
+ }
+ if (suffix != null) {
+ // No need for separator
+ builder.append(prefix);
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Produces a JSON array of routes.
+ *
+ * @param routes the routes with the data
+ * @return JSON array with the routes
+ */
+ private JsonNode json(Collection<BgpRouteEntry> routes) {
+ ObjectMapper mapper = new ObjectMapper();
+ ArrayNode result = mapper.createArrayNode();
+
+ for (BgpRouteEntry route : routes) {
+ result.add(json(mapper, route));
+ }
+ return result;
+ }
+
+ /**
+ * Produces JSON object for a route.
+ *
+ * @param mapper the JSON object mapper to use
+ * @param route the route with the data
+ * @return JSON object for the route
+ */
+ private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
+ ObjectNode result = mapper.createObjectNode();
+
+ result.put("prefix", route.prefix().toString());
+ result.put("nextHop", route.nextHop().toString());
+ result.put("bgpId",
+ route.getBgpSession().remoteInfo().bgpId().toString());
+ result.put("origin", BgpConstants.Update.Origin.typeToString(route.getOrigin()));
+ result.set("asPath", json(mapper, route.getAsPath()));
+ result.put("localPref", route.getLocalPref());
+ result.put("multiExitDisc", route.getMultiExitDisc());
+
+ return result;
+ }
+
+ /**
+ * Produces JSON object for an AS path.
+ *
+ * @param mapper the JSON object mapper to use
+ * @param asPath the AS path with the data
+ * @return JSON object for the AS path
+ */
+ private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
+ ObjectNode result = mapper.createObjectNode();
+ ArrayNode pathSegmentsJson = mapper.createArrayNode();
+ for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
+ ObjectNode pathSegmentJson = mapper.createObjectNode();
+ pathSegmentJson.put("type",
+ BgpConstants.Update.AsPath.typeToString(pathSegment.getType()));
+ ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
+ for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+ segmentAsNumbersJson.add(asNumber);
+ }
+ pathSegmentJson.set("segmentAsNumbers", segmentAsNumbersJson);
+ pathSegmentsJson.add(pathSegmentJson);
+ }
+ result.set("pathSegments", pathSegmentsJson);
+
+ return result;
+ }
+}