1
2
3
4
5
6
7
8 package org.opendaylight.lispflowmapping.lisp.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.net.InetAddresses;
12
13 import java.net.Inet4Address;
14 import java.net.Inet6Address;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.nio.ByteBuffer;
18
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ServicePath;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKeyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public final class MaskUtil {
36 private static final Logger LOG = LoggerFactory.getLogger(MaskUtil.class);
37 private static final short IPV4_MAX_MASK = 32;
38 private static final short IPV6_MAX_MASK = 128;
39
40
41 private MaskUtil() {
42 }
43
44 public static boolean isMaskable(Address address) {
45 if (address instanceof Ipv4Prefix || address instanceof Ipv6Prefix || address instanceof SourceDestKey) {
46 return true;
47 } else if (address instanceof InstanceId) {
48 return isMaskable(((InstanceId)address).getInstanceId().getAddress());
49 }
50 return false;
51 }
52
53 public static boolean isMaskable(SimpleAddress address) {
54 if (address.getIpPrefix() != null) {
55 return true;
56 }
57 return false;
58 }
59
60 private static final int slashPosition(final String prefix) {
61 final int slash = prefix.lastIndexOf('/');
62 Preconditions.checkArgument(slash >= 0, "Argument %s does not contain a slash", prefix);
63 return slash;
64 }
65
66 private static String getPrefixAddress(final String prefix) {
67 return prefix.substring(0, slashPosition(prefix));
68 }
69
70 private static String getPrefixMask(final String prefix) {
71 return prefix.substring(slashPosition(prefix) + 1);
72 }
73
74 private static String[] splitPrefix(final String prefix) {
75 final int slash = slashPosition(prefix);
76 return new String[] { prefix.substring(0, slash), prefix.substring(slash + 1) };
77 }
78
79 public static Eid normalize(Eid eid, short mask) {
80 Address address = eid.getAddress();
81 try {
82 if (address instanceof Ipv4Prefix) {
83 final String addr = getPrefixAddress(((Ipv4Prefix)address).getIpv4Prefix().getValue());
84 InetAddress normalized = normalizeIP(InetAddresses.forString(addr), mask);
85 return LispAddressUtil.asIpv4PrefixEid(eid, (Inet4Address)normalized, mask);
86 } else if (address instanceof Ipv6Prefix) {
87 final String addr = getPrefixAddress(((Ipv6Prefix)address).getIpv6Prefix().getValue());
88 InetAddress normalized = normalizeIP(InetAddresses.forString(addr), mask);
89 return LispAddressUtil.asIpv6PrefixEid(eid, (Inet6Address)normalized, mask);
90 } else if (address instanceof InstanceId) {
91
92 return eid;
93 }
94 } catch (UnknownHostException e) {
95 LOG.warn("Failed to normalize EID {} with mask {}, returning original EID", eid, mask, e);
96 }
97 return eid;
98 }
99
100 public static Eid normalize(Eid eid) {
101 Address address = eid.getAddress();
102 try {
103 if (address instanceof Ipv4Prefix) {
104 String[] v4prefix = splitPrefix(((Ipv4Prefix)address).getIpv4Prefix().getValue());
105 short mask = Short.parseShort(v4prefix[1]);
106 InetAddress normalized = normalizeIP(InetAddresses.forString(v4prefix[0]), mask);
107 return LispAddressUtil.asIpv4PrefixEid(eid, (Inet4Address) normalized, mask);
108 } else if (address instanceof Ipv6Prefix) {
109 String[] v6prefix = splitPrefix(((Ipv6Prefix)address).getIpv6Prefix().getValue());
110 short mask = Short.parseShort(v6prefix[1]);
111 InetAddress normalized = normalizeIP(InetAddresses.forString(v6prefix[0]), mask);
112 return LispAddressUtil.asIpv6PrefixEid(eid, (Inet6Address) normalized, mask);
113 } else if (address instanceof Ipv4) {
114 return LispAddressUtil.asIpv4PrefixEid(((Ipv4) address).getIpv4(), eid.getVirtualNetworkId());
115 } else if (address instanceof Ipv6) {
116 return LispAddressUtil.asIpv6PrefixEid(((Ipv6) address).getIpv6(), eid.getVirtualNetworkId());
117 } else if (address instanceof InstanceId) {
118
119 return eid;
120 } else if (address instanceof SourceDestKey) {
121 return normalizeSrcDst(eid);
122 } else if (address instanceof ServicePath) {
123
124 long spi = ((ServicePath) address).getServicePath().getServicePathId().getValue();
125 long vni = eid.getVirtualNetworkId() != null ? eid.getVirtualNetworkId().getValue() : -1;
126 return LispAddressUtil.asServicePathEid(vni, spi, (short)0);
127 }
128 } catch (UnknownHostException e) {
129 LOG.warn("Failed to normalize EID {}, returning original", eid, e);
130 }
131 return eid;
132 }
133
134 private static Eid normalizeSrcDst(Eid eid) throws UnknownHostException {
135 final SimpleAddress normalizedSrc = normalizeSimpleAddress(
136 ((SourceDestKey) eid.getAddress()).getSourceDestKey().getSource());
137 final SimpleAddress normalizedDst = normalizeSimpleAddress(
138 ((SourceDestKey) eid.getAddress()).getSourceDestKey().getDest());
139 return LispAddressUtil.asSrcDstEid(new SourceDestKeyBuilder()
140 .setSource(normalizedSrc).setDest(normalizedDst).build(), eid.getVirtualNetworkId());
141 }
142
143 private static SimpleAddress normalizeSimpleAddress(SimpleAddress address) throws UnknownHostException {
144 if (address.getIpPrefix() == null) {
145 return address;
146 }
147 return new SimpleAddress(normalizeIpPrefix(address.getIpPrefix()));
148 }
149
150 private static IpPrefix normalizeIpPrefix(IpPrefix address) throws UnknownHostException {
151 String[] prefix = splitPrefix(String.valueOf(address.getValue()));
152 short mask = Short.parseShort(prefix[1]);
153
154 InetAddress normalizedAddress = normalizeIP(InetAddresses.forString(prefix[0]), mask);
155 return IetfInetUtil.INSTANCE.ipPrefixFor(normalizedAddress.getAddress(), mask);
156 }
157
158 private static InetAddress normalizeIP(InetAddress address, int maskLength) throws UnknownHostException {
159 ByteBuffer byteRepresentation = ByteBuffer.wrap(address.getAddress());
160 byte b = (byte) 0xff;
161 int mask = maskLength;
162 for (int i = 0; i < byteRepresentation.array().length; i++) {
163 if (mask >= 8) {
164 byteRepresentation.put(i, (byte) (b & byteRepresentation.get(i)));
165 } else if (mask > 0) {
166 byteRepresentation.put(i, (byte) ((byte) (b << (8 - mask)) & byteRepresentation.get(i)));
167 } else {
168 byteRepresentation.put(i, (byte) (0 & byteRepresentation.get(i)));
169 }
170
171 mask -= 8;
172 }
173 return InetAddress.getByAddress(byteRepresentation.array());
174 }
175
176 public static int getMaxMask(Address address) {
177 if (address instanceof Ipv4 || address instanceof Ipv4Prefix) {
178 return IPV4_MAX_MASK;
179 } else if (address instanceof Ipv6 || address instanceof Ipv6Prefix) {
180 return IPV6_MAX_MASK;
181 } else {
182 return -1;
183 }
184 }
185
186 public static short getMaskForAddress(SimpleAddress address) {
187 if (address.getIpPrefix() == null) {
188 return -1;
189 }
190 return getMaskForIpPrefix(address.getIpPrefix());
191 }
192
193 private static String getIpPrefixString(IpPrefix prefix) {
194 if (prefix.getIpv4Prefix() != null) {
195 return prefix.getIpv4Prefix().getValue();
196 } else if (prefix.getIpv6Prefix() != null) {
197 return prefix.getIpv6Prefix().getValue();
198 } else {
199 throw new IllegalArgumentException("Invalid prefix " + prefix);
200 }
201 }
202
203 public static short getMaskForIpPrefix(IpPrefix prefix) {
204 return Short.parseShort(getPrefixMask(getIpPrefixString(prefix)));
205 }
206
207 public static String getAddressStringForIpPrefix(IpPrefix prefix) {
208 return getPrefixAddress(getIpPrefixString(prefix));
209 }
210
211 public static String getAddressStringForIpv4Prefix(Ipv4Prefix prefix) {
212 return getPrefixAddress(prefix.getIpv4Prefix().getValue());
213 }
214
215 public static String getAddressStringForIpv6Prefix(Ipv6Prefix prefix) {
216 return getPrefixAddress(prefix.getIpv6Prefix().getValue());
217 }
218
219 public static short getMaskForAddress(Address address) {
220 if (address instanceof Ipv4) {
221 return IPV4_MAX_MASK;
222 } else if (address instanceof Ipv6) {
223 return IPV6_MAX_MASK;
224 } else if (address instanceof Ipv4Prefix) {
225 return Short.parseShort(getPrefixMask(((Ipv4Prefix)address).getIpv4Prefix().getValue()));
226 } else if (address instanceof Ipv6Prefix) {
227 return Short.parseShort(getPrefixMask(((Ipv6Prefix)address).getIpv6Prefix().getValue()));
228 } else if (address instanceof InstanceId) {
229 return getMaskForAddress(((InstanceId)address).getInstanceId().getAddress());
230 }
231 return -1;
232 }
233 }