2 * Copyright (c) 2015 Cisco Systems, Inc. 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
8 package org.opendaylight.lispflowmapping.lisp.util;
10 import java.util.List;
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AfiList;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ApplicationData;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AsNumber;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.DistinguishedName;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ExplicitLocatorPath;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.KeyValueAddress;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Mac;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.NoAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.Hop;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.Hop.LrsBits;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ServicePath;
33 import com.google.common.base.Preconditions;
36 * Utility class with static methods returning string representations of
37 * supported LISP address types, both for use in URLs and for user friendly
40 * @author Lorand Jakab
43 public class LispAddressStringifier {
45 private static final String PREFIX_SEPARATOR = ":";
47 * In the unlikely event that a AFI 0 address is used a key, we use a
48 * sequence number to ensure uniqueness
50 protected static int noAddrSeq = 0;
52 * There are three possible destinations for rendering an address as a
55 * * General user interaction, like log and CLI output, GUI
56 * representation, etc.
57 * * As a URI string that is the entry key in the MD-SAL datastore
58 * * As a URL string that is the same as the URI string, except for
59 * characters not accepted in URLs are percent encoded (e.g. '/' is
62 protected enum Destination {
68 public static String getString(LispAddress lispAddress) {
69 return getAddrString(Destination.USER, lispAddress);
72 public static String getURIString(LispAddress lispAddress) {
73 return getAddrString(Destination.URI, lispAddress);
76 public static String getURLString(LispAddress lispAddress) {
77 return getAddrString(Destination.URL, lispAddress);
80 private static String getAddrString(Destination dst, LispAddress lispAddress) {
81 Preconditions.checkNotNull(lispAddress, "lispAddress should not be null");
82 Address addr = lispAddress.getAddress();
86 if (lispAddress.getVirtualNetworkId() != null) {
87 address = "[" + lispAddress.getVirtualNetworkId().getValue() + "] ";
90 if (addr instanceof Ipv4) {
91 prefix = "ipv4" + PREFIX_SEPARATOR;
92 address += getStringFromIpv4(dst, (Ipv4) addr);
93 } else if (addr instanceof Ipv4Prefix) {
94 prefix = "ipv4" + PREFIX_SEPARATOR;
95 address += getStringFromIpv4Prefix(dst, (Ipv4Prefix) addr);
96 } else if (addr instanceof Ipv6) {
97 prefix = "ipv6" + PREFIX_SEPARATOR;
98 address += getStringFromIpv6(dst, (Ipv6) addr);
99 } else if (addr instanceof Ipv6Prefix) {
100 prefix = "ipv6" + PREFIX_SEPARATOR;
101 address += getStringFromIpv6Prefix(dst, (Ipv6Prefix) addr);
102 } else if (addr instanceof Mac) {
103 prefix = "mac" + PREFIX_SEPARATOR;
104 address += getStringFromMac(dst, (Mac) addr);
105 } else if (addr instanceof InstanceId) {
106 SimpleAddress pa = ((InstanceId)addr).getInstanceId().getAddress();
107 // Instance ID is a separate parent hierarchy, so we use the simple address prefix
108 prefix = LispSimpleAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
109 address += getStringFromInstanceId(dst, (InstanceId) addr);
110 } else if (addr instanceof NoAddress) {
111 prefix = "no" + PREFIX_SEPARATOR;
112 address += getStringFromNoAddress(dst, (NoAddress) addr);
113 } else if (addr instanceof DistinguishedName) {
114 prefix = "dn" + PREFIX_SEPARATOR;
115 address += getStringFromDistinguishedName(dst, (DistinguishedName) addr);
116 } else if (addr instanceof AsNumber) {
117 prefix = "as" + PREFIX_SEPARATOR;
118 address += getStringFromAsNumber(dst, (AsNumber) addr);
119 } else if (addr instanceof AfiList) {
120 prefix = "list" + PREFIX_SEPARATOR;
121 address += getStringFromAfiList(dst, (AfiList) addr);
122 } else if (addr instanceof ApplicationData) {
123 prefix = "appdata" + PREFIX_SEPARATOR;
124 address += getStringFromApplicationData(dst, (ApplicationData) addr);
125 } else if (addr instanceof ExplicitLocatorPath) {
126 prefix = "elp" + PREFIX_SEPARATOR;
127 address += getStringFromExplicitLocatorPath(dst, (ExplicitLocatorPath) addr);
128 } else if (addr instanceof SourceDestKey) {
129 prefix = "srcdst" + PREFIX_SEPARATOR;
130 address += getStringFromSourceDestKey(dst, (SourceDestKey) addr);
131 } else if (addr instanceof KeyValueAddress) {
132 prefix = "kv" + PREFIX_SEPARATOR;
133 address += getStringFromKeyValueAddress(dst, (KeyValueAddress) addr);
134 } else if (addr instanceof ServicePath) {
135 prefix = "sp" + PREFIX_SEPARATOR;
136 address += getStringFromServicePath(dst, (ServicePath) addr);
141 if (dst == Destination.USER) {
144 return prefix + address;
149 private static String getPrefixString(Destination dst, String prefix) {
150 if (dst == Destination.URL) {
151 return prefix.replace("/", "%2f");
157 protected static String getStringFromNoAddress(Destination dst, NoAddress addr) {
159 if (dst == Destination.USER) {
160 return "No Address Present";
162 return "" + noAddrSeq++;
166 protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
168 return addr.getIpv4().getValue();
171 protected static String getStringFromIpv4Prefix(Destination dst, Ipv4Prefix addr) {
173 String prefix = addr.getIpv4Prefix().getValue();
174 return getPrefixString(dst, prefix);
177 protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
179 return addr.getIpv6().getValue();
182 protected static String getStringFromIpv6Prefix(Destination dst, Ipv6Prefix addr) {
184 return addr.getIpv6Prefix().getValue();
187 protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
188 // AFI = 17; Distinguished Name
189 return addr.getDistinguishedName().getValue();
192 protected static String getStringFromAsNumber(Destination dst, AsNumber addr) {
193 // AFI = 18; Autonomous System Number
194 return "AS" + addr.getAsNumber().getValue();
196 protected static String getStringFromAfiList(Destination dst, AfiList addr) {
197 // AFI 16387, LCAF Type 1; Address List
198 // Example rendering:
199 // {192.0.2.1,192.0.2.2,2001:db8::1}
200 List<SimpleAddress> addresses = addr.getAfiList().getAddressList();
201 StringBuilder sb = new StringBuilder("{");
202 boolean needComma = false;
203 for (SimpleAddress a : addresses) {
207 sb.append(a.getValue());
211 return sb.toString();
214 protected static String getStringFromInstanceId(Destination dst, InstanceId addr) {
215 // AFI = 16387, LCAF Type 2; Instance ID
216 // Example rendering:
217 // [223] 192.0.2.0/24
218 SimpleAddress pa = addr.getInstanceId().getAddress();
219 if (dst == Destination.USER) {
220 return "[" + addr.getInstanceId().getIid().getValue() + "] "
221 + LispSimpleAddressStringifier.getString(dst, pa);
223 return LispSimpleAddressStringifier.getString(dst, pa);
227 protected static String getStringFromApplicationData(Destination dst, ApplicationData addr) {
228 // AFI = 16387, LCAF Type 4; Application Data
229 // Example rendering:
230 // 192.0.2.1!128!17!80-81!6667-7000
231 return LispSimpleAddressStringifier.getString(dst, addr.getApplicationData().getAddress())
232 + "!" + addr.getApplicationData().getIpTos()
233 + "!" + addr.getApplicationData().getProtocol()
234 + "!" + addr.getApplicationData().getLocalPortLow()
235 + "-" + addr.getApplicationData().getLocalPortHigh()
236 + "!" + addr.getApplicationData().getRemotePortLow()
237 + "-" + addr.getApplicationData().getRemotePortHigh();
240 protected static String getStringFromExplicitLocatorPath(Destination dst, ExplicitLocatorPath addr) {
241 // AFI = 16387, LCAF Type 10, Explicit Locator Path
242 // Example rendering:
243 // {192.0.2.1->192.0.2.2|lps->192.0.2.3}
244 List<Hop> hops = addr.getExplicitLocatorPath().getHop();
245 StringBuilder sb = new StringBuilder();
247 boolean needArrow = false;
248 for (Hop hop : hops) {
252 sb.append(LispSimpleAddressStringifier.getString(dst, hop.getAddress()));
253 LrsBits lrs = hop.getLrsBits();
254 if (lrs.isLookup() || lrs.isRlocProbe() || lrs.isStrict()) {
257 if (lrs.isLookup()) {
260 if (lrs.isRlocProbe()) {
263 if (lrs.isStrict()) {
269 return sb.toString();
272 protected static String getStringFromSourceDestKey(Destination dst, SourceDestKey addr) {
273 // AFI = 16387, LCAF Type 12, Source/Destination Key
274 // Example rendering:
275 // 192.0.2.1/32|192.0.2.2/32
276 return getPrefixString(dst, (new String(addr.getSourceDestKey().getSource().getValue()))
277 + "|" + getPrefixString(dst, new String(addr.getSourceDestKey().getDest().getValue())));
280 protected static String getStringFromKeyValueAddress(Destination dst, KeyValueAddress addr) {
281 // AFI = 16387, LCAF Type 15, Key/Value Address Pair
282 // Example rendering:
283 // 192.0.2.1=>192.0.2.2
284 return getPrefixString(dst, new String(addr.getKeyValueAddress().getKey().getValue())
285 + "=>" + getPrefixString(dst, new String(addr.getKeyValueAddress().getValue().getValue())));
288 protected static String getStringFromMac(Destination dst, Mac addr) {
290 return addr.getMac().getValue();
293 protected static String getStringFromServicePath(Destination dst, ServicePath addr) {
294 // AFI = 16387; LCAF http://tools.ietf.org/html/draft-ermagan-lisp-nsh-00
295 // Example rendering:
297 return getPrefixString(dst, new String(addr.getServicePath().getServicePathId().getValue() + "("
298 + addr.getServicePath().getServiceIndex() + ")"));