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.implementation.util;
10 import java.util.List;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcaflistaddress.Addresses;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcaftrafficengineeringaddress.Hops;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.Address;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.AS;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.DistinguishedName;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Ipv4;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Ipv6;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafApplicationData;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafKeyValue;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafList;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSegment;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSourceDest;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafTrafficEngineering;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Mac;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.No;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafapplicationdata.LcafApplicationDataAddr;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafkeyvalue.LcafKeyValueAddressAddr;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddr;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispsimpleaddress.PrimitiveAddress;
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(LispAddressContainer container) {
69 return getString(Destination.USER, container);
72 public static String getString(LispAddressContainer container, int mask) {
73 return getString(Destination.USER, container, mask);
76 public static String getURIString(LispAddressContainer container, int mask) {
77 return getString(Destination.URI, container, mask);
80 public static String getURLString(LispAddressContainer container, int mask) {
81 return getString(Destination.URL, container, mask);
84 private static String getString(Destination dst, LispAddressContainer container) {
85 Preconditions.checkNotNull(container, "address should not be null");
86 Address addr = container.getAddress();
88 String address = null;
90 if (addr instanceof Ipv4) {
91 prefix = "ipv4" + PREFIX_SEPARATOR;
92 address = getStringFromIpv4(dst, (Ipv4) addr);
93 } else if (addr instanceof Ipv6) {
94 prefix = "ipv6" + PREFIX_SEPARATOR;
95 address = getStringFromIpv6(dst, (Ipv6) addr);
96 } else if (addr instanceof Mac) {
97 prefix = "mac" + PREFIX_SEPARATOR;
98 address = getStringFromMac(dst, (Mac) addr);
99 } else if (addr instanceof LcafSegment) {
100 PrimitiveAddress pa = ((LcafSegment) addr).getLcafSegmentAddr().getAddress().getPrimitiveAddress();
101 // Instance ID is a separate parent hierarchy, so we use the simple address prefix
102 prefix = LispPrimitiveAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
103 address = getStringFromLcafSegment(dst, (LcafSegment) addr);
104 } else if (addr instanceof No) {
105 prefix = "no" + PREFIX_SEPARATOR;
106 address = getStringFromNo(dst, (No) addr);
107 } else if (addr instanceof DistinguishedName) {
108 prefix = "dn" + PREFIX_SEPARATOR;
109 address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
110 } else if (addr instanceof AS) {
111 prefix = "as" + PREFIX_SEPARATOR;
112 address = getStringFromAS(dst, (AS) addr);
113 } else if (addr instanceof LcafList) {
114 prefix = "list" + PREFIX_SEPARATOR;
115 address = getStringFromLcafList(dst, (LcafList) addr);
116 } else if (addr instanceof LcafApplicationData) {
117 prefix = "appdata" + PREFIX_SEPARATOR;
118 address = getStringFromLcafApplicationData(dst, (LcafApplicationData) addr);
119 } else if (addr instanceof LcafTrafficEngineering) {
120 prefix = "elp" + PREFIX_SEPARATOR;
121 address = getStringFromLcafTrafficEngineering(dst, (LcafTrafficEngineering) addr);
122 } else if (addr instanceof LcafSourceDest) {
123 prefix = "srcdst" + PREFIX_SEPARATOR;
124 address = getStringFromLcafSourceDest(dst, (LcafSourceDest) addr);
125 } else if (addr instanceof LcafKeyValue) {
126 prefix = "kv" + PREFIX_SEPARATOR;
127 address = getStringFromLcafKeyValue(dst, (LcafKeyValue) addr);
130 if (dst == Destination.USER) {
133 return prefix + address;
138 private static String getString(Destination dst, LispAddressContainer container, int mask) {
139 Address addr = container.getAddress();
141 if (isMaskable(addr)) {
142 return (getString(dst, container) + getMaskSeparator(dst) + mask);
144 return getString(dst, container);
148 private static boolean isMaskable(Address addr) {
149 if (addr instanceof Ipv4 || addr instanceof Ipv6 || addr instanceof LcafSegment) {
155 private static String getMaskSeparator(Destination dst) {
156 if (dst == Destination.URL) {
163 protected static String getStringFromNo(Destination dst, No addr) {
165 if (dst == Destination.USER) {
166 return "No Address Present";
168 return "" + noAddrSeq++;
172 protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
174 return addr.getIpv4Address().getIpv4Address().getValue();
177 protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
179 return addr.getIpv6Address().getIpv6Address().getValue();
182 protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
183 // AFI = 17; Distinguished Name
184 return addr.getDistinguishedName().getDistinguishedName();
187 protected static String getStringFromAS(Destination dst, AS addr) {
188 // AFI = 18; Autonomous System Number
189 return "AS" + addr.getAS().getAS();
191 protected static String getStringFromLcafList(Destination dst, LcafList addr) {
192 // AFI 16387, LCAF Type 1; Address List
193 // Example rendering:
194 // {192.0.2.1,192.0.2.2,2001:db8::1}
195 List<Addresses> addresses = addr.getLcafListAddr().getAddresses();
196 StringBuilder sb = new StringBuilder("{");
197 boolean needComma = false;
198 for (Addresses a : addresses) {
202 sb.append(LispPrimitiveAddressStringifier.getString(dst, a.getPrimitiveAddress()));
206 return sb.toString();
209 protected static String getStringFromLcafSegment(Destination dst, LcafSegment addr) {
210 // AFI = 16387, LCAF Type 2; Instance ID
211 // Example rendering:
212 // [223] 192.0.2.0/24
213 PrimitiveAddress pa = addr.getLcafSegmentAddr().getAddress().getPrimitiveAddress();
214 if (dst == Destination.USER) {
215 return "[" + addr.getLcafSegmentAddr().getInstanceId() + "] "
216 + LispPrimitiveAddressStringifier.getString(dst, pa);
218 return LispPrimitiveAddressStringifier.getString(dst, pa);
222 protected static String getStringFromLcafApplicationData(Destination dst, LcafApplicationData addr) {
223 // AFI = 16387, LCAF Type 4; Application Data
224 // Example rendering:
225 // 192.0.2.1!128!17!80-81!6667-7000
226 LcafApplicationDataAddr a = addr.getLcafApplicationDataAddr();
227 return LispPrimitiveAddressStringifier.getString(dst, a.getAddress().getPrimitiveAddress())
228 + "!" + a.getIpTos() + "!" + a.getProtocol()
229 + "!" + a.getLocalPortLow() + "-" + a.getLocalPortHigh()
230 + "!" + a.getRemotePortLow() + "-" + a.getRemotePortHigh();
233 protected static String getStringFromLcafTrafficEngineering(Destination dst, LcafTrafficEngineering addr) {
234 // AFI = 16387, LCAF Type 10, Explicit Locator Path
235 // Example rendering:
236 // {192.0.2.1->192.0.2.2|lps->192.0.2.3}
237 List<Hops> hops = addr.getLcafTrafficEngineeringAddr().getHops();
238 StringBuilder sb = new StringBuilder();
240 boolean needArrow = false;
241 for (Hops hop : hops) {
245 sb.append(LispPrimitiveAddressStringifier.getString(dst, hop.getHop().getPrimitiveAddress()));
246 if (hop.isLookup() || hop.isRLOCProbe() || hop.isStrict()) {
249 if (hop.isLookup()) {
252 if (hop.isRLOCProbe()) {
255 if (hop.isStrict()) {
261 return sb.toString();
264 protected static String getStringFromLcafSourceDest(Destination dst, LcafSourceDest addr) {
265 // AFI = 16387, LCAF Type 12, Source/Destination Key
266 // Example rendering:
267 // 192.0.2.1/32|192.0.2.2/32
268 LcafSourceDestAddr a = ((LcafSourceDest) addr).getLcafSourceDestAddr();
269 return LispPrimitiveAddressStringifier.getString(dst, a.getSrcAddress().getPrimitiveAddress())
270 + getMaskSeparator(dst) + a.getSrcMaskLength() + "|"
271 + LispPrimitiveAddressStringifier.getString(dst, a.getDstAddress().getPrimitiveAddress())
272 + getMaskSeparator(dst) + a.getDstMaskLength();
275 protected static String getStringFromLcafKeyValue(Destination dst, LcafKeyValue addr) {
276 // AFI = 16387, LCAF Type 15, Key/Value Address Pair
277 // Example rendering:
278 // 192.0.2.1=>192.0.2.2
279 LcafKeyValueAddressAddr a = addr.getLcafKeyValueAddressAddr();
280 return LispPrimitiveAddressStringifier.getString(dst, a.getKey().getPrimitiveAddress()) + "=>"
281 + LispPrimitiveAddressStringifier.getString(dst, a.getValue().getPrimitiveAddress());
284 protected static String getStringFromMac(Destination dst, Mac addr) {
286 return addr.getMacAddress().getMacAddress().getValue();