sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2016-present Open Networking Foundation |
sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 3 | * |
| 4 | * 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 |
| 7 | * |
| 8 | * 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. |
| 15 | */ |
| 16 | package org.onosproject.ospf.cli; |
| 17 | |
Ray Milkey | 7a2dee5 | 2018-09-28 10:58:28 -0700 | [diff] [blame] | 18 | import org.apache.karaf.shell.api.action.lifecycle.Service; |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 19 | import org.osgi.service.component.annotations.Activate; |
| 20 | import org.osgi.service.component.annotations.Component; |
| 21 | import org.osgi.service.component.annotations.Deactivate; |
| 22 | import org.osgi.service.component.annotations.Reference; |
| 23 | import org.osgi.service.component.annotations.ReferenceCardinality; |
Ray Milkey | 86ad7bb | 2018-09-27 12:32:28 -0700 | [diff] [blame] | 24 | import org.apache.karaf.shell.api.action.Argument; |
| 25 | import org.apache.karaf.shell.api.action.Command; |
sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 26 | import org.onosproject.cli.AbstractShellCommand; |
| 27 | import org.onosproject.ospf.controller.OspfArea; |
| 28 | import org.onosproject.ospf.controller.OspfController; |
| 29 | import org.onosproject.ospf.controller.OspfInterface; |
| 30 | import org.onosproject.ospf.controller.OspfLsaType; |
| 31 | import org.onosproject.ospf.controller.OspfNbr; |
| 32 | import org.onosproject.ospf.controller.OspfProcess; |
| 33 | import org.onosproject.ospf.protocol.lsa.LsaHeader; |
| 34 | import org.onosproject.ospf.protocol.lsa.types.RouterLsa; |
| 35 | |
| 36 | import java.util.ArrayList; |
| 37 | import java.util.Iterator; |
| 38 | import java.util.List; |
| 39 | |
| 40 | /** |
| 41 | * Representation of OSPF cli commands. |
| 42 | */ |
Ray Milkey | 7a2dee5 | 2018-09-28 10:58:28 -0700 | [diff] [blame] | 43 | @Service |
sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 44 | @Component(immediate = true) |
| 45 | @Command(scope = "onos", name = "ospf", description = "list database") |
| 46 | public class ApplicationOspfCommand extends AbstractShellCommand { |
| 47 | |
| 48 | protected static final String FORMAT6 = "%-20s%-20s%-20s%-20s%-20s%-20s\n"; |
| 49 | protected static final String FORMAT5 = "%-20s%-20s%-20s%-20s%-20s\n"; |
| 50 | protected static final String NETWORK = "NETWORK"; |
| 51 | protected static final String SUMMARY = "SUMMARY"; |
| 52 | protected static final String ASBR = "ABSR"; |
| 53 | protected static final String EXTERNAL = "EXTERNAL"; |
| 54 | protected static final String LINKLOOPAQ = "LINKLOCALOPAQUE"; |
| 55 | protected static final String AREALOCOPAQ = "AREALOCALOPAQUE"; |
| 56 | protected static final String ASOPAQ = "ASOPAQUE"; |
| 57 | protected static final String DR = "DR"; |
| 58 | protected static final String BACKUP = "BACKUP"; |
| 59 | protected static final String DROTHER = "DROther"; |
| 60 | static final String DATABASE = "database"; |
| 61 | static final String NEIGHBORLIST = "neighbors"; |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 62 | @Reference(cardinality = ReferenceCardinality.MANDATORY) |
sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 63 | protected OspfController ospfController; |
| 64 | @Argument(index = 0, name = "name", |
| 65 | description = "database|neighborlist", |
| 66 | required = true, multiValued = false) |
| 67 | private String name = null; |
| 68 | @Argument(index = 1, name = "processid", |
| 69 | description = "processId", |
| 70 | required = true, multiValued = false) |
| 71 | private String process = null; |
| 72 | @Argument(index = 2, name = "areaid", |
| 73 | description = "areaId", |
| 74 | required = false, multiValued = false) |
| 75 | private String area = null; |
| 76 | private List<String> routerLsa = new ArrayList<>(); |
| 77 | private List<String> networkLsa = new ArrayList<>(); |
| 78 | private List<String> summaryLsa = new ArrayList<>(); |
| 79 | private List<String> externalLsa = new ArrayList<>(); |
| 80 | private List<String> asbrSumm = new ArrayList<>(); |
| 81 | private List<String> areaLocalOpaqLsa = new ArrayList<>(); |
| 82 | private List<String> linkLocalOpqLsa = new ArrayList<>(); |
| 83 | private List<String> asOpqLsa = new ArrayList<>(); |
| 84 | private List<String> undefinedLsa = new ArrayList<>(); |
| 85 | private List<OspfArea> areaList = new ArrayList<>(); |
| 86 | |
| 87 | |
| 88 | @Activate |
| 89 | public void activate() { |
| 90 | print("OSPF cli activated...!!!"); |
| 91 | log.debug("OSPF cli activated...!!!"); |
| 92 | } |
| 93 | |
| 94 | @Deactivate |
| 95 | public void deactivate() { |
| 96 | log.debug("OSPF cli deactivated...!!!"); |
| 97 | } |
| 98 | |
| 99 | @Override |
Ray Milkey | 86ad7bb | 2018-09-27 12:32:28 -0700 | [diff] [blame] | 100 | protected void doExecute() { |
sunishvk | f7c5655 | 2016-07-18 16:02:39 +0530 | [diff] [blame] | 101 | if (DATABASE.equals(name)) { |
| 102 | buildOspfDatabaseInformation(); |
| 103 | } else if (NEIGHBORLIST.equals(name)) { |
| 104 | buildNeighborInformation(); |
| 105 | } else { |
| 106 | print("Please check the command (database|neighbor)"); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Clears all the lists. |
| 112 | */ |
| 113 | private void clearLists() { |
| 114 | routerLsa.clear(); |
| 115 | networkLsa.clear(); |
| 116 | summaryLsa.clear(); |
| 117 | externalLsa.clear(); |
| 118 | asbrSumm.clear(); |
| 119 | areaLocalOpaqLsa.clear(); |
| 120 | linkLocalOpqLsa.clear(); |
| 121 | asOpqLsa.clear(); |
| 122 | undefinedLsa.clear(); |
| 123 | areaList.clear(); |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * Builds OSPF database information. |
| 128 | */ |
| 129 | private void buildOspfDatabaseInformation() { |
| 130 | try { |
| 131 | //Builds LSA details |
| 132 | buildLsaLists(); |
| 133 | for (OspfArea area : areaList) { |
| 134 | if (routerLsa.size() > 0) { |
| 135 | printRouterFormat(area.areaId().toString(), area.routerId().toString(), process); |
| 136 | for (String str : routerLsa) { |
| 137 | String[] lsaVal = str.split("\\,"); |
| 138 | if (area.areaId().toString().equalsIgnoreCase(lsaVal[0])) { |
| 139 | print(FORMAT6, lsaVal[2], lsaVal[3], lsaVal[4], lsaVal[5], lsaVal[6], lsaVal[7]); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | if (networkLsa.size() > 0) { |
| 144 | printNetworkFormat(area.areaId().toString(), NETWORK); |
| 145 | printDetails(networkLsa, area.areaId().toString()); |
| 146 | } |
| 147 | if (summaryLsa.size() > 0) { |
| 148 | printNetworkFormat(area.areaId().toString(), SUMMARY); |
| 149 | printDetails(summaryLsa, area.areaId().toString()); |
| 150 | } |
| 151 | if (externalLsa.size() > 0) { |
| 152 | printNetworkFormat(area.areaId().toString(), EXTERNAL); |
| 153 | printDetails(externalLsa, area.areaId().toString()); |
| 154 | } |
| 155 | if (asbrSumm.size() > 0) { |
| 156 | printNetworkFormat(area.areaId().toString(), ASBR); |
| 157 | printDetails(asbrSumm, area.areaId().toString()); |
| 158 | } |
| 159 | if (areaLocalOpaqLsa.size() > 0) { |
| 160 | printNetworkFormat(area.areaId().toString(), AREALOCOPAQ); |
| 161 | printDetails(areaLocalOpaqLsa, area.areaId().toString()); |
| 162 | } |
| 163 | if (linkLocalOpqLsa.size() > 0) { |
| 164 | printNetworkFormat(area.areaId().toString(), LINKLOOPAQ); |
| 165 | printDetails(linkLocalOpqLsa, area.areaId().toString()); |
| 166 | } |
| 167 | if (asOpqLsa.size() > 0) { |
| 168 | printNetworkFormat(area.areaId().toString(), ASOPAQ); |
| 169 | printDetails(asOpqLsa, area.areaId().toString()); |
| 170 | } |
| 171 | if (undefinedLsa.size() > 0) { |
| 172 | printRouterFormat(area.areaId().toString(), area.routerId().toString(), process); |
| 173 | printDetails(undefinedLsa, area.areaId().toString()); |
| 174 | } |
| 175 | } |
| 176 | clearLists(); |
| 177 | } catch (Exception ex) { |
| 178 | clearLists(); |
| 179 | print("Error occured while Ospf controller getting called" + ex.getMessage()); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | /** |
| 184 | * Prints LSA details. |
| 185 | * |
| 186 | * @param lsaDetails LSA details |
| 187 | * @param areaId area ID |
| 188 | */ |
| 189 | private void printDetails(List<String> lsaDetails, String areaId) { |
| 190 | for (String str : lsaDetails) { |
| 191 | String[] lsaVal = str.split("\\,"); |
| 192 | if (areaId.equalsIgnoreCase(lsaVal[0])) { |
| 193 | print(FORMAT5, lsaVal[2], lsaVal[3], lsaVal[4], lsaVal[5], lsaVal[6]); |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | /** |
| 199 | * Builds all LSA lists with LSA details. |
| 200 | */ |
| 201 | private void buildLsaLists() { |
| 202 | this.ospfController = get(OspfController.class); |
| 203 | List<OspfProcess> listOfProcess = ospfController.getAllConfiguredProcesses(); |
| 204 | Iterator<OspfProcess> itrProcess = listOfProcess.iterator(); |
| 205 | while (itrProcess.hasNext()) { |
| 206 | OspfProcess ospfProcess = itrProcess.next(); |
| 207 | if (process.equalsIgnoreCase(ospfProcess.processId())) { |
| 208 | List<OspfArea> listAreas = ospfProcess.areas(); |
| 209 | Iterator<OspfArea> itrArea = listAreas.iterator(); |
| 210 | while (itrArea.hasNext()) { |
| 211 | OspfArea area = itrArea.next(); |
| 212 | List<LsaHeader> lsas = area.database() |
| 213 | .getAllLsaHeaders(false, area.isOpaqueEnabled()); |
| 214 | List<LsaHeader> tmpLsaList = new ArrayList<>(lsas); |
| 215 | log.debug("OSPFController::size of database::" + (lsas != null ? lsas.size() : null)); |
| 216 | Iterator<LsaHeader> itrLsaHeader = tmpLsaList.iterator(); |
| 217 | areaList.add(area); |
| 218 | if (itrLsaHeader != null) { |
| 219 | while (itrLsaHeader.hasNext()) { |
| 220 | LsaHeader header = itrLsaHeader.next(); |
| 221 | populateLsaLists(header, area); |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | /** |
| 230 | * Populates the LSA lists based on the input. |
| 231 | * |
| 232 | * @param header LSA header instance |
| 233 | * @param area OSPF area instance |
| 234 | */ |
| 235 | private void populateLsaLists(LsaHeader header, OspfArea area) { |
| 236 | String seqNo = Long.toHexString(header.lsSequenceNo()); |
| 237 | String checkSum = Long.toHexString(header.lsCheckSum()); |
| 238 | if (seqNo.length() == 16) { |
| 239 | seqNo = seqNo.substring(8, seqNo.length()); |
| 240 | } |
| 241 | if (checkSum.length() == 16) { |
| 242 | checkSum = checkSum.substring(8, checkSum.length()); |
| 243 | } |
| 244 | StringBuffer strBuf = getBuffList(area.areaId().toString(), area.routerId().toString(), |
| 245 | header.linkStateId(), |
| 246 | header.advertisingRouter().toString(), |
| 247 | header.age(), seqNo, checkSum); |
| 248 | if (header.lsType() == OspfLsaType.ROUTER.value()) { |
| 249 | strBuf.append(","); |
| 250 | strBuf.append(((RouterLsa) header).noLink()); |
| 251 | routerLsa.add(strBuf.toString()); |
| 252 | } else if (header.lsType() == OspfLsaType.NETWORK.value()) { |
| 253 | strBuf.append(","); |
| 254 | strBuf.append("0"); |
| 255 | networkLsa.add(strBuf.toString()); |
| 256 | } else if (header.lsType() == OspfLsaType.SUMMARY.value()) { |
| 257 | strBuf.append(","); |
| 258 | strBuf.append("0"); |
| 259 | summaryLsa.add(strBuf.toString()); |
| 260 | } else if (header.lsType() == OspfLsaType.EXTERNAL_LSA.value()) { |
| 261 | strBuf.append(","); |
| 262 | strBuf.append("0"); |
| 263 | externalLsa.add(strBuf.toString()); |
| 264 | } else if (header.lsType() == OspfLsaType.ASBR_SUMMARY.value()) { |
| 265 | strBuf.append(","); |
| 266 | strBuf.append("0"); |
| 267 | asbrSumm.add(strBuf.toString()); |
| 268 | } else if (header.lsType() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) { |
| 269 | strBuf.append(","); |
| 270 | strBuf.append("0"); |
| 271 | areaLocalOpaqLsa.add(strBuf.toString()); |
| 272 | } else if (header.lsType() == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value()) { |
| 273 | strBuf.append(","); |
| 274 | strBuf.append("0"); |
| 275 | linkLocalOpqLsa.add(strBuf.toString()); |
| 276 | } else if (header.lsType() == OspfLsaType.AS_OPAQUE_LSA.value()) { |
| 277 | strBuf.append(","); |
| 278 | strBuf.append("0"); |
| 279 | asOpqLsa.add(strBuf.toString()); |
| 280 | } else { |
| 281 | strBuf.append(","); |
| 282 | strBuf.append("0"); |
| 283 | undefinedLsa.add(strBuf.toString()); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | /** |
| 288 | * Builds OSPF neighbor information. |
| 289 | */ |
| 290 | private void buildNeighborInformation() { |
| 291 | try { |
| 292 | this.ospfController = get(OspfController.class); |
| 293 | List<OspfProcess> listOfProcess = ospfController.getAllConfiguredProcesses(); |
| 294 | boolean flag = false; |
| 295 | printNeighborsFormat(); |
| 296 | Iterator<OspfProcess> itrProcess = listOfProcess.iterator(); |
| 297 | while (itrProcess.hasNext()) { |
| 298 | OspfProcess process = itrProcess.next(); |
| 299 | List<OspfArea> listAreas = process.areas(); |
| 300 | Iterator<OspfArea> itrArea = listAreas.iterator(); |
| 301 | while (itrArea.hasNext()) { |
| 302 | OspfArea area = itrArea.next(); |
| 303 | List<OspfInterface> itrefaceList = area.ospfInterfaceList(); |
| 304 | for (OspfInterface interfc : itrefaceList) { |
| 305 | List<OspfNbr> nghbrList = new ArrayList<>(interfc.listOfNeighbors().values()); |
| 306 | for (OspfNbr neigbor : nghbrList) { |
| 307 | print("%-20s%-20s%-20s%-20s%-20s\n", neigbor.neighborId(), neigbor.routerPriority(), |
| 308 | neigbor.getState() + "/" + checkDrBdrOther(neigbor.neighborIpAddr().toString(), |
| 309 | neigbor.neighborDr().toString(), |
| 310 | neigbor.neighborBdr().toString()), |
| 311 | neigbor.neighborIpAddr().toString(), interfc.ipAddress()); |
| 312 | } |
| 313 | } |
| 314 | } |
| 315 | } |
| 316 | } catch (Exception ex) { |
| 317 | print("Error occured while Ospf controller getting called" + ex.getMessage()); |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | /** |
| 322 | * Prints input after formatting. |
| 323 | * |
| 324 | * @param areaId area ID |
| 325 | * @param routerId router ID |
| 326 | * @param processId process ID |
| 327 | */ |
| 328 | private void printRouterFormat(String areaId, String routerId, String processId) { |
| 329 | print("%s (%s) %s %s\n", "OSPF Router with ID", routerId, "Process Id", processId); |
| 330 | print("%s ( Area %s)\n", "Router Link States", areaId); |
| 331 | print("%-20s%-20s%-20s%-20s%-20s%-20s\n", "Link Id", "ADV Router", "Age", "Seq#", |
| 332 | "CkSum", "Link Count"); |
| 333 | } |
| 334 | |
| 335 | /** |
| 336 | * Prints input after formatting. |
| 337 | * |
| 338 | * @param areaId area ID |
| 339 | * @param type network type |
| 340 | */ |
| 341 | private void printNetworkFormat(String areaId, String type) { |
| 342 | print("%s %s ( Area %s)\n", type, "Link States", areaId); |
| 343 | print("%-20s%-20s%-20s%-20s%-20s\n", "Link Id", "ADV Router", "Age", "Seq#", "CkSum"); |
| 344 | } |
| 345 | |
| 346 | /** |
| 347 | * Prints input after formatting. |
| 348 | */ |
| 349 | private void printNeighborsFormat() { |
| 350 | print("%-20s%-20s%-20s%-20s%-20s\n", "Neighbor Id", "Pri", "State", |
| 351 | "Address", "Interface"); |
| 352 | } |
| 353 | |
| 354 | /** |
| 355 | * Checks whether the neighbor is DR or BDR. |
| 356 | * |
| 357 | * @param ip IP address to check |
| 358 | * @param drIP DRs IP address |
| 359 | * @param bdrIp BDRs IP address |
| 360 | * @return 1- neighbor is DR, 2- neighbor is BDR, 3- DROTHER |
| 361 | */ |
| 362 | public String checkDrBdrOther(String ip, String drIP, String bdrIp) { |
| 363 | |
| 364 | if (ip.equalsIgnoreCase(drIP)) { |
| 365 | return DR; |
| 366 | } else if (ip.equalsIgnoreCase(bdrIp)) { |
| 367 | return BACKUP; |
| 368 | } else { |
| 369 | return DROTHER; |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | /** |
| 374 | * Returns inputs as formatted string. |
| 375 | * |
| 376 | * @param areaId area id |
| 377 | * @param routerId router id |
| 378 | * @param linkStateId link state id |
| 379 | * @param advertisingRouter advertising router |
| 380 | * @param age age |
| 381 | * @param seqNo sequence number |
| 382 | * @param checkSum checksum |
| 383 | * @return formatted string |
| 384 | */ |
| 385 | private StringBuffer getBuffList(String areaId, String routerId, String linkStateId, |
| 386 | String advertisingRouter, int age, String seqNo, String checkSum) { |
| 387 | StringBuffer strBuf = new StringBuffer(); |
| 388 | strBuf.append(areaId); |
| 389 | strBuf.append(","); |
| 390 | strBuf.append(routerId); |
| 391 | strBuf.append(","); |
| 392 | strBuf.append(linkStateId); |
| 393 | strBuf.append(","); |
| 394 | strBuf.append(advertisingRouter); |
| 395 | strBuf.append(","); |
| 396 | strBuf.append(age); |
| 397 | strBuf.append(","); |
| 398 | strBuf.append(seqNo); |
| 399 | strBuf.append(","); |
| 400 | strBuf.append(checkSum); |
| 401 | return strBuf; |
| 402 | } |
| 403 | } |