2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.openflowplugin.impl.util;
10 import java.net.InetAddress;
11 import java.net.UnknownHostException;
12 import java.util.Locale;
13 import org.eclipse.jdt.annotation.Nullable;
14 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.IpConversionUtil;
16 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
17 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
27 import org.opendaylight.yangtools.yang.common.Uint32;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Utility class used for converting OpenFlow port numbers, Ipv4 and Ipv6 addresses to normalized format.
34 public final class AddressNormalizationUtil {
35 private static final Logger LOG = LoggerFactory.getLogger(AddressNormalizationUtil.class);
37 private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff";
38 private static final String PREFIX_SEPARATOR = "/";
40 private AddressNormalizationUtil() {
44 * Extract port number from URI and convert it to OpenFlow specific textual representation.
46 * @param port the OpenFlow port
47 * @param protocolVersion the OpenFLow protocol version
48 * @return normalized uri
50 public static @Nullable Uri normalizeProtocolAgnosticPort(@Nullable final Uri port, final short protocolVersion) {
55 Uint32 portValue = InventoryDataServiceUtil
56 .portNumberfromNodeConnectorId(OpenflowVersion.get(protocolVersion), port.getValue());
58 return portValue == null ? null : OpenflowPortsUtil.getProtocolAgnosticPortUri(protocolVersion, portValue);
62 * Normalize Ipv6 address with prefix mask (ex. 1234:5678:9ABC::/76) and apply prefix mask to Ipv6 address.
64 * @param ipv6Prefix the Ipv6 prefix
65 * @return normalized Ipv6 prefix
67 public static @Nullable Ipv6Prefix normalizeIpv6Prefix(@Nullable final Ipv6Prefix ipv6Prefix) {
68 if (ipv6Prefix == null) {
72 final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(IpConversionUtil.extractIpv6Address(ipv6Prefix));
74 IpConversionUtil.convertIpv6PrefixToByteArray(IpConversionUtil.extractIpv6Prefix(ipv6Prefix));
75 return normalizeIpv6Address(address, mask);
79 * Normalize Ipv6 address and arbitrary mask and apply arbitrary mask to Ipv6 address.
81 * @param ipv6Address the Ipv4 address
82 * @param ipv4Mask the Ipv4 mask
83 * @return normalized Ipv6 prefix
85 public static @Nullable Ipv6Prefix normalizeIpv6Arbitrary(@Nullable final Ipv6Address ipv6Address,
86 @Nullable final Ipv6ArbitraryMask ipv4Mask) {
87 if (ipv6Address == null) {
91 final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(ipv6Address);
92 final byte[] mask = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(ipv4Mask);
93 return normalizeIpv6Address(address, mask);
97 * Normalize ipv 6 address without mask.
99 * @param ipv6Address the Ipv6 address
100 * @return normalized Ipv6 address
102 public static @Nullable Ipv6Address normalizeIpv6AddressWithoutMask(@Nullable final Ipv6Address ipv6Address) {
103 final Ipv6Prefix ipv6Prefix = normalizeIpv6Arbitrary(ipv6Address, null);
104 return ipv6Prefix == null ? null : new Ipv6Address(ipv6Prefix.getValue().split(PREFIX_SEPARATOR)[0]);
108 * Normalize Ipv4 address with prefix mask (ex. 192.168.0.1/24) and apply prefix mask to Ipv4 address.
110 * @param ipv4Prefix the Ipv4 prefix
111 * @return normalized Ipv4 prefix
113 public static @Nullable Ipv4Prefix normalizeIpv4Prefix(@Nullable final Ipv4Prefix ipv4Prefix) {
114 if (ipv4Prefix == null) {
118 final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(IpConversionUtil.extractIpv4Address(ipv4Prefix));
120 IpConversionUtil.convertArbitraryMaskToByteArray(IpConversionUtil.extractIpv4AddressMask(ipv4Prefix));
121 return normalizeIpv4Address(address, mask);
125 * Normalize Ipv4 address and arbitrary mask and apply arbitrary mask to Ipv4 address.
127 * @param ipv4Address the Ipv4 address
128 * @param ipv4Mask the Ipv4 mask
129 * @return normalized Ipv4 prefix
131 public static @Nullable Ipv4Prefix normalizeIpv4Arbitrary(@Nullable final Ipv4Address ipv4Address,
132 @Nullable final DottedQuad ipv4Mask) {
133 if (ipv4Address == null) {
137 final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(ipv4Address);
138 final byte[] mask = IpConversionUtil.convertArbitraryMaskToByteArray(ipv4Mask);
139 return normalizeIpv4Address(address, mask);
143 * Normalize Ipv4 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv4 address.
145 * @param address Ipv4 address byte array
146 * @param mask Ipv4 mask byte array
147 * @return normalized Ipv4 prefix
149 public static @Nullable Ipv4Prefix normalizeIpv4Address(final byte @Nullable [] address,
150 final byte @Nullable [] mask) {
151 final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
153 if (addressPrefix == null) {
157 return new Ipv4Prefix(addressPrefix);
162 * Normalize Ipv6 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv6 address.
164 * @param address Ipv6 address byte array
165 * @param mask Ipv6 mask byte array
166 * @return normalized Ipv6 prefix
168 public static @Nullable Ipv6Prefix normalizeIpv6Address(final byte @Nullable [] address,
169 final byte @Nullable [] mask) {
170 final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
172 if (addressPrefix == null) {
176 return new Ipv6Prefix(addressPrefix);
180 * Normalize generic IP address and arbitrary mask in byte array format and apply arbitrary mask to IP address.
182 * @param address address byte array
183 * @param mask mask byte array
184 * @return normalized Inet address
186 public static @Nullable InetAddress normalizeIpAddress(final byte @Nullable [] address,
187 final byte @Nullable [] mask) {
188 if (address == null) {
192 final byte[] result = new byte[address.length];
194 for (int i = 0; i < address.length; i++) {
195 result[i] = mask != null ? (byte) (address[i] & mask[i]) : address[i];
199 return InetAddress.getByAddress(result);
200 } catch (UnknownHostException e) {
201 LOG.warn("Failed to recognize the host while normalizing IP address from bytes ", e);
207 * Convert arbitrary mask to prefix mask and append it to textual representation of Inet address.
209 * @param address the address
210 * @param mask the mask
213 public static @Nullable String normalizeInetAddressWithMask(final @Nullable InetAddress address,
214 final byte @Nullable [] mask) {
215 if (address == null) {
219 return address.getHostAddress()
220 + (mask == null ? "" : PREFIX_SEPARATOR + String.valueOf(IpConversionUtil.countBits(mask)));
224 * Convert MAC address to it's lower case format.
226 * @param macAddress the MAC address
227 * @return normalized MAC address
230 public static MacAddress normalizeMacAddress(@Nullable final MacAddress macAddress) {
231 return macAddress == null ? null : new MacAddress(macAddress.getValue().toLowerCase(Locale.ROOT));
235 * Convert MAC address mask to it's lower case format and if it is full F mask, return null.
237 * @param macAddress the MAC address
238 * @return normalized MAC address
241 public static MacAddress normalizeMacAddressMask(@Nullable final MacAddress macAddress) {
242 final MacAddress normalizedMacAddress = normalizeMacAddress(macAddress);
244 if (normalizedMacAddress == null) {
248 if (NO_ETH_MASK.equals(normalizedMacAddress.getValue())) {
252 return normalizedMacAddress;