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 com.google.common.io.BaseEncoding;
11 import com.google.common.net.InetAddresses;
12 import java.net.Inet4Address;
13 import java.net.Inet6Address;
14 import java.net.UnknownHostException;
15 import java.util.List;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AfiList;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ApplicationData;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AsNumber;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.DistinguishedName;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ExplicitLocatorPath;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.KeyValueAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Mac;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.NoAddress;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ServicePath;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
35 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;
36 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;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4Binary;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4PrefixBinary;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv6Binary;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv6PrefixBinary;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Utility class with static methods returning string representations of
48 * supported LISP address types, both for use in URLs and for user friendly
51 * @author Lorand Jakab
54 public final class LispAddressStringifier {
55 protected static final Logger LOG = LoggerFactory.getLogger(LispAddressStringifier.class);
57 private static final String PREFIX_SEPARATOR = ":";
60 * In the unlikely event that a AFI 0 address is used a key, we use a
61 * sequence number to ensure uniqueness
63 protected static int noAddrSeq = 0;
66 * There are three possible destinations for rendering an address as a
69 * * General user interaction, like log and CLI output, GUI
70 * representation, etc.
71 * * As a URI string that is the entry key in the MD-SAL datastore
72 * * As a URL string that is the same as the URI string, except for
73 * characters not accepted in URLs are percent encoded (e.g. '/' is
76 protected enum Destination {
82 // Utility class, should not be instantiated
83 private LispAddressStringifier() {
86 public static String getString(LispAddress lispAddress) {
87 return getAddrString(Destination.USER, lispAddress);
90 public static String getString(Set<Eid> eids) {
91 StringBuilder sb = new StringBuilder("{");
93 for (Eid eid : eids) {
97 sb.append(getString(eid));
101 return sb.toString();
104 public static String getString(Address address) {
105 return getAddrString(Destination.USER, address, null);
108 public static String getString(XtrId xtrId) {
109 return getXtrIdString(xtrId);
112 public static String getURIString(LispAddress lispAddress) {
113 return getAddrString(Destination.URI, lispAddress);
116 public static String getURIString(XtrId xtrId) {
117 return getXtrIdString(xtrId);
120 public static String getURLString(LispAddress lispAddress) {
121 return getAddrString(Destination.URL, lispAddress);
124 public static String getURLString(XtrId xtrId) {
125 return getXtrIdString(xtrId);
128 private static String getXtrIdString(XtrId xtrId) {
129 return BaseEncoding.base16().encode(xtrId.getValue());
132 private static String getAddrString(Destination dst, LispAddress lispAddress) {
133 if (lispAddress == null) {
137 Address addr = lispAddress.getAddress();
140 if (lispAddress.getVirtualNetworkId() != null) {
141 vni = lispAddress.getVirtualNetworkId().getValue();
144 return getAddrString(dst, addr, vni);
147 private static String getAddrString(Destination dst, Address addr, Long virtualNetworkId) {
152 if (virtualNetworkId != null) {
153 vni = "[" + virtualNetworkId + "] ";
156 if (addr instanceof Ipv4) {
157 prefix = "ipv4" + PREFIX_SEPARATOR;
158 address = getStringFromIpv4(dst, (Ipv4) addr);
159 } else if (addr instanceof Ipv4Binary) {
160 prefix = "ipv4" + PREFIX_SEPARATOR;
161 address = getStringFromIpv4Binary(dst, (Ipv4Binary) addr);
162 } else if (addr instanceof Ipv4Prefix) {
163 prefix = "ipv4" + PREFIX_SEPARATOR;
164 address = getStringFromIpv4Prefix(dst, (Ipv4Prefix) addr);
165 } else if (addr instanceof Ipv4PrefixBinary) {
166 prefix = "ipv4" + PREFIX_SEPARATOR;
167 address = getStringFromIpv4PrefixBinary(dst, (Ipv4PrefixBinary) addr);
168 } else if (addr instanceof Ipv6) {
169 prefix = "ipv6" + PREFIX_SEPARATOR;
170 address = getStringFromIpv6(dst, (Ipv6) addr);
171 } else if (addr instanceof Ipv6Binary) {
172 prefix = "ipv6" + PREFIX_SEPARATOR;
173 address = getStringFromIpv6Binary(dst, (Ipv6Binary) addr);
174 } else if (addr instanceof Ipv6Prefix) {
175 prefix = "ipv6" + PREFIX_SEPARATOR;
176 address = getStringFromIpv6Prefix(dst, (Ipv6Prefix) addr);
177 } else if (addr instanceof Ipv6PrefixBinary) {
178 prefix = "ipv6" + PREFIX_SEPARATOR;
179 address = getStringFromIpv6PrefixBinary(dst, (Ipv6PrefixBinary) addr);
180 } else if (addr instanceof Mac) {
181 prefix = "mac" + PREFIX_SEPARATOR;
182 address = getStringFromMac(dst, (Mac) addr);
183 } else if (addr instanceof InstanceId) {
184 SimpleAddress pa = ((InstanceId)addr).getInstanceId().getAddress();
185 // Instance ID is a separate parent hierarchy, so we use the simple address prefix
186 prefix = LispSimpleAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
187 address = getStringFromInstanceId(dst, (InstanceId) addr);
188 } else if (addr instanceof NoAddress) {
189 prefix = "no" + PREFIX_SEPARATOR;
190 address = getStringFromNoAddress(dst, (NoAddress) addr);
191 } else if (addr instanceof DistinguishedName) {
192 prefix = "dn" + PREFIX_SEPARATOR;
193 address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
194 } else if (addr instanceof AsNumber) {
195 prefix = "as" + PREFIX_SEPARATOR;
196 address = getStringFromAsNumber(dst, (AsNumber) addr);
197 } else if (addr instanceof AfiList) {
198 prefix = "list" + PREFIX_SEPARATOR;
199 address = getStringFromAfiList(dst, (AfiList) addr);
200 } else if (addr instanceof ApplicationData) {
201 prefix = "appdata" + PREFIX_SEPARATOR;
202 address = getStringFromApplicationData(dst, (ApplicationData) addr);
203 } else if (addr instanceof ExplicitLocatorPath) {
204 prefix = "elp" + PREFIX_SEPARATOR;
205 address = getStringFromExplicitLocatorPath(dst, (ExplicitLocatorPath) addr);
206 } else if (addr instanceof SourceDestKey) {
207 prefix = "srcdst" + PREFIX_SEPARATOR;
208 address = getStringFromSourceDestKey(dst, (SourceDestKey) addr);
209 } else if (addr instanceof KeyValueAddress) {
210 prefix = "kv" + PREFIX_SEPARATOR;
211 address = getStringFromKeyValueAddress(dst, (KeyValueAddress) addr);
212 } else if (addr instanceof ServicePath) {
213 prefix = "sp" + PREFIX_SEPARATOR;
214 address = getStringFromServicePath(dst, (ServicePath) addr);
219 if (dst == Destination.USER) {
220 return vni + address;
222 return prefix + address;
227 private static String getPrefixString(Destination dst, String prefix) {
228 if (dst == Destination.URL) {
229 return prefix.replace("/", "%2f");
235 protected static String getStringFromNoAddress(Destination dst, NoAddress addr) {
237 if (dst == Destination.USER) {
238 return "No Address Present";
240 return "" + noAddrSeq++;
244 protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
246 return addr.getIpv4().getValue();
249 protected static String getStringFromIpv4Binary(Destination dst, Ipv4Binary addr) {
252 return InetAddresses.toAddrString(Inet4Address.getByAddress(addr.getIpv4Binary().getValue()));
253 } catch (UnknownHostException e) {
254 LOG.debug("Cannot convert binary IPv4 to string", e);
259 protected static String getStringFromIpv4Prefix(Destination dst, Ipv4Prefix addr) {
261 String prefix = addr.getIpv4Prefix().getValue();
262 return getPrefixString(dst, prefix);
265 protected static String getStringFromIpv4PrefixBinary(Destination dst, Ipv4PrefixBinary addr) {
268 StringBuilder prefixBuilder = new StringBuilder(InetAddresses.toAddrString(
269 Inet4Address.getByAddress(addr.getIpv4AddressBinary().getValue())));
270 prefixBuilder.append('/');
271 prefixBuilder.append(addr.getIpv4MaskLength().toString());
272 return getPrefixString(dst, prefixBuilder.toString());
273 } catch (UnknownHostException e) {
274 LOG.debug("Cannot convert binary IPv4 prefix to string", e);
279 protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
281 return addr.getIpv6().getValue();
284 protected static String getStringFromIpv6Binary(Destination dst, Ipv6Binary addr) {
287 return InetAddresses.toAddrString(Inet6Address.getByAddress(addr.getIpv6Binary().getValue()));
288 } catch (UnknownHostException e) {
289 LOG.debug("Cannot convert binary IPv6 to string", e);
294 protected static String getStringFromIpv6Prefix(Destination dst, Ipv6Prefix addr) {
296 return addr.getIpv6Prefix().getValue();
299 protected static String getStringFromIpv6PrefixBinary(Destination dst, Ipv6PrefixBinary addr) {
302 StringBuilder prefixBuilder = new StringBuilder(InetAddresses.toAddrString(
303 Inet6Address.getByAddress(addr.getIpv6AddressBinary().getValue())));
304 prefixBuilder.append('/');
305 prefixBuilder.append(addr.getIpv6MaskLength().toString());
306 return getPrefixString(dst, prefixBuilder.toString());
307 } catch (UnknownHostException e) {
308 LOG.debug("Cannot convert binary IPv6 prefix to string", e);
313 protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
314 // AFI = 17; Distinguished Name
315 return addr.getDistinguishedName().getValue();
318 protected static String getStringFromAsNumber(Destination dst, AsNumber addr) {
319 // AFI = 18; Autonomous System Number
320 return "AS" + addr.getAsNumber().getValue();
323 protected static String getStringFromAfiList(Destination dst, AfiList addr) {
324 // AFI 16387, LCAF Type 1; Address List
325 // Example rendering:
326 // {192.0.2.1,192.0.2.2,2001:db8::1}
327 List<SimpleAddress> addresses = addr.getAfiList().getAddressList();
328 StringBuilder sb = new StringBuilder("{");
329 boolean needComma = false;
330 for (SimpleAddress a : addresses) {
334 sb.append(a.stringValue());
338 return sb.toString();
341 protected static String getStringFromInstanceId(Destination dst, InstanceId addr) {
342 // AFI = 16387, LCAF Type 2; Instance ID
343 // Example rendering:
344 // [223] 192.0.2.0/24
345 SimpleAddress pa = addr.getInstanceId().getAddress();
346 if (dst == Destination.USER) {
347 return "[" + addr.getInstanceId().getIid().getValue() + "] "
348 + LispSimpleAddressStringifier.getString(dst, pa);
350 return LispSimpleAddressStringifier.getString(dst, pa);
354 protected static String getStringFromApplicationData(Destination dst, ApplicationData addr) {
355 // AFI = 16387, LCAF Type 4; Application Data
356 // Example rendering:
357 // 192.0.2.1!128!17!80-81!6667-7000
358 return LispSimpleAddressStringifier.getString(dst, addr.getApplicationData().getAddress())
359 + "!" + addr.getApplicationData().getIpTos()
360 + "!" + addr.getApplicationData().getProtocol()
361 + "!" + addr.getApplicationData().getLocalPortLow()
362 + "-" + addr.getApplicationData().getLocalPortHigh()
363 + "!" + addr.getApplicationData().getRemotePortLow()
364 + "-" + addr.getApplicationData().getRemotePortHigh();
367 protected static String getStringFromExplicitLocatorPath(Destination dst, ExplicitLocatorPath addr) {
368 // AFI = 16387, LCAF Type 10, Explicit Locator Path
369 // Example rendering:
370 // {192.0.2.1->192.0.2.2|lps->192.0.2.3}
371 List<Hop> hops = addr.getExplicitLocatorPath().getHop();
372 StringBuilder sb = new StringBuilder();
374 boolean needArrow = false;
375 for (Hop hop : hops) {
379 sb.append(LispSimpleAddressStringifier.getString(dst, hop.getAddress()));
380 LrsBits lrs = hop.getLrsBits();
381 if (lrs.isLookup() || lrs.isRlocProbe() || lrs.isStrict()) {
384 if (lrs.isLookup()) {
387 if (lrs.isRlocProbe()) {
390 if (lrs.isStrict()) {
396 return sb.toString();
399 protected static String getStringFromSourceDestKey(Destination dst, SourceDestKey addr) {
400 // AFI = 16387, LCAF Type 12, Source/Destination Key
401 // Example rendering:
402 // 192.0.2.1/32|192.0.2.2/32
403 return getPrefixString(dst, addr.getSourceDestKey().getSource().stringValue()
404 + "|" + getPrefixString(dst, addr.getSourceDestKey().getDest().stringValue()));
407 protected static String getStringFromKeyValueAddress(Destination dst, KeyValueAddress addr) {
408 // AFI = 16387, LCAF Type 15, Key/Value Address Pair
409 // Example rendering:
410 // 192.0.2.1=>192.0.2.2
411 return getPrefixString(dst, addr.getKeyValueAddress().getKey().stringValue()
412 + "=>" + getPrefixString(dst, addr.getKeyValueAddress().getValue().stringValue()));
415 protected static String getStringFromMac(Destination dst, Mac addr) {
417 return addr.getMac().getValue();
420 protected static String getStringFromServicePath(Destination dst, ServicePath addr) {
421 // AFI = 16387; LCAF http://tools.ietf.org/html/draft-ermagan-lisp-nsh-00
422 // Example rendering:
424 return getPrefixString(dst, new String(addr.getServicePath().getServicePathId().getValue() + "("
425 + addr.getServicePath().getServiceIndex() + ")"));