View Javadoc

1   /*
2    * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
3    *
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
7    */
8   package org.opendaylight.lispflowmapping.lisp.util;
9   
10  import java.util.List;
11  
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;
32  
33  import com.google.common.base.Preconditions;
34  
35  /**
36   * Utility class with static methods returning string representations of
37   * supported LISP address types, both for use in URLs and for user friendly
38   * output.
39   *
40   * @author Lorand Jakab
41   *
42   */
43  public class LispAddressStringifier {
44  
45      private static final String PREFIX_SEPARATOR = ":";
46      /*
47       * In the unlikely event that a AFI 0 address is used a key, we use a
48       * sequence number to ensure uniqueness
49       */
50      protected static int noAddrSeq = 0;
51      /*
52       * There are three possible destinations for rendering an address as a
53       * string:
54       *
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
60       *     encoded as '%2f'
61       */
62      protected enum Destination {
63          USER,
64          URI,
65          URL;
66      }
67  
68      public static String getString(LispAddress lispAddress) {
69          return getAddrString(Destination.USER, lispAddress);
70      }
71  
72      public static String getURIString(LispAddress lispAddress) {
73          return getAddrString(Destination.URI, lispAddress);
74      }
75  
76      public static String getURLString(LispAddress lispAddress) {
77          return getAddrString(Destination.URL, lispAddress);
78      }
79  
80      private static String getAddrString(Destination dst, LispAddress lispAddress) {
81          Preconditions.checkNotNull(lispAddress, "lispAddress should not be null");
82          Address addr = lispAddress.getAddress();
83          String prefix = "";
84          String vni = "";
85          String address = "";
86  
87          if (lispAddress.getVirtualNetworkId() != null) {
88              vni = "[" + lispAddress.getVirtualNetworkId().getValue() + "] ";
89          }
90  
91          if (addr instanceof Ipv4) {
92              prefix = "ipv4" + PREFIX_SEPARATOR;
93              address = getStringFromIpv4(dst, (Ipv4) addr);
94          } else if (addr instanceof Ipv4Prefix) {
95              prefix = "ipv4" + PREFIX_SEPARATOR;
96              address = getStringFromIpv4Prefix(dst, (Ipv4Prefix) addr);
97          } else if (addr instanceof Ipv6) {
98              prefix = "ipv6" + PREFIX_SEPARATOR;
99              address = getStringFromIpv6(dst, (Ipv6) addr);
100         } else if (addr instanceof Ipv6Prefix) {
101             prefix = "ipv6" + PREFIX_SEPARATOR;
102             address = getStringFromIpv6Prefix(dst, (Ipv6Prefix) addr);
103         } else if (addr instanceof Mac) {
104             prefix = "mac" + PREFIX_SEPARATOR;
105             address = getStringFromMac(dst, (Mac) addr);
106         } else if (addr instanceof InstanceId) {
107             SimpleAddress pa = ((InstanceId)addr).getInstanceId().getAddress();
108             // Instance ID is a separate parent hierarchy, so we use the simple address prefix
109             prefix = LispSimpleAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
110             address = getStringFromInstanceId(dst, (InstanceId) addr);
111         } else if (addr instanceof NoAddress) {
112             prefix = "no" + PREFIX_SEPARATOR;
113             address = getStringFromNoAddress(dst, (NoAddress) addr);
114         } else if (addr instanceof DistinguishedName) {
115             prefix = "dn" + PREFIX_SEPARATOR;
116             address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
117         } else if (addr instanceof AsNumber) {
118             prefix = "as" + PREFIX_SEPARATOR;
119             address = getStringFromAsNumber(dst, (AsNumber) addr);
120         } else if (addr instanceof AfiList) {
121             prefix = "list" + PREFIX_SEPARATOR;
122             address = getStringFromAfiList(dst, (AfiList) addr);
123         } else if (addr instanceof ApplicationData) {
124             prefix = "appdata" + PREFIX_SEPARATOR;
125             address = getStringFromApplicationData(dst, (ApplicationData) addr);
126         } else if (addr instanceof ExplicitLocatorPath) {
127             prefix = "elp" + PREFIX_SEPARATOR;
128             address = getStringFromExplicitLocatorPath(dst, (ExplicitLocatorPath) addr);
129         } else if (addr instanceof SourceDestKey) {
130             prefix = "srcdst" + PREFIX_SEPARATOR;
131             address = getStringFromSourceDestKey(dst, (SourceDestKey) addr);
132         } else if (addr instanceof KeyValueAddress) {
133             prefix = "kv" + PREFIX_SEPARATOR;
134             address = getStringFromKeyValueAddress(dst, (KeyValueAddress) addr);
135         } else if (addr instanceof ServicePath) {
136             prefix = "sp" + PREFIX_SEPARATOR;
137             address = getStringFromServicePath(dst, (ServicePath) addr);
138         } else {
139             return null;
140         }
141 
142         if (dst == Destination.USER) {
143             return vni + address;
144         } else {
145             return prefix + address;
146         }
147 
148     }
149 
150     private static String getPrefixString(Destination dst, String prefix) {
151         if (dst == Destination.URL) {
152             return prefix.replace("/", "%2f");
153         } else {
154             return prefix;
155         }
156     }
157 
158     protected static String getStringFromNoAddress(Destination dst, NoAddress addr) {
159         // AFI = 0
160         if (dst == Destination.USER) {
161             return "No Address Present";
162         } else {
163             return "" + noAddrSeq++;
164         }
165     }
166 
167     protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
168         // AFI = 1; IPv4
169         return addr.getIpv4().getValue();
170     }
171 
172     protected static String getStringFromIpv4Prefix(Destination dst, Ipv4Prefix addr) {
173         // AFI = 1; IPv4
174         String prefix = addr.getIpv4Prefix().getValue();
175         return getPrefixString(dst, prefix);
176     }
177 
178     protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
179         // AFI = 2; IPv6
180         return addr.getIpv6().getValue();
181     }
182 
183     protected static String getStringFromIpv6Prefix(Destination dst, Ipv6Prefix addr) {
184         // AFI = 2; IPv6
185         return addr.getIpv6Prefix().getValue();
186     }
187 
188     protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
189         // AFI = 17; Distinguished Name
190         return addr.getDistinguishedName().getValue();
191     }
192 
193     protected static String getStringFromAsNumber(Destination dst, AsNumber addr) {
194         // AFI = 18; Autonomous System Number
195         return "AS" + addr.getAsNumber().getValue();
196     }
197     protected static String getStringFromAfiList(Destination dst, AfiList addr) {
198         // AFI 16387, LCAF Type 1; Address List
199         // Example rendering:
200         //    {192.0.2.1,192.0.2.2,2001:db8::1}
201         List<SimpleAddress> addresses = addr.getAfiList().getAddressList();
202         StringBuilder sb = new StringBuilder("{");
203         boolean needComma = false;
204         for (SimpleAddress a : addresses) {
205             if (needComma) {
206                 sb.append(",");
207             }
208             sb.append(a.getValue());
209             needComma = true;
210         }
211         sb.append("}");
212         return sb.toString();
213     }
214 
215     protected static String getStringFromInstanceId(Destination dst, InstanceId addr) {
216         // AFI = 16387, LCAF Type 2; Instance ID
217         // Example rendering:
218         //    [223] 192.0.2.0/24
219         SimpleAddress pa = addr.getInstanceId().getAddress();
220         if (dst == Destination.USER) {
221             return "[" + addr.getInstanceId().getIid().getValue() + "] "
222                     + LispSimpleAddressStringifier.getString(dst, pa);
223         } else {
224             return LispSimpleAddressStringifier.getString(dst, pa);
225         }
226     }
227 
228     protected static String getStringFromApplicationData(Destination dst, ApplicationData addr) {
229         // AFI = 16387, LCAF Type 4; Application Data
230         // Example rendering:
231         //    192.0.2.1!128!17!80-81!6667-7000
232         return LispSimpleAddressStringifier.getString(dst, addr.getApplicationData().getAddress())
233                 + "!" + addr.getApplicationData().getIpTos()
234                 + "!" + addr.getApplicationData().getProtocol()
235                 + "!" + addr.getApplicationData().getLocalPortLow()
236                 + "-" + addr.getApplicationData().getLocalPortHigh()
237                 + "!" + addr.getApplicationData().getRemotePortLow()
238                 + "-" + addr.getApplicationData().getRemotePortHigh();
239     }
240 
241     protected static String getStringFromExplicitLocatorPath(Destination dst, ExplicitLocatorPath addr) {
242         // AFI = 16387, LCAF Type 10, Explicit Locator Path
243         // Example rendering:
244         //    {192.0.2.1->192.0.2.2|lps->192.0.2.3}
245         List<Hop> hops = addr.getExplicitLocatorPath().getHop();
246         StringBuilder sb = new StringBuilder();
247         sb.append("{");
248         boolean needArrow = false;
249         for (Hop hop : hops) {
250             if (needArrow) {
251                 sb.append("->");
252             }
253             sb.append(LispSimpleAddressStringifier.getString(dst, hop.getAddress()));
254             LrsBits lrs = hop.getLrsBits();
255             if (lrs.isLookup() || lrs.isRlocProbe() || lrs.isStrict()) {
256                 sb.append("|");
257             }
258             if (lrs.isLookup()) {
259                 sb.append("l");
260             }
261             if (lrs.isRlocProbe()) {
262                 sb.append("p");
263             }
264             if (lrs.isStrict()) {
265                 sb.append("s");
266             }
267             needArrow = true;
268         }
269         sb.append("}");
270         return sb.toString();
271     }
272 
273     protected static String getStringFromSourceDestKey(Destination dst, SourceDestKey addr) {
274         // AFI = 16387, LCAF Type 12, Source/Destination Key
275         // Example rendering:
276         //    192.0.2.1/32|192.0.2.2/32
277         return getPrefixString(dst, (new String(addr.getSourceDestKey().getSource().getValue()))
278                 + "|" + getPrefixString(dst, new String(addr.getSourceDestKey().getDest().getValue())));
279     }
280 
281     protected static String getStringFromKeyValueAddress(Destination dst, KeyValueAddress addr) {
282         // AFI = 16387, LCAF Type 15, Key/Value Address Pair
283         // Example rendering:
284         //    192.0.2.1=>192.0.2.2
285         return getPrefixString(dst, new String(addr.getKeyValueAddress().getKey().getValue())
286                 + "=>" + getPrefixString(dst, new String(addr.getKeyValueAddress().getValue().getValue())));
287     }
288 
289     protected static String getStringFromMac(Destination dst, Mac addr) {
290         // AFI = 16389; MAC
291         return addr.getMac().getValue();
292     }
293 
294     protected static String getStringFromServicePath(Destination dst, ServicePath addr) {
295         // AFI = 16387; LCAF http://tools.ietf.org/html/draft-ermagan-lisp-nsh-00
296         // Example rendering:
297         //     42(3)
298         return getPrefixString(dst, new String(addr.getServicePath().getServicePathId().getValue() + "("
299                 + addr.getServicePath().getServiceIndex() + ")"));
300     }
301 
302 }