blob: 15cb5548cffe37144ffcb0ff3a9bc23f3254a5fc [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Jonathan Hart0b04bed2014-10-16 16:39:19 -070016package org.onlab.onos.sdnip.cli;
17
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080018import java.util.Collection;
19
20import com.fasterxml.jackson.databind.JsonNode;
21import com.fasterxml.jackson.databind.ObjectMapper;
22import com.fasterxml.jackson.databind.node.ArrayNode;
23import com.fasterxml.jackson.databind.node.ObjectNode;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070024import org.apache.karaf.shell.commands.Command;
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080025import org.apache.karaf.shell.commands.Option;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070026import org.onlab.onos.cli.AbstractShellCommand;
27import org.onlab.onos.sdnip.SdnIpService;
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080028import org.onlab.onos.sdnip.bgp.BgpConstants.Update.AsPath;
29import org.onlab.onos.sdnip.bgp.BgpConstants.Update.Origin;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070030import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
31
32/**
33 * Command to show the routes learned through BGP.
34 */
35@Command(scope = "onos", name = "bgp-routes",
36 description = "Lists all routes received from BGP")
37public class BgpRoutesListCommand extends AbstractShellCommand {
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080038 @Option(name = "-s", aliases = "--summary",
39 description = "BGP routes summary",
40 required = false, multiValued = false)
41 private boolean routesSummary = false;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070042
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080043 private static final String FORMAT_SUMMARY = "Total BGP routes = %d";
44 private static final String FORMAT_ROUTE =
Jonathan Hart0b04bed2014-10-16 16:39:19 -070045 "prefix=%s, nexthop=%s, origin=%s, localpref=%s, med=%s, aspath=%s, bgpid=%s";
46
47 @Override
48 protected void execute() {
49 SdnIpService service = get(SdnIpService.class);
50
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080051 // Print summary of the routes
52 if (routesSummary) {
53 printSummary(service.getBgpRoutes());
54 return;
55 }
56
57 // Print all routes
58 printRoutes(service.getBgpRoutes());
59 }
60
61 /**
62 * Prints summary of the routes.
63 *
64 * @param routes the routes
65 */
66 private void printSummary(Collection<BgpRouteEntry> routes) {
67 if (outputJson()) {
68 ObjectMapper mapper = new ObjectMapper();
69 ObjectNode result = mapper.createObjectNode();
70 result.put("totalRoutes", routes.size());
71 print("%s", result);
72 } else {
73 print(FORMAT_SUMMARY, routes.size());
Jonathan Hart0b04bed2014-10-16 16:39:19 -070074 }
75 }
76
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080077 /**
78 * Prints all routes.
79 *
80 * @param routes the routes to print
81 */
82 private void printRoutes(Collection<BgpRouteEntry> routes) {
83 if (outputJson()) {
84 print("%s", json(routes));
85 } else {
86 for (BgpRouteEntry route : routes) {
87 printRoute(route);
88 }
89 }
90 }
91
92 /**
93 * Prints a BGP route.
94 *
95 * @param route the route to print
96 */
Jonathan Hart0b04bed2014-10-16 16:39:19 -070097 private void printRoute(BgpRouteEntry route) {
98 if (route != null) {
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -080099 print(FORMAT_ROUTE, route.prefix(), route.nextHop(),
100 Origin.typeToString(route.getOrigin()),
101 route.getLocalPref(), route.getMultiExitDisc(),
102 route.getAsPath(), route.getBgpSession().getRemoteBgpId());
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700103 }
104 }
105
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -0800106 /**
107 * Produces a JSON array of routes.
108 *
109 * @param routes the routes with the data
110 * @return JSON array with the routes
111 */
112 private JsonNode json(Collection<BgpRouteEntry> routes) {
113 ObjectMapper mapper = new ObjectMapper();
114 ArrayNode result = mapper.createArrayNode();
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700115
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -0800116 for (BgpRouteEntry route : routes) {
117 result.add(json(mapper, route));
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700118 }
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -0800119 return result;
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700120 }
121
Pavlin Radoslavov2ce1c522014-11-07 10:32:37 -0800122 /**
123 * Produces JSON object for a route.
124 *
125 * @param mapper the JSON object mapper to use
126 * @param route the route with the data
127 * @return JSON object for the route
128 */
129 private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
130 ObjectNode result = mapper.createObjectNode();
131
132 result.put("prefix", route.prefix().toString());
133 result.put("nextHop", route.nextHop().toString());
134 result.put("bgpId", route.getBgpSession().getRemoteBgpId().toString());
135 result.put("origin", Origin.typeToString(route.getOrigin()));
136 result.put("asPath", json(mapper, route.getAsPath()));
137 result.put("localPref", route.getLocalPref());
138 result.put("multiExitDisc", route.getMultiExitDisc());
139
140 return result;
141 }
142
143 /**
144 * Produces JSON object for an AS path.
145 *
146 * @param mapper the JSON object mapper to use
147 * @param asPath the AS path with the data
148 * @return JSON object for the AS path
149 */
150 private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
151 ObjectNode result = mapper.createObjectNode();
152 ArrayNode pathSegmentsJson = mapper.createArrayNode();
153 for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
154 ObjectNode pathSegmentJson = mapper.createObjectNode();
155 pathSegmentJson.put("type",
156 AsPath.typeToString(pathSegment.getType()));
157 ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
158 for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
159 segmentAsNumbersJson.add(asNumber);
160 }
161 pathSegmentJson.put("segmentAsNumbers", segmentAsNumbersJson);
162 pathSegmentsJson.add(pathSegmentJson);
163 }
164 result.put("pathSegments", pathSegmentsJson);
165
166 return result;
167 }
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700168}