2 * Copyright (c) 2014 Contextream, Inc. 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
8 package org.opendaylight.lispflowmapping.lisp.util;
10 import java.net.Inet4Address;
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.nio.ByteBuffer;
16 import org.apache.commons.lang3.exception.ExceptionUtils;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LcafSegmentAddress;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LcafSourceDestAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LispAFIAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LispIpv4Address;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LispIpv6Address;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsegmentaddress.AddressBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsegmentaddress.Address;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsourcedestaddress.DstAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsourcedestaddress.DstAddressBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsourcedestaddress.SrcAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lcafsourcedestaddress.SrcAddressBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.LispAddressContainer;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.LispAddressContainerBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.Ipv4;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.Ipv4Builder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.Ipv6;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.Ipv6Builder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.LcafSegment;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.LcafSegmentBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.LcafSourceDest;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.LcafSourceDestBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.ipv4.Ipv4AddressBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.ipv6.Ipv6Address;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.ipv6.Ipv6AddressBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddr;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddrBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddr;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddrBuilder;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 public class MaskUtil {
50 private static final Logger LOG = LoggerFactory.getLogger(MaskUtil.class);
51 public static boolean isMaskable(LispAFIAddress address) {
52 if (address instanceof Ipv4Address || address instanceof Ipv6Address || address instanceof LcafSegmentAddr) {
58 public static boolean isMaskable(LispAddressContainer address) {
59 if (address.getAddress() instanceof Ipv4 || address.getAddress() instanceof Ipv6) {
61 } else if (address.getAddress() instanceof LcafSegment) {
62 return isMaskable(LispAFIConvertor.toAFIfromPrimitive(((LcafSegment) address.getAddress())
63 .getLcafSegmentAddr().getAddress().getPrimitiveAddress()));
64 } else if (address.getAddress() instanceof LcafSourceDestAddress) {
65 LcafSourceDestAddr sd = ((LcafSourceDest) address.getAddress()).getLcafSourceDestAddr();
66 return isMaskable(LispAFIConvertor.toAFIfromPrimitive(sd.getSrcAddress().getPrimitiveAddress()))
67 && isMaskable(LispAFIConvertor.toAFIfromPrimitive(sd.getDstAddress().getPrimitiveAddress()));
72 public static LispAFIAddress normalize(LispAFIAddress address, short mask) {
74 if (address instanceof Ipv4Address) {
75 return LispAFIConvertor.asIPAfiAddress(normalizeIP(
76 Inet4Address.getByName(((Ipv4Address) address).getIpv4Address().getValue()),
77 mask).getHostAddress());
78 } else if (address instanceof Ipv6Address) {
79 return LispAFIConvertor.asIPv6AfiAddress(normalizeIP(
80 Inet6Address.getByName(((Ipv6Address) address).getIpv6Address().getValue()),
81 mask).getHostAddress());
82 } else if (address instanceof LcafSegmentAddr) {
83 LcafSegmentAddr segAddr = (LcafSegmentAddr) address;
84 LispAFIAddress afiAddr = LispAFIConvertor
85 .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
86 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
87 LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
88 return new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build();
90 } catch (UnknownHostException e) {
91 LOG.trace("Failed to normalize " + address + ": " + ExceptionUtils.getStackTrace(e));
96 public static LispAFIAddress normalize(LispAFIAddress address) {
97 if (address instanceof Ipv4Address) {
98 return normalize(address, ((Ipv4Address) address).getMask());
99 } else if (address instanceof Ipv6Address) {
100 return normalize(address, ((Ipv6Address) address).getMask());
101 } else if (address instanceof LcafSegmentAddr) {
102 LcafSegmentAddr segAddr = (LcafSegmentAddr) address;
103 LispAFIAddress afiAddr = LispAFIConvertor.toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
104 short mask = getMaskForAfiAddress(afiAddr);
108 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
109 LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
110 return new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build();
115 public static LispAddressContainer normalize(LispAddressContainer address, short mask) {
117 if (address.getAddress() instanceof Ipv4) {
118 return LispAFIConvertor.asIPv4Prefix(normalizeIP(
119 Inet4Address.getByName(((Ipv4) address.getAddress()).getIpv4Address().getIpv4Address().getValue()),
120 mask).getHostAddress(), mask);
121 } else if (address.getAddress() instanceof Ipv6) {
122 return LispAFIConvertor.asIPv6Prefix(normalizeIP(
123 Inet6Address.getByName(((Ipv6) address.getAddress()).getIpv6Address().getIpv6Address().getValue()),
124 mask).getHostAddress(), mask);
125 } else if (address.getAddress() instanceof LcafSegment) {
126 LcafSegmentAddress segAddr = ((LcafSegment) address.getAddress()).getLcafSegmentAddr();
127 LispAFIAddress afiAddr = LispAFIConvertor
128 .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
129 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
130 LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
131 return new LispAddressContainerBuilder().setAddress(
132 new LcafSegmentBuilder().setLcafSegmentAddr(
133 new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build()).build())
136 } catch (UnknownHostException e) {
137 LOG.trace("Failed to normalize " + address + ": " + ExceptionUtils.getStackTrace(e));
142 public static LispAddressContainer normalize(LispAddressContainer address) {
143 if (address.getAddress() instanceof Ipv4) {
144 return normalize(address, ((Ipv4)address.getAddress()).getIpv4Address().getMask());
145 } else if (address.getAddress() instanceof Ipv6) {
146 return normalize(address, ((Ipv6)address.getAddress()).getIpv6Address().getMask());
147 } else if (address.getAddress() instanceof LcafSegment) {
148 LcafSegmentAddress segAddr = ((LcafSegment) address.getAddress()).getLcafSegmentAddr();
149 LispAFIAddress afiAddr = LispAFIConvertor
150 .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
151 short mask = getMaskForAfiAddress(afiAddr);
155 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
156 LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
157 return new LispAddressContainerBuilder().setAddress(
158 new LcafSegmentBuilder().setLcafSegmentAddr(
159 new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build()).build())
165 private static InetAddress normalizeIP(InetAddress address, int mask) throws UnknownHostException {
166 ByteBuffer byteRepresentation = ByteBuffer.wrap(address.getAddress());
167 byte b = (byte) 0xff;
168 for (int i = 0; i < byteRepresentation.array().length; i++) {
170 byteRepresentation.put(i, (byte) (b & byteRepresentation.get(i)));
173 byteRepresentation.put(i, (byte) ((byte) (b << (8 - mask)) & byteRepresentation.get(i)));
175 byteRepresentation.put(i, (byte) (0 & byteRepresentation.get(i)));
180 return InetAddress.getByAddress(byteRepresentation.array());
183 public static String normalizeIPString(String addr, int mask) {
184 short afi = getIpAfiForString(addr);
187 return normalizeIP(Inet4Address.getByName(addr), mask).getHostAddress();
188 } else if (afi == 2) {
189 return normalizeIP(Inet6Address.getByName(addr), mask).getHostAddress();
191 LOG.debug("The string {} is not a valid IP address!", addr);
194 } catch (Exception e){
195 LOG.trace("Failed to normalize " + addr + ": " + ExceptionUtils.getStackTrace(e));
200 public static int getMaxMask(LispAFIAddress address) {
201 if (address instanceof Ipv4Address) {
204 if (address instanceof Ipv6Address) {
210 public static byte getMaxMaskForAfi(int afi) {
213 } else if (afi == 2) {
220 private static short getMaskForAfiAddress(LispAFIAddress addr) {
221 if (addr instanceof Ipv4Address) {
222 Short res = ((Ipv4Address) addr).getMask();
223 return (res != null) ? res.shortValue() : 32;
224 } else if (addr instanceof Ipv6Address) {
225 Short res = ((Ipv6Address) addr).getMask();
226 return (res != null) ? res.shortValue() : 128;
232 public static short getMaskForAddress(LispAddressContainer addr) {
233 if (addr.getAddress() instanceof Ipv4) {
234 Short res = ((Ipv4)addr.getAddress()).getIpv4Address().getMask();
235 return (res != null) ? res.shortValue() : 32;
236 } else if (addr.getAddress() instanceof Ipv6) {
237 Short res = ((Ipv6)addr.getAddress()).getIpv6Address().getMask();
238 return (res != null) ? res.shortValue() : 128;
239 } else if (addr.getAddress() instanceof LcafSegment) {
240 return getMaskForAfiAddress(LispAFIConvertor.toAFIfromPrimitive((((LcafSegment) addr.getAddress())
241 .getLcafSegmentAddr()).getAddress().getPrimitiveAddress()));
246 private static short getIpAfiForString(String addr) {
247 if(addr.matches("([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])") == true){
250 else if(addr.matches("([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)") == true){
256 public static LispAddressContainer setMask(LispAddressContainer addr, int mask) {
257 if (addr.getAddress() instanceof Ipv4) {
258 return new LispAddressContainerBuilder().setAddress(
259 new Ipv4Builder().setIpv4Address(
260 new Ipv4AddressBuilder(((Ipv4) addr.getAddress()).getIpv4Address()).setMask((short) mask)
261 .build()).build()).build();
263 } else if (addr.getAddress() instanceof Ipv6) {
264 return new LispAddressContainerBuilder().setAddress(
265 new Ipv6Builder().setIpv6Address(
266 new Ipv6AddressBuilder(((Ipv6) addr.getAddress()).getIpv6Address()).setMask((short) mask)
267 .build()).build()).build();
268 } else if (addr.getAddress() instanceof LcafSegment) {
269 setMask(LispAFIConvertor.toAFIfromPrimitive(((LcafSegment) addr.getAddress()).getLcafSegmentAddr()
270 .getAddress().getPrimitiveAddress()), mask);
275 public static LispAFIAddress setMask(LispAFIAddress addr, int mask) {
276 if (addr instanceof LispIpv4Address) {
277 return new Ipv4AddressBuilder().setIpv4Address(((LispIpv4Address) addr).getIpv4Address())
278 .setAfi(addr.getAfi()).setMask((short)mask).build();
279 } else if (addr instanceof LispIpv6Address) {
280 return new Ipv6AddressBuilder().setIpv6Address(((LispIpv6Address) addr).getIpv6Address())
281 .setAfi(addr.getAfi()).setMask((short)mask).build();
282 } else if (addr instanceof LcafSegmentAddress) {
283 LispAFIAddress afiAddr = LispAFIConvertor.toAFIfromPrimitive(((LcafSegmentAddress) addr).getAddress()
284 .getPrimitiveAddress());
285 afiAddr = setMask(afiAddr, mask);
286 return new LcafSegmentAddrBuilder((LcafSegmentAddress) addr).setAddress(
287 new AddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(afiAddr)).build()).build();
292 public static LispAFIAddress setMaskSourceDest(LispAFIAddress addr, int srcMask, int dstMask) {
293 DstAddress dst = LcafSourceDestHelper.getDstAddress(addr);
294 LispAFIAddress dstAfi = LispAFIConvertor.toAFIfromPrimitive(dst.getPrimitiveAddress());
295 DstAddress newDst = new DstAddressBuilder(dst).setPrimitiveAddress(LispAFIConvertor.toPrimitive(setMask(dstAfi, dstMask))).build();
296 SrcAddress src = LcafSourceDestHelper.getSrcAddress(addr);
297 LispAFIAddress srcAfi = LispAFIConvertor.toAFIfromPrimitive(src.getPrimitiveAddress());
298 SrcAddress newSrc = new SrcAddressBuilder(src).setPrimitiveAddress(LispAFIConvertor.toPrimitive(setMask(srcAfi, srcMask))).build();
299 return new LcafSourceDestAddrBuilder((LcafSourceDestAddress)addr).setDstAddress(newDst).setSrcAddress(newSrc).build();
302 public static LispAddressContainer setMaskSourceDest(LispAddressContainer addr, int srcMask, int dstMask) {
303 return new LispAddressContainerBuilder().setAddress(
304 new LcafSourceDestBuilder((LcafSourceDest) addr.getAddress()).setLcafSourceDestAddr(
305 (LcafSourceDestAddr) setMaskSourceDest(
306 ((LcafSourceDest) addr.getAddress()).getLcafSourceDestAddr(), srcMask, dstMask))
311 * RFC6830 defines masks and EIDs as separate fields of larger, encompassing blocks of LISP messages. However within
312 * LispFlowMapping masks are internal fields of EIDs. The fixMask methods should be used in deserializers and RPC
313 * handlers to ensure that masks for EIDs reflect accordingly the mask field values carried in LISP messages or RPC
314 * input objects respectively.
316 public static LispAFIAddress fixMask(LispAFIAddress addr, short mask) {
317 if (addr instanceof LispIpv4Address || addr instanceof LispIpv6Address || addr instanceof LcafSegmentAddress) {
318 return MaskUtil.setMask(addr, mask);
319 } else if (addr instanceof LcafSourceDestAddress) {
320 return MaskUtil.setMaskSourceDest(addr, LcafSourceDestHelper.getSrcMask(addr),
321 LcafSourceDestHelper.getDstMask(addr));
326 public static LispAddressContainer fixMask(LispAddressContainer addr, short mask) {
327 if (addr.getAddress() instanceof Ipv4 || addr.getAddress() instanceof Ipv6
328 || addr.getAddress() instanceof LcafSegment) {
329 return MaskUtil.setMask(addr, mask);
330 } else if (addr.getAddress() instanceof LcafSourceDest) {
331 return MaskUtil.setMaskSourceDest(addr, LcafSourceDestHelper.getSrcMask(addr),
332 LcafSourceDestHelper.getDstMask(addr));