2 * Copyright (c) 2015 - 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.fibmanager.shell;
11 import java.io.PrintStream;
12 import java.net.Inet4Address;
13 import java.net.Inet6Address;
14 import java.net.InetAddress;
15 import java.net.UnknownHostException;
16 import java.util.List;
17 import java.util.Locale;
18 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command;
20 import org.apache.karaf.shell.commands.Option;
21 import org.apache.karaf.shell.console.OsgiCommandSupport;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
25 import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
26 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
27 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.VrfEntryBase.EncapType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 @Command(scope = "vpnservice", name = "fib-show", description = "Displays fib entries.\t"
38 + "To get more help use cli fib-show fullHelp")
39 public class ShowFibCommand extends OsgiCommandSupport {
41 private static final Logger LOG = LoggerFactory.getLogger(ShowFibCommand.class);
43 private static final String TABULAR_FORMAT = " %-7s %-20s %-20s %-7s %-7s";
44 private static final String HEADER = String.format(TABULAR_FORMAT, "RD", "Prefix", "NextHop", "Label", "Origin")
45 + "\n -------------------------------------------------------------------";
46 private static final String ADDRFAMILY = "--addr-family";
47 private static final String SUBNET = "--subnet";
49 @Argument(name = "addFam|fullHelp", description = "type of address families to show, or full help cli",
50 required = false, multiValued = false)
51 private final String options = null;
53 @Option(name = ADDRFAMILY, aliases = {"-af"},
54 description = "show address family ipv4 and/or ipv6 and/or l2vpn",
55 required = false, multiValued = true)
56 private final List<String> addrFamList = null;
58 @Option(name = SUBNET, aliases = {"-sub"},
59 description = "show only one IP or subnet sorted by mask ex \"x.x.x.x/32\" or \"2001::1/128\"",
60 required = false, multiValued = true)
61 private final String prefixOrSubnetOption = null;
62 private String prefixOrSubnet = null;
64 private SingleTransactionDataBroker singleTxDb;
66 public void setDataBroker(DataBroker dataBroker) {
67 this.singleTxDb = new SingleTransactionDataBroker(dataBroker);
71 protected Object doExecute() {
72 PrintStream console = session.getConsole();
73 if (prefixOrSubnetOption != null && prefixOrSubnetOption.length() > 0) {
74 prefixOrSubnet = prefixOrSubnetOption.replace("[", "");
75 prefixOrSubnet = prefixOrSubnet.replace("]", "");
76 if (prefixOrSubnet.indexOf("/") < 0) {
77 String maskFull = null;
79 Inet4Address tempAdd = (Inet4Address) InetAddress.getByName(prefixOrSubnet);
81 } catch (SecurityException | UnknownHostException | ClassCastException e) {
84 if (maskFull == null) {
86 Inet6Address tempAdd = (Inet6Address) InetAddress.getByName(prefixOrSubnet);
88 } catch (SecurityException | UnknownHostException | ClassCastException e) {
92 if (maskFull == null) {
93 console.println("a part of cli " + SUBNET + " is wrong => " + prefixOrSubnet);
94 return usage(console);
96 prefixOrSubnet += maskFull;
99 console.println(HEADER);
100 if (options == null && prefixOrSubnet == null && (addrFamList == null || addrFamList.isEmpty())) {
101 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
103 FibEntries fibEntries = singleTxDb.syncRead(LogicalDatastoreType.CONFIGURATION, id);
105 List<VrfTables> vrfTablesList = fibEntries.getVrfTables();
106 if (vrfTablesList == null || vrfTablesList.isEmpty()) {
107 console.println(" No Fib entries found");
111 for (VrfTables vrfTable : vrfTablesList) {
112 printVrfTable(vrfTable, console);
114 } catch (ExpectedDataObjectNotFoundException e404) {
115 String errMsg = "FATAL: fib-entries container is missing from MD-SAL";
116 console.println("\n" + errMsg);
117 LOG.error(errMsg, e404);
118 } catch (ReadFailedException rfe) {
119 String errMsg = "Internal Error occurred while processing vpnservice:fib-show command";
120 console.println("\n" + errMsg);
121 LOG.error(errMsg, rfe);
125 String optionsLowerCase = options != null ? options.toLowerCase(Locale.getDefault()) : "";
126 switch (optionsLowerCase) {
128 return usage(console);
132 if ((addrFamList == null || addrFamList.isEmpty()) && (prefixOrSubnet == null
133 || prefixOrSubnet.indexOf("/") < 5)) {
134 console.println("any address family is requiered or " + SUBNET + " is wrong");
137 boolean isIpv4 = false;
138 boolean isIpv6 = false;
139 boolean isL2vpn = false;
140 if (addrFamList != null && addrFamList.size() > 0) {
141 for (String addF : addrFamList) {
142 switch (addF.toLowerCase(Locale.getDefault())) {
156 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
158 FibEntries fibEntries = singleTxDb.syncRead(LogicalDatastoreType.CONFIGURATION, id);
160 List<VrfTables> vrfTablesList = fibEntries.getVrfTables();
161 if (vrfTablesList == null || vrfTablesList.isEmpty()) {
162 console.println(" No Fib entries found");
166 for (VrfTables vrfTable : vrfTablesList) {
167 printVrfTable(vrfTable, console, isIpv4, isIpv6, isL2vpn, prefixOrSubnet);
169 } catch (ExpectedDataObjectNotFoundException e404) {
170 String errMsg = "FATAL: fib-entries container is missing from MD-SAL";
171 console.println("\n" + errMsg);
172 LOG.error(errMsg, e404);
173 } catch (ReadFailedException rfe) {
174 String errMsg = "Internal Error occurred while processing vpnservice:fib-show command";
175 console.println("\n" + errMsg);
176 LOG.error(errMsg, rfe);
184 private void printVrfTable(VrfTables vrfTable, PrintStream console) {
185 printVrfTable(vrfTable, console, true, true, true, null);
188 private void printVrfTable(VrfTables vrfTable, PrintStream console, boolean isIpv4, boolean isIpv6,
189 boolean isL2vpn, String inputPrefixOrSubnet) {
191 List<VrfEntry> vrfEntries = vrfTable.getVrfEntry();
192 if (vrfEntries == null) {
193 LOG.warn("Null vrfEntries found for VPN with rd={}", vrfTable.getRouteDistinguisher());
197 for (VrfEntry vrfEntry : vrfEntries) {
198 boolean showIt = false;
199 if (isIpv4 && isIpv6 && isL2vpn) {
202 if (!showIt && isIpv4) {
203 LOG.debug("is ipv4 address family=> vrfEntry.getDestPrefix() = " + vrfEntry.getDestPrefix());
204 showIt = FibHelper.isIpv4Prefix(vrfEntry.getDestPrefix());
206 if (!showIt && isIpv6) {
207 LOG.debug("is ipv6 address family=> vrfEntry.getDestPrefix() = " + vrfEntry.getDestPrefix());
208 showIt = FibHelper.isIpv6Prefix(vrfEntry.getDestPrefix());
210 if (!showIt && isL2vpn) {
211 if (vrfEntry.getEncapType() != null && !EncapType.Mplsgre.equals(vrfEntry.getEncapType())) {
212 LOG.debug("is l2vpn address family=> vrfEntry.getEncapType() = " + vrfEntry.getEncapType());
216 if (!showIt && inputPrefixOrSubnet != null) {
217 showIt = FibHelper.isBelongingPrefix(vrfEntry.getDestPrefix(), inputPrefixOrSubnet);
222 List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
223 if (routePaths == null || routePaths.isEmpty()) {
224 console.println(String.format(TABULAR_FORMAT,
225 vrfTable.getRouteDistinguisher(), vrfEntry.getDestPrefix(),
226 "local", routePaths == null ? "<not set>" : "<empty>",
227 vrfEntry.getOrigin()));
230 for (RoutePaths routePath : routePaths) {
231 console.println(String.format(TABULAR_FORMAT,
232 vrfTable.getRouteDistinguisher(), vrfEntry.getDestPrefix(),
233 routePath.getNexthopAddress(), routePath.getLabel(),
234 vrfEntry.getOrigin()));
239 private Object usage(PrintStream console) {
240 String nl = System.getProperty("line.separator");
241 console.println("===================================================");
242 console.println("usage cli =>" + nl);
243 console.println("fib-show --help => to get the current help");
244 console.println("fib-show fullHelp => to get the FULL help" + nl);
245 console.println("fib-show -af ipv4 => to get ipv4 address family");
246 console.println("fib-show -af ipv4 -af ipv6 => to get ipv4 and ipv6 address family");
247 console.println("fib-show -af ipv4 -af ipv6 -af l2vpn => to get ipv4 and ipv6 and l2vpn address family");
248 console.println("---------------------------------------------------");
249 console.println("fib-show -sub 40.1.1.0/24 => to get all IPv4 from fib belonging to this subnet");
250 console.println("fib-show -sub 40.1.1.1/32 => to get the IPv4 from fib");
251 console.println("---------------------------------------------------");
252 console.println("fib-show -sub 2001::1/64 => to get all IPv6 from fib belonging to this subnet");
253 console.println("fib-show -sub 2001::1/128 => to get all IPv6 from fib");
254 console.println("===================================================");