classes = new HashSet<>();
}
+ /**
+ * Get augmentation classes
+ * @return list of augmentation classes
+ */
+ public Set<Class<? extends Augmentation<?>>> getClasses() {
+ return classes;
+ }
+
/**
* @param cls equivalent augmentation class
* @return this for chaining
return Optional.empty();
}
+
}
*/
void addMark(KEY key);
- /**
- * Checks if registry has mark for KEY.
- * @param key device registry key
- * @return true if device registry has mark for KEY
- */
- boolean hasMark(KEY key);
-
/**
* Process marked keys.
*/
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
-import java.util.function.BiConsumer;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.registry.CommonDeviceRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
ListenableFuture<List<Optional<FlowCapableNode>>> fill();
- void storeDescriptor(FlowRegistryKey flowRegistryKey, FlowDescriptor flowDescriptor);
+ void storeDescriptor(@Nonnull FlowRegistryKey flowRegistryKey, @Nonnull FlowDescriptor flowDescriptor);
- FlowDescriptor retrieveDescriptor(FlowRegistryKey flowRegistryKey);
-
- void forEachEntry(BiConsumer<FlowRegistryKey, FlowDescriptor> consumer);
+ @Nullable
+ FlowDescriptor retrieveDescriptor(@Nonnull FlowRegistryKey flowRegistryKey);
}
package org.opendaylight.openflowplugin.impl.datastore.multipart;
+import java.util.Objects;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(version, flow.build());
registry.getDeviceFlowRegistry().store(flowRegistryKey);
- final FlowKey key = new FlowKey(registry
- .getDeviceFlowRegistry()
- .retrieveDescriptor(flowRegistryKey)
- .getFlowId());
+ final FlowDescriptor flowDescriptor = registry
+ .getDeviceFlowRegistry()
+ .retrieveDescriptor(flowRegistryKey);
- writeToTransaction(
- getInstanceIdentifier()
- .augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(stat.getTableId()))
- .child(Flow.class, key),
- flow
- .setId(key.getId())
- .setKey(key)
- .build(),
- withParents);
+ if (Objects.nonNull(flowDescriptor)) {
+ final FlowKey key = new FlowKey(flowDescriptor
+ .getFlowId());
+
+ writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(stat.getTableId()))
+ .child(Flow.class, key),
+ flow
+ .setId(key.getId())
+ .setKey(key)
+ .build(),
+ withParents);
+ }
});
}
import com.google.common.base.Optional;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
+import com.google.common.collect.Maps;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.Nonnull;
import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
private static final String ALIEN_SYSTEM_FLOW_ID = "#UF$TABLE*";
private static final AtomicInteger UNACCOUNTED_FLOWS_COUNTER = new AtomicInteger(0);
- private final BiMap<FlowRegistryKey, FlowDescriptor> flowRegistry = HashBiMap.create();
- private final List<FlowRegistryKey> marks = new ArrayList<>();
+ private final BiMap<FlowRegistryKey, FlowDescriptor> flowRegistry = Maps.synchronizedBiMap(HashBiMap.create());
private final DataBroker dataBroker;
private final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier;
private final List<ListenableFuture<List<Optional<FlowCapableNode>>>> lastFillFutures = new ArrayList<>();
this.dataBroker = dataBroker;
this.instanceIdentifier = instanceIdentifier;
- // Specifies what to do with flow read from datastore
+ // Specifies what to do with flow read from data store
flowConsumer = flow -> {
- // Create flow registry key from flow
- final FlowRegistryKey key = FlowRegistryKeyFactory.create(version, flow);
-
- // Now, we will update the registry, but we will also try to prevent duplicate entries
- if (!flowRegistry.containsKey(key)) {
- LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue());
- final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId());
- storeDescriptor(key, descriptor);
+ final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(version, flow);
+
+ if (!flowRegistry.containsKey(flowRegistryKey)) {
+ // Now, we will update the registry
+ storeDescriptor(flowRegistryKey, FlowDescriptorFactory.create(flow.getTableId(), flow.getId()));
}
};
}
@Override
- @GuardedBy("this")
- public synchronized ListenableFuture<List<Optional<FlowCapableNode>>> fill() {
- LOG.debug("Filling flow registry with flows for node: {}", instanceIdentifier.getKey().getId().getValue());
+ public ListenableFuture<List<Optional<FlowCapableNode>>> fill() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Filling flow registry with flows for node: {}", instanceIdentifier.getKey().getId().getValue());
+ }
// Prepare path for read transaction
// TODO: Read only Tables, and not entire FlowCapableNode (fix Yang model)
return lastFillFuture;
}
- @GuardedBy("this")
private CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> fillFromDatastore(final LogicalDatastoreType logicalDatastoreType, final InstanceIdentifier<FlowCapableNode> path) {
// Create new read-only transaction
final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
// Bail out early if transaction is null
if (transaction == null) {
return Futures.immediateFailedCheckedFuture(
- new ReadFailedException("Read transaction is null"));
+ new ReadFailedException("Read transaction is null"));
}
// Prepare read operation from datastore for path
final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> future =
- transaction.read(logicalDatastoreType, path);
+ transaction.read(logicalDatastoreType, path);
// Bail out early if future is null
if (future == null) {
return Futures.immediateFailedCheckedFuture(
- new ReadFailedException("Future from read transaction is null"));
+ new ReadFailedException("Future from read transaction is null"));
}
Futures.addCallback(future, new FutureCallback<Optional<FlowCapableNode>>() {
@Override
public void onSuccess(Optional<FlowCapableNode> result) {
result.asSet().stream()
- .filter(Objects::nonNull)
- .filter(flowCapableNode -> Objects.nonNull(flowCapableNode.getTable()))
- .flatMap(flowCapableNode -> flowCapableNode.getTable().stream())
- .filter(Objects::nonNull)
- .filter(table -> Objects.nonNull(table.getFlow()))
- .flatMap(table -> table.getFlow().stream())
- .filter(Objects::nonNull)
- .filter(flow -> Objects.nonNull(flow.getId()))
- .forEach(flowConsumer);
+ .filter(Objects::nonNull)
+ .filter(flowCapableNode -> Objects.nonNull(flowCapableNode.getTable()))
+ .flatMap(flowCapableNode -> flowCapableNode.getTable().stream())
+ .filter(Objects::nonNull)
+ .filter(table -> Objects.nonNull(table.getFlow()))
+ .flatMap(table -> table.getFlow().stream())
+ .filter(Objects::nonNull)
+ .filter(flow -> Objects.nonNull(flow.getId()))
+ .forEach(flowConsumer);
// After we are done with reading from datastore, close the transaction
transaction.close();
}
@Override
- @GuardedBy("this")
- public synchronized FlowDescriptor retrieveDescriptor(final FlowRegistryKey flowRegistryKey) {
- LOG.trace("Retrieving flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
- return flowRegistry.get(correctFlowRegistryKey(flowRegistry.keySet(), flowRegistryKey));
+ public FlowDescriptor retrieveDescriptor(@Nonnull final FlowRegistryKey flowRegistryKey) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Retrieving flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
+ }
+
+ return flowRegistry.get(flowRegistryKey);
}
@Override
- @GuardedBy("this")
- public synchronized void storeDescriptor(final FlowRegistryKey flowRegistryKey, final FlowDescriptor flowDescriptor) {
- final FlowRegistryKey correctFlowRegistryKey = correctFlowRegistryKey(flowRegistry.keySet(), flowRegistryKey);
-
+ public void storeDescriptor(@Nonnull final FlowRegistryKey flowRegistryKey,
+ @Nonnull final FlowDescriptor flowDescriptor) {
try {
- if (hasMark(correctFlowRegistryKey)) {
- // We are probably doing update of flow ID or table ID, so remove mark for removal of this flow
- // and replace it with new value
- marks.remove(correctFlowRegistryKey(marks, correctFlowRegistryKey));
- flowRegistry.forcePut(correctFlowRegistryKey, flowDescriptor);
- return;
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Storing flowDescriptor with table ID : {} and flow ID : {} for flow hash : {}",
+ flowDescriptor.getTableKey().getId(), flowDescriptor.getFlowId().getValue(), flowRegistryKey.hashCode());
}
- LOG.trace("Storing flowDescriptor with table ID : {} and flow ID : {} for flow hash : {}",
- flowDescriptor.getTableKey().getId(), flowDescriptor.getFlowId().getValue(), correctFlowRegistryKey.hashCode());
-
- flowRegistry.put(correctFlowRegistryKey, flowDescriptor);
+ flowRegistry.put(flowRegistryKey, flowDescriptor);
} catch (IllegalArgumentException ex) {
- if (hasMark(flowRegistry.inverse().get(flowDescriptor))) {
- // We are probably doing update of flow, but without changing flow ID or table ID, so we need to replace
- // old value with new value, but keep the old value marked for removal
- flowRegistry.forcePut(correctFlowRegistryKey, flowDescriptor);
- return;
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Flow with flow ID {} already exists in table {}, generating alien flow ID", flowDescriptor.getFlowId().getValue(),
+ flowDescriptor.getTableKey().getId());
}
// We are trying to store new flow to flow registry, but we already have different flow with same flow ID
// stored in registry, so we need to create alien ID for this new flow here.
- LOG.warn("Flow with flow ID {} already exists in table {}, generating alien flow ID", flowDescriptor.getFlowId().getValue(),
- flowDescriptor.getTableKey().getId());
-
flowRegistry.put(
- correctFlowRegistryKey,
- FlowDescriptorFactory.create(
- flowDescriptor.getTableKey().getId(),
- createAlienFlowId(flowDescriptor.getTableKey().getId())));
+ flowRegistryKey,
+ FlowDescriptorFactory.create(
+ flowDescriptor.getTableKey().getId(),
+ createAlienFlowId(flowDescriptor.getTableKey().getId())));
}
}
@Override
- @GuardedBy("this")
- public synchronized void forEachEntry(final BiConsumer<FlowRegistryKey, FlowDescriptor> consumer) {
- flowRegistry.forEach(consumer);
- }
-
- @Override
- @GuardedBy("this")
- public synchronized void store(final FlowRegistryKey flowRegistryKey) {
+ public void store(final FlowRegistryKey flowRegistryKey) {
if (Objects.isNull(retrieveDescriptor(flowRegistryKey))) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Flow descriptor for flow hash : {} not found, generating alien flow ID", flowRegistryKey.hashCode());
+ }
+
// We do not found flow in flow registry, that means it do not have any ID already assigned, so we need
// to generate new alien flow ID here.
- LOG.debug("Flow descriptor for flow hash : {} not found, generating alien flow ID", flowRegistryKey.hashCode());
- final short tableId = flowRegistryKey.getTableId();
- final FlowId alienFlowId = createAlienFlowId(tableId);
- final FlowDescriptor flowDescriptor = FlowDescriptorFactory.create(tableId, alienFlowId);
-
- // Finally we got flowDescriptor, so now we will store it to registry,
- // so next time we won't need to generate it again
- storeDescriptor(flowRegistryKey, flowDescriptor);
+ storeDescriptor(
+ flowRegistryKey,
+ FlowDescriptorFactory.create(
+ flowRegistryKey.getTableId(),
+ createAlienFlowId(flowRegistryKey.getTableId())));
}
}
@Override
- @GuardedBy("this")
- public synchronized void addMark(final FlowRegistryKey flowRegistryKey) {
- LOG.trace("Removing flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
- marks.add(flowRegistryKey);
- }
-
- @Override
- @GuardedBy("this")
- public synchronized boolean hasMark(final FlowRegistryKey flowRegistryKey) {
- return Objects.nonNull(flowRegistryKey) && marks.contains(correctFlowRegistryKey(marks, flowRegistryKey));
+ public void addMark(final FlowRegistryKey flowRegistryKey) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Removing flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
+ }
+ flowRegistry.remove(flowRegistryKey);
}
@Override
- @GuardedBy("this")
- public synchronized void processMarks() {
- // Remove all flows that was marked for removal from flow registry and clear all marks.
- marks.forEach(flowRegistry::remove);
- marks.clear();
+ public void processMarks() {
+ // Do nothing
}
@Override
- @GuardedBy("this")
- public synchronized void forEach(final Consumer<FlowRegistryKey> consumer) {
- flowRegistry.keySet().forEach(consumer);
+ public void forEach(final Consumer<FlowRegistryKey> consumer) {
+ synchronized (flowRegistry) {
+ flowRegistry.keySet().forEach(consumer);
+ }
}
@Override
- @GuardedBy("this")
- public synchronized int size() {
+ public int size() {
return flowRegistry.size();
}
@Override
- @GuardedBy("this")
- public synchronized void close() {
+ public void close() {
final Iterator<ListenableFuture<List<Optional<FlowCapableNode>>>> iterator = lastFillFutures.iterator();
- // We need to force interrupt and clear all running futures that are trying to read flow IDs from datastore
+ // We need to force interrupt and clear all running futures that are trying to read flow IDs from data store
while (iterator.hasNext()) {
final ListenableFuture<List<Optional<FlowCapableNode>>> next = iterator.next();
boolean success = next.cancel(true);
}
flowRegistry.clear();
- marks.clear();
- }
-
- @GuardedBy("this")
- private FlowRegistryKey correctFlowRegistryKey(final Collection<FlowRegistryKey> flowRegistryKeys, final FlowRegistryKey key) {
- if (Objects.isNull(key)) {
- return null;
- }
-
- if (!flowRegistryKeys.contains(key)) {
- // If we failed to compare FlowRegistryKey by hashCode, try to retrieve correct FlowRegistryKey
- // from set of keys using custom comparator method for Match. This case can occur when we have different
- // augmentations on extensions, or switch returned things like IP address or port in different format that
- // we sent.
- if (LOG.isTraceEnabled()) {
- LOG.trace("Failed to retrieve flow descriptor for flow hash : {}, trying with custom equals method", key.hashCode());
- }
-
- for (final FlowRegistryKey flowRegistryKey : flowRegistryKeys) {
- if (key.equals(flowRegistryKey)) {
- return flowRegistryKey;
- }
- }
- }
-
- // If we failed to find key at all or key is already present in set of keys, just return original key
- return key;
}
@VisibleForTesting
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
* Created by Martin Bobak <mbobak@cisco.com> on 9.4.2015.
*/
public class FlowDescriptorFactory {
+
private FlowDescriptorFactory() {
// Hide implicit constructor
}
- public static FlowDescriptor create(final short tableId, final FlowId fLowId) {
- final TableKey tableKey = new TableKey(tableId);
- return new FlowDescriptorDto(tableKey, fLowId);
+ @Nonnull
+ public static FlowDescriptor create(final short tableId, @Nonnull final FlowId flowId) {
+ return new FlowDescriptorDto(
+ new TableKey(tableId),
+ Preconditions.checkNotNull(flowId));
}
private static final class FlowDescriptorDto implements FlowDescriptor {
private final FlowId flowId;
private final TableKey tableKey;
- private FlowDescriptorDto(final TableKey tableKey, final FlowId flowId) {
- Preconditions.checkNotNull(tableKey);
- Preconditions.checkNotNull(flowId);
+ private FlowDescriptorDto(@Nonnull final TableKey tableKey, @Nonnull final FlowId flowId) {
this.flowId = flowId;
this.tableKey = tableKey;
}
return tableKey;
}
}
+
}
\ No newline at end of file
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import java.math.BigInteger;
+import javax.annotation.Nonnull;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
-import org.opendaylight.openflowplugin.impl.util.MatchComparatorFactory;
+import org.opendaylight.openflowplugin.impl.util.MatchNormalizationUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-/**
- * Created by Martin Bobak <mbobak@cisco.com> on 8.4.2015.
- */
public class FlowRegistryKeyFactory {
private FlowRegistryKeyFactory() {
// Hide implicit constructor
}
- public static FlowRegistryKey create(final short version, final Flow flow) {
- return new FlowRegistryKeyDto(version, flow);
+ @Nonnull
+ public static FlowRegistryKey create(final short version, @Nonnull final Flow flow) {
+ //TODO: mandatory flow input values (or default values) should be specified via yang model
+ final short tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
+ final int priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
+ final BigInteger cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
+ final Match match = MatchNormalizationUtil.normalizeMatch(MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH), version);
+ return new FlowRegistryKeyDto(tableId, priority, cookie, match);
}
private static final class FlowRegistryKeyDto implements FlowRegistryKey {
private final int priority;
private final BigInteger cookie;
private final Match match;
- private final short version;
-
- private FlowRegistryKeyDto(final short version, final Flow flow) {
- //TODO: mandatory flow input values (or default values) should be specified via yang model
- tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
- priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
- match = MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH);
- cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
- this.version = version;
+
+ private FlowRegistryKeyDto(final short tableId,
+ final int priority,
+ @Nonnull final BigInteger cookie,
+ @Nonnull final Match match) {
+ this.tableId = tableId;
+ this.priority = priority;
+ this.cookie = cookie;
+ this.match = match;
}
@Override
return getPriority() == that.getPriority() &&
getTableId() == that.getTableId() &&
getCookie().equals(that.getCookie()) &&
- MatchComparatorFactory.createMatch().areObjectsEqual(version, getMatch(), that.getMatch());
+ getMatch().equals(that.getMatch());
}
@Override
return match;
}
}
+
}
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
+import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+@ThreadSafe
public class DeviceGroupRegistryImpl implements DeviceGroupRegistry {
private final List<GroupId> groupIds = Collections.synchronizedList(new ArrayList<>());
marks.add(groupId);
}
- @Override
- public boolean hasMark(final GroupId groupId) {
- return marks.contains(groupId);
- }
-
@Override
public void processMarks() {
groupIds.removeAll(marks);
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
+import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+@ThreadSafe
public class DeviceMeterRegistryImpl implements DeviceMeterRegistry {
private final List<MeterId> meterIds = Collections.synchronizedList(new ArrayList<>());
marks.add(meterId);
}
- @Override
- public boolean hasMark(final MeterId meterId) {
- return marks.contains(meterId);
- }
-
@Override
public void processMarks() {
meterIds.removeAll(marks);
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.util;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.IpConversionUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class used for converting OpenFlow port numbers, Ipv4 and Ipv6 addresses to normalized format.
+ */
+public class AddressNormalizationUtil {
+ private static final Logger LOG = LoggerFactory.getLogger(AddressNormalizationUtil.class);
+
+ private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff";
+ private static final String PREFIX_SEPARATOR = "/";
+
+ /**
+ * Extract port number from URI and convert it to OpenFlow specific textual representation.
+ *
+ * @param port the OpenFlow port
+ * @param protocolVersion the OpenFLow protocol version
+ * @return normalized uri
+ */
+ @Nullable
+ public static Uri normalizeProtocolAgnosticPort(@Nullable final Uri port, final short protocolVersion) {
+ if (Objects.isNull(port)) {
+ return null;
+ }
+
+ return OpenflowPortsUtil.getProtocolAgnosticPortUri(protocolVersion, InventoryDataServiceUtil
+ .portNumberfromNodeConnectorId(OpenflowVersion.get(protocolVersion), port.getValue()));
+ }
+
+ /**
+ * Normalize Ipv6 address with prefix mask (ex. 1234:5678:9ABC::/76) and apply prefix mask to Ipv6 address.
+ *
+ * @param ipv6Prefix the Ipv6 prefix
+ * @return normalized Ipv6 prefix
+ */
+ @Nullable
+ public static Ipv6Prefix normalizeIpv6Prefix(@Nullable final Ipv6Prefix ipv6Prefix) {
+ if (Objects.isNull(ipv6Prefix)) {
+ return null;
+ }
+
+ final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(IpConversionUtil.extractIpv6Address(ipv6Prefix));
+ final byte[] mask = IpConversionUtil.convertIpv6PrefixToByteArray(IpConversionUtil.extractIpv6Prefix(ipv6Prefix));
+ return normalizeIpv6Address(address, mask);
+ }
+
+ /**
+ * Normalize Ipv6 address and arbitrary mask and apply arbitrary mask to Ipv6 address.
+ *
+ * @param ipv6Address the Ipv4 address
+ * @param ipv4Mask the Ipv4 mask
+ * @return normalized Ipv6 prefix
+ */
+ @Nullable
+ public static Ipv6Prefix normalizeIpv6Arbitrary(@Nullable final Ipv6Address ipv6Address, @Nullable final Ipv6ArbitraryMask ipv4Mask) {
+ if (Objects.isNull(ipv6Address)) {
+ return null;
+ }
+
+ final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(ipv6Address);
+ final byte[] mask = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(ipv4Mask);
+ return normalizeIpv6Address(address, mask);
+ }
+
+ /**
+ * Normalize ipv 6 address without mask.
+ *
+ * @param ipv6Address the Ipv6 address
+ * @return normalized Ipv6 address
+ */
+ @Nullable
+ public static Ipv6Address normalizeIpv6AddressWithoutMask(@Nullable final Ipv6Address ipv6Address) {
+ final Ipv6Prefix ipv6Prefix = normalizeIpv6Arbitrary(ipv6Address, null);
+ return Objects.nonNull(ipv6Prefix)
+ ? new Ipv6Address(ipv6Prefix.getValue().split(PREFIX_SEPARATOR)[0])
+ : null;
+ }
+
+ /**
+ * Normalize Ipv4 address with prefix mask (ex. 192.168.0.1/24) and apply prefix mask to Ipv4 address.
+ *
+ * @param ipv4Prefix the Ipv4 prefix
+ * @return normalized Ipv4 prefix
+ */
+ @Nullable
+ public static Ipv4Prefix normalizeIpv4Prefix(@Nullable final Ipv4Prefix ipv4Prefix) {
+ if (Objects.isNull(ipv4Prefix)) {
+ return null;
+ }
+
+ final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(IpConversionUtil.extractIpv4Address(ipv4Prefix));
+ final byte[] mask = IpConversionUtil.convertArbitraryMaskToByteArray(IpConversionUtil.extractIpv4AddressMask(ipv4Prefix));
+ return normalizeIpv4Address(address, mask);
+ }
+
+ /**
+ * Normalize Ipv4 address and arbitrary mask and apply arbitrary mask to Ipv4 address.
+ *
+ * @param ipv4Address the Ipv4 address
+ * @param ipv4Mask the Ipv4 mask
+ * @return normalized Ipv4 prefix
+ */
+ @Nullable
+ public static Ipv4Prefix normalizeIpv4Arbitrary(@Nullable final Ipv4Address ipv4Address, @Nullable final DottedQuad ipv4Mask) {
+ if (Objects.isNull(ipv4Address)) {
+ return null;
+ }
+
+ final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(ipv4Address);
+ final byte[] mask = IpConversionUtil.convertArbitraryMaskToByteArray(ipv4Mask);
+ return normalizeIpv4Address(address, mask);
+ }
+
+ /**
+ * Normalize Ipv4 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv4 address.
+ *
+ * @param address Ipv4 address byte array
+ * @param mask Ipv4 mask byte array
+ * @return normalized Ipv4 prefix
+ */
+ @Nullable
+ public static Ipv4Prefix normalizeIpv4Address(@Nullable final byte[] address, @Nullable final byte[] mask) {
+ final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
+
+ if (Objects.isNull(addressPrefix)) {
+ return null;
+ }
+
+ return new Ipv4Prefix(addressPrefix);
+ }
+
+
+ /**
+ * Normalize Ipv6 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv6 address.
+ *
+ * @param address Ipv6 address byte array
+ * @param mask Ipv6 mask byte array
+ * @return normalized Ipv6 prefix
+ */
+ @Nullable
+ public static Ipv6Prefix normalizeIpv6Address(@Nullable final byte[] address, @Nullable final byte[] mask) {
+ final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
+
+ if (Objects.isNull(addressPrefix)) {
+ return null;
+ }
+
+ return new Ipv6Prefix(addressPrefix);
+ }
+
+ /**
+ * Normalize generic IP address and arbitrary mask in byte array format and apply arbitrary mask to IP address.
+ *
+ * @param address address byte array
+ * @param mask mask byte array
+ * @return normalized Inet address
+ */
+ @Nullable
+ public static InetAddress normalizeIpAddress(@Nullable final byte[] address, @Nullable final byte[] mask) {
+ if (Objects.isNull(address)) {
+ return null;
+ }
+
+ final byte[] result = new byte[address.length];
+
+ for (int i = 0; i < address.length; i++) {
+ result[i] = Objects.nonNull(mask) ?
+ (byte) (address[i] & mask[i]) :
+ address[i];
+ }
+
+ try {
+ return InetAddress.getByAddress(result);
+ } catch (UnknownHostException e) {
+ LOG.warn("Failed to recognize the host while normalizing IP address from bytes ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Convert arbitrary mask to prefix mask and append it to textual representation of Inet address
+ *
+ * @param address the address
+ * @param mask the mask
+ * @return the string
+ */
+ @Nullable
+ public static String normalizeInetAddressWithMask(@Nullable final InetAddress address, @Nullable final byte[] mask) {
+ if (Objects.isNull(address)) {
+ return null;
+ }
+
+ return address.getHostAddress() +
+ (Objects.nonNull(mask)
+ ? PREFIX_SEPARATOR + String.valueOf(IpConversionUtil.countBits(mask))
+ : "");
+ }
+
+ /**
+ * Convert MAC address to it's lower case format
+ *
+ * @param macAddress the MAC address
+ * @return normalized MAC address
+ */
+ @Nullable
+ public static MacAddress normalizeMacAddress(@Nullable final MacAddress macAddress) {
+ if (Objects.isNull(macAddress)) {
+ return null;
+ }
+
+ return new MacAddress(macAddress.getValue().toLowerCase());
+ }
+
+ /**
+ * Convert MAC address mask to it's lower case format and if it is full F mask, return null
+ *
+ * @param macAddress the MAC address
+ * @return normalized MAC address
+ */
+ @Nullable
+ public static MacAddress normalizeMacAddressMask(@Nullable final MacAddress macAddress) {
+ final MacAddress normalizedMacAddress = normalizeMacAddress(macAddress);
+
+ if (Objects.isNull(normalizedMacAddress)) {
+ return null;
+ }
+
+ if (NO_ETH_MASK.equals(normalizedMacAddress.getValue())) {
+ return null;
+ }
+
+ return normalizedMacAddress;
+ }
+
+}
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.util;
-
-/**
- * 4B base + 4B mask wrapper
- */
-public class IntegerIpAddress {
-
- int ip;
- int mask;
-
- public IntegerIpAddress(final int ip, final int mask) {
- this.ip = ip;
- this.mask = mask;
- }
-
- public int getIp() {
- return ip;
- }
-
- public int getMask() {
- return mask;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013, 2015 IBM Corporation and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Optional;
-import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
-import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
-import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
-
-/**
- * Provides comparator for comparing according to various {@link Match} attributes
- *
- */
-public final class MatchComparatorFactory {
-
- private MatchComparatorFactory() {
- // NOOP
- }
-
- private static final Collection<SimpleComparator<Match>> MATCH_COMPARATORS = new ArrayList<>();
- static {
- MATCH_COMPARATORS.add(MatchComparatorFactory.createEthernet());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createIcmpv4());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createInPhyPort());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createInPort());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createIp());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createL3());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createL4());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createProtocolMatchFields());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createMetadata());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createNull());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createTunnel());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createVlan());
- MATCH_COMPARATORS.add(MatchComparatorFactory.createExtension());
- }
-
- private static SimpleComparator<Match> createExtension() {
- return new SimpleComparator<Match>() {
- /**
- * Compare extension lists
- */
- @Override
- public boolean areObjectsEqual(final short version, final Match statsMatch, final Match storedMatch) {
- return ExtensionResolvers
- .getMatchExtensionResolver()
- .getExtension(statsMatch)
- .flatMap(statExt -> Optional.ofNullable(statExt.getExtensionList()))
- .map(statList -> ExtensionResolvers
- .getMatchExtensionResolver()
- .getExtension(storedMatch)
- .flatMap(storedExt -> Optional.ofNullable(storedExt.getExtensionList()))
- .filter(storedList -> statList.size() == storedList.size())
- .map(storedList -> {
- final Collection<ExtensionList> difference = new HashSet<>(statList);
- difference.removeAll(storedList);
- return difference.isEmpty();
- })
- .orElse(false))
- .orElse(!ExtensionResolvers
- .getMatchExtensionResolver()
- .getExtension(storedMatch)
- .flatMap(storedExt -> Optional.ofNullable(storedExt.getExtensionList()))
- .isPresent());
- }
- };
- }
-
- private static SimpleComparator<Match> createNull() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by whole object
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- return (statsMatch == null) == (storedMatch == null);
- }
- };
- }
-
- private static SimpleComparator<Match> createVlan() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by VLAN
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getVlanMatch() == null) {
- if (statsMatch.getVlanMatch() != null) {
- return false;
- }
- } else if (!storedMatch.getVlanMatch().equals(statsMatch.getVlanMatch())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createTunnel() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by tunnel
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getTunnel() == null) {
- if (statsMatch.getTunnel() != null) {
- return false;
- }
- } else if (!storedMatch.getTunnel().equals(statsMatch.getTunnel())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createProtocolMatchFields() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by protocol fields
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getProtocolMatchFields() == null) {
- if (statsMatch.getProtocolMatchFields() != null) {
- return false;
- }
- } else if (!storedMatch.getProtocolMatchFields().equals(statsMatch.getProtocolMatchFields())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createMetadata() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by metadata
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getMetadata() == null) {
- if (statsMatch.getMetadata() != null) {
- return false;
- }
- } else if (!storedMatch.getMetadata().equals(statsMatch.getMetadata())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createL4() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by layer4
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getLayer4Match() == null) {
- if (statsMatch.getLayer4Match() != null) {
- return false;
- }
- } else if (!storedMatch.getLayer4Match().equals(statsMatch.getLayer4Match())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createL3() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by layer3
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getLayer3Match() == null) {
- if (statsMatch.getLayer3Match() != null) {
- return false;
- }
- } else if (!MatchComparatorHelper.layer3MatchEquals(statsMatch.getLayer3Match(), storedMatch.getLayer3Match())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createIp() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by Ip
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getIpMatch() == null) {
- if (statsMatch.getIpMatch() != null) {
- return false;
- }
- } else if (!storedMatch.getIpMatch().equals(statsMatch.getIpMatch())) {
- return false;
- }
- return true;
- }
- };
- }
-
-
- /**
- * Converts both ports in node connector id format to number format and compare them
- *
- * @param version openflow version
- * @param left first object to compare
- * @param right second object to compare
- * @return true if equal
- */
- private static boolean arePortNumbersEqual(short version, NodeConnectorId left, NodeConnectorId right) {
- final OpenflowVersion ofVersion = OpenflowVersion.get(version);
-
- final Long leftPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, left);
- final Long rightPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, right);
-
- if (leftPort == null) {
- if (rightPort != null) {
- return false;
- }
- } else if (!leftPort.equals(rightPort)) {
- return false;
- }
-
- return true;
- }
-
- private static SimpleComparator<Match> createInPort() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by InPort
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getInPort() == null) {
- if (statsMatch.getInPort() != null) {
- return false;
- }
- } else if (!arePortNumbersEqual(version, storedMatch.getInPort(), statsMatch.getInPort())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createInPhyPort() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by InPhyPort
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getInPhyPort() == null) {
- if (statsMatch.getInPhyPort() != null) {
- return false;
- }
- } else if (!arePortNumbersEqual(version, storedMatch.getInPhyPort(), statsMatch.getInPhyPort())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createEthernet() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by Ethernet
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getEthernetMatch() == null) {
- if (statsMatch.getEthernetMatch() != null) {
- return false;
- }
- } else if (!MatchComparatorHelper.ethernetMatchEquals(statsMatch.getEthernetMatch(), storedMatch.getEthernetMatch())) {
- return false;
- }
- return true;
- }
- };
- }
-
- private static SimpleComparator<Match> createIcmpv4() {
- return new SimpleComparator<Match>() {
- /**
- * Compares by Icmpv4
- */
- @Override
- public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
- if (storedMatch == null) {
- return false;
- }
- if (storedMatch.getIcmpv4Match() == null) {
- if (statsMatch.getIcmpv4Match() != null) {
- return false;
- }
- } else if (!storedMatch.getIcmpv4Match().equals(statsMatch.getIcmpv4Match())) {
- return false;
- }
- return true;
- }
- };
- }
-
- public static SimpleComparator<Match> createMatch() {
- return new SimpleComparator<Match>() {
- /**
- * Compares flows by whole match
- */
- @Override
- public boolean areObjectsEqual(short version, final Match statsFlow, final Match storedFlow) {
- if (statsFlow == null) {
- if (storedFlow != null) {
- return false;
- }
- } else if (!compareMatches(version, statsFlow, storedFlow)) {
- return false;
- }
- return true;
- }
- };
- }
-
-
- /**
- * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
- * Flow installation process has three steps
- * 1) Store flow in config data store
- * 2) and send it to plugin for installation
- * 3) Flow gets installed in switch
- *
- * The flow user wants to install and what finally gets installed in switch can be slightly different.
- * E.g, If user installs flow with src/dst ip=10.0.0.1/24, when it get installed in the switch
- * src/dst ip will be changes to 10.0.0.0/24 because of netmask of 24. When statistics manager fetch
- * stats it gets 10.0.0.0/24 rather then 10.0.0.1/24. Custom match takes care of by using masked ip
- * while comparing two ip addresses.
- *
- * Sometimes when user don't provide few values that is required by flow installation request, like
- * priority,hard timeout, idle timeout, cookies etc, plugin usages default values before sending
- * request to the switch. So when statistics manager gets flow statistics, it gets the default value.
- * But the flow stored in config data store don't have those defaults value. I included those checks
- * in the customer flow/match equal function.
- */
- private static boolean compareMatches(final short version, final Match statsMatch, final Match storedMatch) {
- if (statsMatch == storedMatch) {
- return true;
- }
-
- for (SimpleComparator<Match> matchComp : MATCH_COMPARATORS) {
- if (!matchComp.areObjectsEqual(version, statsMatch, storedMatch)) {
- return false;
- }
- }
- return true;
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2015, 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.util;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.net.InetAddresses;
-import com.google.common.primitives.UnsignedBytes;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.MacAddressFilter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigInteger;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * @author joe
- * @author sai.marapareddy@gmail.com
- *
- */
-public class MatchComparatorHelper {
-
- private static final Logger LOG = LoggerFactory.getLogger(MatchComparatorHelper.class);
- private static final int DEFAULT_SUBNET = 32;
- private static final int IPV4_MASK_LENGTH = 32;
- private static final int SHIFT_OCTET_1 = 24;
- private static final int SHIFT_OCTET_2 = 16;
- private static final int SHIFT_OCTET_3 = 8;
- private static final int SHIFT_OCTET_4 = 0;
- private static final int POSITION_OCTET_1 = 0;
- private static final int POSITION_OCTET_2 = 1;
- private static final int POSITION_OCTET_3 = 2;
- private static final int POSITION_OCTET_4 = 3;
- private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255";
- private static final String DEFAULT_IPV6_ARBITRARY_BIT_MASK = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
- private static final String PREFIX_SEPARATOR = "/";
- private static final int IPV4_ADDRESS_LENGTH = 32;
- private static final int IPV6_ADDRESS_LENGTH = 128;
- private static final int BYTE_SIZE = 8;
- private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff";
-
- /*
- * Custom EthernetMatch is required because mac address string provided by user in EthernetMatch can be in any case
- * (upper or lower or mix). Ethernet Match which controller receives from switch is always an upper case string.
- * Default EthernetMatch equals doesn't use equalsIgnoreCase() and hence it fails. E.g User provided mac address
- * string in flow match is aa:bb:cc:dd:ee:ff and when controller fetch statistic data, openflow driver library
- * returns AA:BB:CC:DD:EE:FF and default eqauls fails here.
- */
- @VisibleForTesting
- static boolean ethernetMatchEquals(final EthernetMatch statsEthernetMatch, final EthernetMatch storedEthernetMatch) {
- boolean verdict = true;
- final Boolean checkNullValues = checkNullValues(statsEthernetMatch, storedEthernetMatch);
- if (checkNullValues != null) {
- verdict = checkNullValues;
- } else {
- verdict = ethernetMatchFieldsEquals(statsEthernetMatch.getEthernetSource(),
- storedEthernetMatch.getEthernetSource());
- if (verdict) {
- verdict = ethernetMatchFieldsEquals(statsEthernetMatch.getEthernetDestination(),
- storedEthernetMatch.getEthernetDestination());
- }
- if (verdict) {
- if (statsEthernetMatch.getEthernetType() == null) {
- if (storedEthernetMatch.getEthernetType() != null) {
- verdict = false;
- }
- } else {
- verdict = statsEthernetMatch.getEthernetType().equals(storedEthernetMatch.getEthernetType());
- }
- }
- }
- return verdict;
- }
-
- static boolean ethernetMatchFieldsEquals(final MacAddressFilter statsEthernetMatchFields,
- final MacAddressFilter storedEthernetMatchFields) {
- boolean verdict = true;
- final Boolean checkNullValues = checkNullValues(statsEthernetMatchFields, storedEthernetMatchFields);
- if (checkNullValues != null) {
- verdict = checkNullValues;
- } else {
- verdict = macAddressEquals(statsEthernetMatchFields.getAddress(), storedEthernetMatchFields.getAddress());
- if (verdict) {
- verdict = macAddressMaskEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask());
- }
- }
- return verdict;
- }
-
- static boolean macAddressEquals(final MacAddress statsMacAddress, final MacAddress storedMacAddress) {
- boolean verdict = true;
- final Boolean checkNullValues = checkNullValues(statsMacAddress, storedMacAddress);
- if (checkNullValues != null) {
- verdict = checkNullValues;
- } else {
- verdict = statsMacAddress.getValue().equalsIgnoreCase(storedMacAddress.getValue());
- }
- return verdict;
- }
-
- static boolean macAddressMaskEquals(final MacAddress statsMacAddressMask, final MacAddress storedMacAddressMask) {
- boolean verdict = true;
- //User sent the mask with all bit set, which actually means no mask. Switch might just ignore it.
- if(statsMacAddressMask == null && storedMacAddressMask != null &&
- storedMacAddressMask.getValue().equalsIgnoreCase(NO_ETH_MASK)) {
- return verdict;
- }
- final Boolean checkNullValues = checkNullValues(statsMacAddressMask, storedMacAddressMask);
- if (checkNullValues != null) {
- verdict = checkNullValues;
- } else {
- verdict = statsMacAddressMask.getValue().equalsIgnoreCase(storedMacAddressMask.getValue());
- }
- return verdict;
- }
-
- @VisibleForTesting
- static boolean layer3MatchEquals(final Layer3Match statsLayer3Match, final Layer3Match storedLayer3Match) {
- boolean verdict = true;
- if (statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4Match) {
- final Ipv4Match statsIpv4Match = (Ipv4Match) statsLayer3Match;
- final Ipv4Match storedIpv4Match = (Ipv4Match) storedLayer3Match;
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(storedIpv4Match.getIpv4Destination(),
- statsIpv4Match.getIpv4Destination());
- if (verdict) {
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(statsIpv4Match.getIpv4Source(),
- storedIpv4Match.getIpv4Source());
- }
- } else if (statsLayer3Match instanceof Ipv6Match && storedLayer3Match instanceof Ipv6Match) {
- final Ipv6Match statsIpv6Match = (Ipv6Match) statsLayer3Match;
- final Ipv6Match storedIpv6Match = (Ipv6Match) storedLayer3Match;
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(storedIpv6Match.getIpv6Destination(),
- statsIpv6Match.getIpv6Destination());
- if (verdict) {
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(statsIpv6Match.getIpv6Source(),
- storedIpv6Match.getIpv6Source());
- }
- } else if (statsLayer3Match instanceof Ipv4MatchArbitraryBitMask && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
- // At this moment storedIpv4MatchArbitraryBitMask & statsIpv4MatchArbitraryBitMask will always have non null arbitrary masks.
- // In case of no / null arbitrary mask, statsLayer3Match will be an instance of Ipv4Match.
- // Eg:- stats -> 1.0.1.0/255.0.255.0 stored -> 1.1.1.0/255.0.255.0
- final Ipv4MatchArbitraryBitMask statsIpv4MatchArbitraryBitMask= (Ipv4MatchArbitraryBitMask) statsLayer3Match;
- final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
- if ((storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null |
- storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null)) {
- if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
- String storedDstIpAddress = normalizeIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(),
- storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
- String statsDstIpAddress = normalizeIpv4Address(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(),
- statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
- if (MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue(),
- statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue())) {
- verdict = MatchComparatorHelper.compareStringNullSafe(storedDstIpAddress,
- statsDstIpAddress);
- } else {
- verdict = false;
- return verdict;
- }
- }
- if (storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
- String storedSrcIpAddress = normalizeIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask()
- ,storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
- String statsSrcIpAddress = normalizeIpv4Address(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask()
- ,statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
- if (MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue(),
- statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue())) {
- verdict = MatchComparatorHelper.compareStringNullSafe(storedSrcIpAddress,
- statsSrcIpAddress);
- } else {
- verdict = false;
- }
- }
- } else {
- final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
- if (nullCheckOut != null) {
- verdict = nullCheckOut;
- } else {
- verdict = storedLayer3Match.equals(statsLayer3Match);
- }
- }
- } else if (statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
- // Here stored netmask is an instance of Ipv4MatchArbitraryBitMask, when it is pushed in to switch
- // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
- // Eg:- stats src/dest -> 1.1.1.0/24 stored src/dest -> 1.1.1.0/255.255.255.0
- final Ipv4Match statsIpv4Match = (Ipv4Match) statsLayer3Match;
- final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
- if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
- Ipv4Prefix ipv4PrefixDestination;
- if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask() != null) {
- byte[] destByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
- ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(), destByteMask);
- } else {
- ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixDestination, statsIpv4Match.getIpv4Destination());
- if (verdict == false) {
- return verdict;
- }
- }
- if (storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
- Ipv4Prefix ipv4PrefixSource;
- if (storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask() != null) {
- byte[] srcByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
- ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask(), srcByteMask);
- } else {
- ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixSource, statsIpv4Match.getIpv4Source());
- }
- } else if (statsLayer3Match instanceof Ipv4MatchArbitraryBitMask && storedLayer3Match instanceof Ipv4Match) {
- // Here stored netmask is an instance of Ipv4MatchArbitraryBitMask, when it is pushed in to switch
- // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
- // Eg:- stats src/dest -> 1.1.1.0/24 stored src/dest -> 1.1.1.0/255.255.255.0
- final Ipv4Match storedIpv4Match = (Ipv4Match) storedLayer3Match;
- final Ipv4MatchArbitraryBitMask statsIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) statsLayer3Match;
- if (statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
- Ipv4Prefix ipv4PrefixDestination;
- if (statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask() != null) {
- byte[] destByteMask = convertArbitraryMaskToByteArray(statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
- ipv4PrefixDestination = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(), destByteMask);
- } else {
- ipv4PrefixDestination = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixDestination, storedIpv4Match.getIpv4Destination());
- if (verdict == false) {
- return verdict;
- }
- }
- if (statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
- Ipv4Prefix ipv4PrefixSource;
- if (statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask() != null) {
- byte[] srcByteMask = convertArbitraryMaskToByteArray(statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
- ipv4PrefixSource = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask(), srcByteMask);
- } else {
- ipv4PrefixSource = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixSource, storedIpv4Match.getIpv4Source());
- }
- } else if (statsLayer3Match instanceof Ipv6MatchArbitraryBitMask && storedLayer3Match instanceof Ipv6MatchArbitraryBitMask) {
- // At this moment storedIpv6MatchArbitraryBitMask & statsIpv6MatchArbitraryBitMask will always have non null arbitrary masks.
- // In case of no / null arbitrary mask, statsLayer3Match will be an instance of Ipv6Match.
- // Eg:- stats src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:0000:FFFF:FFFF:FFF0
- // stored src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:0000:FFFF:FFFF:FFF0
- final Ipv6MatchArbitraryBitMask statsIpv6MatchArbitraryBitMask= (Ipv6MatchArbitraryBitMask) statsLayer3Match;
- final Ipv6MatchArbitraryBitMask storedIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) storedLayer3Match;
- if ((storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null |
- storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null)) {
- if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
- String storedDstIpAddress = normalizeIpv6Address(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(),
- storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
- String statsDstIpAddress = normalizeIpv6Address(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(),
- statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
- String storedDstMask = extractIpv6CanonicalForm(storedIpv6MatchArbitraryBitMask.
- getIpv6DestinationArbitraryBitmask().getValue()).getHostAddress();
- String statsDstMask = extractIpv6CanonicalForm(statsIpv6MatchArbitraryBitMask.
- getIpv6DestinationArbitraryBitmask().getValue()).getHostAddress();
- if (MatchComparatorHelper.compareStringNullSafe(storedDstMask,statsDstMask)) {
- verdict = MatchComparatorHelper.compareStringNullSafe(storedDstIpAddress,
- statsDstIpAddress);
- } else {
- verdict = false;
- return verdict;
- }
- }
- if (storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
- String storedSrcIpAddress = normalizeIpv6Address(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask()
- ,storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
- String statsSrcIpAddress = normalizeIpv6Address(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask()
- ,statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
- String storedSrcMask = extractIpv6CanonicalForm(storedIpv6MatchArbitraryBitMask.
- getIpv6SourceArbitraryBitmask().getValue()).getHostAddress();
- String statsSrcMask = extractIpv6CanonicalForm(statsIpv6MatchArbitraryBitMask.
- getIpv6SourceArbitraryBitmask().getValue()).getHostAddress();
- if (MatchComparatorHelper.compareStringNullSafe(storedSrcMask, statsSrcMask)) {
- verdict = MatchComparatorHelper.compareStringNullSafe(storedSrcIpAddress,
- statsSrcIpAddress);
- } else {
- verdict = false;
- }
- }
- } else {
- final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
- if (nullCheckOut != null) {
- verdict = nullCheckOut;
- } else {
- verdict = storedLayer3Match.equals(statsLayer3Match);
- }
- }
- } else if (statsLayer3Match instanceof Ipv6Match && storedLayer3Match instanceof Ipv6MatchArbitraryBitMask) {
- // Here stored netmask is an instance of Ipv6MatchArbitraryBitMask, when it is pushed in to switch
- // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
- // Eg:- stats src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/124
- // stored src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFF0
- final Ipv6Match statsIpv6Match = (Ipv6Match) statsLayer3Match;
- final Ipv6MatchArbitraryBitMask storedIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) storedLayer3Match;
- if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
- Ipv6Prefix ipv6PrefixDestination;
- if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask() != null) {
- byte[] destByteMask = convertIpv6ArbitraryMaskToByteArray(storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
- ipv6PrefixDestination = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(), destByteMask);
- } else {
- ipv6PrefixDestination = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixDestination, statsIpv6Match.getIpv6Destination());
- if (verdict == false) {
- return verdict;
- }
- }
- if (storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
- Ipv6Prefix ipv6PrefixSource;
- if (storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask() != null) {
- byte[] srcByteMask = convertIpv6ArbitraryMaskToByteArray(storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
- ipv6PrefixSource = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask(), srcByteMask);
- } else {
- ipv6PrefixSource = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixSource, statsIpv6Match.getIpv6Source());
- }
- } else if (statsLayer3Match instanceof Ipv6MatchArbitraryBitMask && storedLayer3Match instanceof Ipv6Match) {
- // Here stored netmask is an instance of Ipv6MatchArbitraryBitMask, when it is pushed in to switch
- // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
- // Eg:- stats src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/124
- // stored src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFF0
- final Ipv6Match storedIpv6Match = (Ipv6Match) storedLayer3Match;
- final Ipv6MatchArbitraryBitMask statsIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) statsLayer3Match;
- if (statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
- Ipv6Prefix ipv6PrefixDestination;
- if (statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask() != null) {
- byte[] destByteMask = convertIpv6ArbitraryMaskToByteArray(statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
- ipv6PrefixDestination = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(), destByteMask);
- } else {
- ipv6PrefixDestination = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixDestination, storedIpv6Match.getIpv6Destination());
- if (verdict == false) {
- return verdict;
- }
- }
- if (statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
- Ipv6Prefix ipv6PrefixSource;
- if (statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask() != null) {
- byte[] srcByteMask = convertIpv6ArbitraryMaskToByteArray(statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
- ipv6PrefixSource = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask(), srcByteMask);
- } else {
- ipv6PrefixSource = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask());
- }
- verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixSource, storedIpv6Match.getIpv6Source());
- }
- } else if (statsLayer3Match instanceof ArpMatch && storedLayer3Match instanceof ArpMatch) {
- verdict = arpMatchEquals((ArpMatch)statsLayer3Match, (ArpMatch)storedLayer3Match);
- } else {
- final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
- if (nullCheckOut != null) {
- verdict = nullCheckOut;
- } else {
- verdict = storedLayer3Match.equals(statsLayer3Match);
- }
- }
- return verdict;
- }
-
- static boolean arpMatchEquals(final ArpMatch statsArpMatch, final ArpMatch storedArpMatch) {
-
- Integer statsOp = statsArpMatch.getArpOp();
- Integer storedOp = storedArpMatch.getArpOp();
-
- Boolean nullCheck = checkNullValues(statsOp, storedOp);
- if (nullCheck != null) {
- if (nullCheck == false) {
- return false;
- }
- } else if (!statsOp.equals(storedOp)) {
- return false;
- }
-
- Ipv4Prefix statsIp = statsArpMatch.getArpSourceTransportAddress();
- Ipv4Prefix storedIp = storedArpMatch.getArpSourceTransportAddress();
- if (!compareIpv4PrefixNullSafe(statsIp, storedIp)) {
- return false;
- }
-
- statsIp = statsArpMatch.getArpTargetTransportAddress();
- storedIp = storedArpMatch.getArpTargetTransportAddress();
- if (!compareIpv4PrefixNullSafe(statsIp, storedIp)) {
- return false;
- }
-
- MacAddressFilter statsMac = statsArpMatch.getArpSourceHardwareAddress();
- MacAddressFilter storedMac = storedArpMatch.getArpSourceHardwareAddress();
- if (!ethernetMatchFieldsEquals(statsMac, storedMac)) {
- return false;
- }
-
- statsMac = statsArpMatch.getArpTargetHardwareAddress();
- storedMac = storedArpMatch.getArpTargetHardwareAddress();
- if (!ethernetMatchFieldsEquals(statsMac, storedMac)) {
- return false;
- }
-
- return true;
- }
-
-
- /**
- * TODO: why don't we use the default Ipv4Prefix.equals()?
- *
- * @param statsIpAddress
- * @param storedIpAddress
- * @return true if IPv4prefixes equals
- */
- static boolean IpAddressEquals(final Ipv4Prefix statsIpAddress, final Ipv4Prefix storedIpAddress) {
- final IntegerIpAddress statsIpAddressInt = MatchComparatorHelper.strIpToIntIp(statsIpAddress.getValue());
- final IntegerIpAddress storedIpAddressInt = MatchComparatorHelper.strIpToIntIp(storedIpAddress.getValue());
-
- if (ipAndMaskBasedMatch(statsIpAddressInt, storedIpAddressInt)) {
- return true;
- }
- if (ipBasedMatch(statsIpAddressInt, storedIpAddressInt)) {
- return true;
- }
- return false;
- }
-
- static boolean ipAndMaskBasedMatch(final IntegerIpAddress statsIpAddressInt,
- final IntegerIpAddress storedIpAddressInt) {
- return ((statsIpAddressInt.getIp() & statsIpAddressInt.getMask()) == (storedIpAddressInt.getIp() & storedIpAddressInt
- .getMask()));
- }
-
- static boolean ipBasedMatch(final IntegerIpAddress statsIpAddressInt, final IntegerIpAddress storedIpAddressInt) {
- return (statsIpAddressInt.getIp() == storedIpAddressInt.getIp());
- }
-
-
- private static boolean IpAddressEquals(Ipv6Prefix statsIpv6, Ipv6Prefix storedIpv6) {
- final String[] statsIpMask = statsIpv6.getValue().split("/");
- final String[] storedIpMask = storedIpv6.getValue().split("/");
- if (! (statsIpMask.length > 1 && storedIpMask.length > 1 && statsIpMask[1].equals(storedIpMask[1]))){
- return false;
- }
-
- final int prefix = Integer.parseInt(statsIpMask[1]);
- final int byteIndex = prefix/BYTE_SIZE;
- final int lastByteBits = BYTE_SIZE - (prefix % BYTE_SIZE);
- final InetAddress statsIp = InetAddresses.forString(statsIpMask[0]);
- final InetAddress storedIp = InetAddresses.forString(storedIpMask[0]);
- byte[] statsIpArr = Arrays.copyOfRange(statsIp.getAddress(),0,byteIndex+1);
- byte[] storedIpArr = Arrays.copyOfRange(storedIp.getAddress(),0,byteIndex+1);
- statsIpArr[byteIndex] = (byte) (statsIpArr[byteIndex] & (0XFF << lastByteBits));
- storedIpArr[byteIndex] = (byte) (storedIpArr[byteIndex] & (0XFF << lastByteBits));
- if(Arrays.equals(statsIpArr,storedIpArr)) {
- return true;
- }
- return false;
- }
-
- static Boolean checkNullValues(final Object v1, final Object v2) {
- Boolean verdict = null;
- if (v1 == null && v2 != null) {
- verdict = Boolean.FALSE;
- } else if (v1 != null && v2 == null) {
- verdict = Boolean.FALSE;
- } else if (v1 == null && v2 == null) {
- verdict = Boolean.TRUE;
- }
- return verdict;
- }
-
- static boolean compareIpv4PrefixNullSafe(final Ipv4Prefix statsIpv4, final Ipv4Prefix storedIpv4) {
- boolean verdict = true;
- final Boolean checkDestNullValuesOut = checkNullValues(storedIpv4, statsIpv4);
- if (checkDestNullValuesOut != null) {
- verdict = checkDestNullValuesOut;
- } else if (!IpAddressEquals(statsIpv4, storedIpv4)) {
- verdict = false;
- }
- return verdict;
- }
-
- static boolean compareStringNullSafe(final String stringA, final String stringB) {
- boolean verdict = true;
- final Boolean checkDestNullValuesOut = checkNullValues(stringA,stringB);
- if (checkDestNullValuesOut != null) {
- verdict = checkDestNullValuesOut;
- } else if (!stringA.equals(stringB)) {
- verdict = false;
- }
- return verdict;
- }
-
- private static boolean compareIpv6PrefixNullSafe(Ipv6Prefix statsIpv6, Ipv6Prefix storedIpv6) {
- boolean verdict = true;
- final Boolean checkDestNullValuesOut = checkNullValues(statsIpv6, storedIpv6);
- if (checkDestNullValuesOut != null) {
- verdict = checkDestNullValuesOut;
- } else if (!IpAddressEquals(statsIpv6, storedIpv6)) {
- verdict = false;
- }
- return verdict;
- }
-
- /**
- * Method return integer version of ip address. Converted int will be mask if mask specified
- */
- static IntegerIpAddress strIpToIntIp(final String ipAddresss) {
-
- final String[] parts = ipAddresss.split("/");
- final String ip = parts[0];
- int prefix;
-
- if (parts.length < 2) {
- prefix = DEFAULT_SUBNET;
- } else {
- prefix = Integer.parseInt(parts[1]);
- if (prefix < 0 || prefix > IPV4_MASK_LENGTH) {
- final StringBuilder stringBuilder = new StringBuilder(
- "Valid values for mask are from range 0 - 32. Value ");
- stringBuilder.append(prefix);
- stringBuilder.append(" is invalid.");
- throw new IllegalStateException(stringBuilder.toString());
- }
- }
-
- IntegerIpAddress integerIpAddress = null;
-
- final Inet4Address addr = ((Inet4Address) InetAddresses.forString(ip));
- final byte[] addrBytes = addr.getAddress();
- // FIXME: what is meaning of anding with 0xFF? Probably could be removed.
- final int ipInt = ((addrBytes[POSITION_OCTET_1] & 0xFF) << SHIFT_OCTET_1)
- | ((addrBytes[POSITION_OCTET_2] & 0xFF) << SHIFT_OCTET_2)
- | ((addrBytes[POSITION_OCTET_3] & 0xFF) << SHIFT_OCTET_3)
- | ((addrBytes[POSITION_OCTET_4] & 0xFF) << SHIFT_OCTET_4);
-
- // FIXME: Is this valid?
- final int mask = 0xffffffff << DEFAULT_SUBNET - prefix;
-
- integerIpAddress = new IntegerIpAddress(ipInt, mask);
-
- return integerIpAddress;
- }
-
- static boolean isArbitraryBitMask(byte[] byteMask) {
- if (byteMask == null) {
- return false;
- } else {
- ArrayList<Integer> integerMaskArrayList = new ArrayList<Integer>();
- String maskInBits;
- // converting byte array to bits
- maskInBits = new BigInteger(1, byteMask).toString(2);
- ArrayList<String> stringMaskArrayList = new ArrayList<String>(Arrays.asList(maskInBits.split("(?!^)")));
- for(String string:stringMaskArrayList){
- integerMaskArrayList.add(Integer.parseInt(string));
- }
- return checkArbitraryBitMask(integerMaskArrayList);
- }
- }
-
- static boolean checkArbitraryBitMask(ArrayList<Integer> arrayList) {
- if (arrayList.size()>0 && arrayList.size()< IPV4_MASK_LENGTH ) {
- // checks 0*1* case - Leading zeros in arrayList are truncated
- return true;
- } else {
- //checks 1*0*1 case
- for(int i=0; i<arrayList.size()-1;i++) {
- if(arrayList.get(i) ==0 && arrayList.get(i+1) == 1) {
- return true;
- }
- }
- }
- return false;
- }
-
- static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) {
- String maskValue;
- if (mask.getValue() != null) {
- maskValue = mask.getValue();
- } else {
- maskValue = DEFAULT_ARBITRARY_BIT_MASK;
- }
- InetAddress maskInIpFormat = null;
- try {
- maskInIpFormat = InetAddress.getByName(maskValue);
- } catch (UnknownHostException e) {
- LOG.error("Failed to recognize the host while converting mask ", e);
- }
- byte[] bytes = maskInIpFormat.getAddress();
- return bytes;
- }
-
- private static final byte[] convertIpv6ArbitraryMaskToByteArray ( final Ipv6ArbitraryMask mask) {
- String maskValue;
- if (mask.getValue() != null) {
- maskValue = mask.getValue();
- } else {
- maskValue = DEFAULT_IPV6_ARBITRARY_BIT_MASK;
- }
- InetAddress maskInIpv6Format = null;
- try {
- maskInIpv6Format = InetAddress.getByName(maskValue);
- } catch (UnknownHostException e) {
- LOG.error("Failed to convert string mask value to ipv6 format ", e);
- }
- return maskInIpv6Format.getAddress();
- }
-
- static String normalizeIpv4Address(Ipv4Address ipAddress, DottedQuad netMask) {
- String actualIpAddress="";
- String[] netMaskParts = netMask.getValue().split("\\.");
- String[] ipAddressParts = ipAddress.getValue().split("\\.");
-
- for (int i=0; i<ipAddressParts.length;i++) {
- int integerFormatIpAddress=Integer.parseInt(ipAddressParts[i]);
- int integerFormatNetMask=Integer.parseInt(netMaskParts[i]);
- int ipAddressPart=(integerFormatIpAddress) & (integerFormatNetMask);
- actualIpAddress += ipAddressPart;
- if (i != ipAddressParts.length -1 ) {
- actualIpAddress = actualIpAddress+".";
- }
- }
- return actualIpAddress;
- }
-
- private static String normalizeIpv6Address(final Ipv6Address ipAddress, final Ipv6ArbitraryMask netMask) {
- byte[] ipAddressParts = convertIpv6ToBytes(ipAddress.getValue());
- byte[] netMaskParts = convertIpv6ToBytes(netMask.getValue());
- byte[] actualIpv6Bytes = new byte[16];
-
- for (int i=0; i<ipAddressParts.length;i++) {
- byte ipAddressPart= (byte) (ipAddressParts[i] & netMaskParts[i]);
- actualIpv6Bytes[i] = ipAddressPart;
- }
- InetAddress ipv6Address = null;
- try {
- ipv6Address = InetAddress.getByAddress(actualIpv6Bytes);
- } catch (UnknownHostException e) {
- LOG.error("Failed to recognize the host while normalizing IPv6 address from bytes ", e);
- }
- return ipv6Address.getHostAddress();
- }
-
- private static byte[] convertIpv6ToBytes(final String ipv6Address) {
- return extractIpv6CanonicalForm(ipv6Address).getAddress();
- }
-
- private static InetAddress extractIpv6CanonicalForm(final String ipv6Address) {
- InetAddress address = null;
- try {
- address = InetAddress.getByName(ipv6Address);
- } catch (UnknownHostException e) {
- LOG.error("Failed to recognize the host while converting IPv6 to bytes ", e);
- }
- return address;
- }
-
- static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final byte [] bytemask){
- return createPrefix(ipv4Address, String.valueOf(countBits(bytemask)));
- }
-
- private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final byte [] bytemask) {
- return createPrefix(ipv6Address, String.valueOf(countBits(bytemask)));
- }
-
- private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final String mask) {
- if (mask != null && !mask.isEmpty()) {
- return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + mask);
- } else {
- return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + IPV6_ADDRESS_LENGTH);
- }
- }
-
- private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address) {
- return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + IPV6_ADDRESS_LENGTH);
- }
-
- static int countBits(final byte[] mask) {
- int netmask = 0;
- for (byte b : mask) {
- netmask += Integer.bitCount(UnsignedBytes.toInt(b));
- }
- return netmask;
- }
-
- static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address){
- return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
- }
-
- static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final String mask){
- /*
- * Ipv4Address has already validated the address part of the prefix,
- * It is mandated to comply to the same regexp as the address
- * There is absolutely no point rerunning additional checks vs this
- * Note - there is no canonical form check here!!!
- */
- if (null != mask && !mask.isEmpty()) {
- return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + mask);
- } else {
- return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
- }
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.util;
+
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv4Arbitrary;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv4Prefix;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6AddressWithoutMask;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6Arbitrary;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6Prefix;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeMacAddress;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeMacAddressMask;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeProtocolAgnosticPort;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.extension.api.GroupingLooseResolver;
+import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralExtensionListGrouping;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+/**
+ * Utility class for match normalization
+ */
+public final class MatchNormalizationUtil {
+ // Cache normalizers for common OpenFlow versions
+ private static final Map<Short, Set<Function<MatchBuilder, MatchBuilder>>> NORMALIZERS = ImmutableMap
+ .<Short, Set<Function<MatchBuilder, MatchBuilder>>>builder()
+ .put(OFConstants.OFP_VERSION_1_0, createNormalizers(OFConstants.OFP_VERSION_1_0).collect(Collectors.toSet()))
+ .put(OFConstants.OFP_VERSION_1_3, createNormalizers(OFConstants.OFP_VERSION_1_3).collect(Collectors.toSet()))
+ .build();
+
+ private MatchNormalizationUtil() {
+ throw new RuntimeException("Creating instance of util classes is prohibited");
+ }
+
+ /**
+ * Normalize match.
+ *
+ * @param match the OpenFlow match
+ * @param version the OpenFlow version
+ * @return normalized OpenFlow match
+ */
+ @Nonnull
+ public static Match normalizeMatch(@Nonnull final Match match, final short version) {
+ final MatchBuilder matchBuilder = new MatchBuilder(match);
+
+ Optional.ofNullable(NORMALIZERS.get(version))
+ .orElseGet(() -> createNormalizers(version).collect(Collectors.toSet()))
+ .forEach(normalizer -> normalizer.apply(matchBuilder));
+
+ return matchBuilder.build();
+ }
+
+ @Nonnull
+ private static Stream<Function<MatchBuilder, MatchBuilder>> createNormalizers(final short version) {
+ return Stream.of(
+ MatchNormalizationUtil::normalizeExtensionMatch,
+ MatchNormalizationUtil::normalizeEthernetMatch,
+ MatchNormalizationUtil::normalizeArpMatch,
+ MatchNormalizationUtil::normalizeTunnelIpv4Match,
+ MatchNormalizationUtil::normalizeIpv4Match,
+ MatchNormalizationUtil::normalizeIpv4MatchArbitraryBitMask,
+ MatchNormalizationUtil::normalizeIpv6Match,
+ MatchNormalizationUtil::normalizeIpv6MatchArbitraryBitMask,
+ (match) -> normalizeInPortMatch(match, version),
+ (match) -> normalizeInPhyPortMatch(match, version));
+ }
+
+ @Nonnull
+ @SuppressWarnings("unchecked")
+ private static MatchBuilder normalizeExtensionMatch(@Nonnull final MatchBuilder match) {
+ final GroupingLooseResolver<GeneralExtensionListGrouping> matchExtensionResolver =
+ ExtensionResolvers.getMatchExtensionResolver();
+
+ return matchExtensionResolver
+ .getExtension(match.build())
+ .flatMap(statExt -> Optional.ofNullable(statExt.getExtensionList()))
+ .map(extensionLists -> {
+ matchExtensionResolver.getClasses().forEach(aClass -> match
+ .removeAugmentation((Class<? extends Augmentation<Match>>) aClass));
+
+ return match.addAugmentation(
+ GeneralAugMatchNotifUpdateFlowStats.class,
+ new GeneralAugMatchNotifUpdateFlowStatsBuilder()
+ .setExtensionList(extensionLists)
+ .build());
+ })
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeInPortMatch(@Nonnull final MatchBuilder match, final short version) {
+ return Optional
+ .ofNullable(match.getInPort())
+ .flatMap(inPort -> Optional.ofNullable(normalizeProtocolAgnosticPort(inPort, version)))
+ .map(inPortUri -> match.setInPort(new NodeConnectorId(inPortUri)))
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeInPhyPortMatch(@Nonnull final MatchBuilder match, final short version) {
+ return Optional
+ .ofNullable(match.getInPhyPort())
+ .flatMap(inPhyPort -> Optional.ofNullable(normalizeProtocolAgnosticPort(inPhyPort, version)))
+ .map(inPhyPortUri -> match.setInPhyPort(new NodeConnectorId(inPhyPortUri)))
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeArpMatch(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(ArpMatch.class::isInstance)
+ .map(ArpMatch.class::cast)
+ .map(arp -> match.setLayer3Match(new ArpMatchBuilder(arp)
+ .setArpSourceHardwareAddress(Optional
+ .ofNullable(arp.getArpSourceHardwareAddress())
+ .map(arpSource -> new ArpSourceHardwareAddressBuilder(arpSource)
+ .setAddress(normalizeMacAddress(arpSource.getAddress()))
+ .setMask(normalizeMacAddress(arpSource.getMask()))
+ .build())
+ .orElse(arp.getArpSourceHardwareAddress()))
+ .setArpTargetHardwareAddress(Optional
+ .ofNullable(arp.getArpTargetHardwareAddress())
+ .map(arpTarget -> new ArpTargetHardwareAddressBuilder(arpTarget)
+ .setAddress(normalizeMacAddress(arpTarget.getAddress()))
+ .setMask(normalizeMacAddress(arpTarget.getMask()))
+ .build())
+ .orElse(arp.getArpTargetHardwareAddress()))
+ .setArpSourceTransportAddress(normalizeIpv4Prefix(arp.getArpSourceTransportAddress()))
+ .setArpTargetTransportAddress(normalizeIpv4Prefix(arp.getArpTargetTransportAddress()))
+ .build())
+ )
+ .orElse(match);
+ }
+
+
+ @Nonnull
+ private static MatchBuilder normalizeTunnelIpv4Match(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(TunnelIpv4Match.class::isInstance)
+ .map(TunnelIpv4Match.class::cast)
+ .map(tunnelIpv4 -> match.setLayer3Match(new TunnelIpv4MatchBuilder(tunnelIpv4)
+ .setTunnelIpv4Source(normalizeIpv4Prefix(tunnelIpv4.getTunnelIpv4Source()))
+ .setTunnelIpv4Destination(normalizeIpv4Prefix(tunnelIpv4.getTunnelIpv4Destination()))
+ .build()))
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeIpv4Match(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(Ipv4Match.class::isInstance)
+ .map(Ipv4Match.class::cast)
+ .map(ipv4 -> match.setLayer3Match(new Ipv4MatchBuilder(ipv4)
+ .setIpv4Source(normalizeIpv4Prefix(ipv4.getIpv4Source()))
+ .setIpv4Destination(normalizeIpv4Prefix(ipv4.getIpv4Destination()))
+ .build()))
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeIpv4MatchArbitraryBitMask(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(Ipv4MatchArbitraryBitMask.class::isInstance)
+ .map(Ipv4MatchArbitraryBitMask.class::cast)
+ .map(ipv4arbitrary -> match.setLayer3Match(new Ipv4MatchBuilder()
+ .setIpv4Source(normalizeIpv4Arbitrary(
+ ipv4arbitrary.getIpv4SourceAddressNoMask(),
+ ipv4arbitrary.getIpv4SourceArbitraryBitmask()))
+ .setIpv4Destination(normalizeIpv4Arbitrary(
+ ipv4arbitrary.getIpv4DestinationAddressNoMask(),
+ ipv4arbitrary.getIpv4DestinationArbitraryBitmask()))
+ .build()))
+ .orElse(match);
+ }
+
+
+ @Nonnull
+ private static MatchBuilder normalizeIpv6Match(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(Ipv6Match.class::isInstance)
+ .map(Ipv6Match.class::cast)
+ .map(ipv6 -> match.setLayer3Match(new Ipv6MatchBuilder(ipv6)
+ .setIpv6NdSll(normalizeMacAddress(ipv6.getIpv6NdSll()))
+ .setIpv6NdTll(normalizeMacAddress(ipv6.getIpv6NdTll()))
+ .setIpv6NdTarget(normalizeIpv6AddressWithoutMask(ipv6.getIpv6NdTarget()))
+ .setIpv6Source(normalizeIpv6Prefix(ipv6.getIpv6Source()))
+ .setIpv6Destination(normalizeIpv6Prefix(ipv6.getIpv6Destination()))
+ .build()))
+ .orElse(match);
+ }
+
+
+ @Nonnull
+ private static MatchBuilder normalizeIpv6MatchArbitraryBitMask(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getLayer3Match())
+ .filter(Ipv6MatchArbitraryBitMask.class::isInstance)
+ .map(Ipv6MatchArbitraryBitMask.class::cast)
+ .map(ipv6Arbitrary -> match.setLayer3Match(new Ipv6MatchBuilder()
+ .setIpv6Source(normalizeIpv6Arbitrary(
+ ipv6Arbitrary.getIpv6SourceAddressNoMask(),
+ ipv6Arbitrary.getIpv6SourceArbitraryBitmask()))
+ .setIpv6Destination(normalizeIpv6Arbitrary(
+ ipv6Arbitrary.getIpv6DestinationAddressNoMask(),
+ ipv6Arbitrary.getIpv6DestinationArbitraryBitmask()))
+ .build()))
+ .orElse(match);
+ }
+
+ @Nonnull
+ private static MatchBuilder normalizeEthernetMatch(@Nonnull final MatchBuilder match) {
+ return Optional
+ .ofNullable(match.getEthernetMatch())
+ .map(eth -> match.setEthernetMatch(new EthernetMatchBuilder(eth)
+ .setEthernetSource(Optional
+ .ofNullable(eth.getEthernetSource())
+ .map(filter -> new EthernetSourceBuilder(filter)
+ .setAddress(normalizeMacAddress(filter.getAddress()))
+ .setMask(normalizeMacAddressMask(filter.getMask()))
+ .build())
+ .orElse(eth.getEthernetSource()))
+ .setEthernetDestination(Optional
+ .ofNullable(eth.getEthernetDestination())
+ .map(filter -> new EthernetDestinationBuilder(filter)
+ .setAddress(normalizeMacAddress(filter.getAddress()))
+ .setMask(normalizeMacAddressMask(filter.getMask()))
+ .build())
+ .orElse(eth.getEthernetDestination()))
+ .build()))
+ .orElse(match);
+ }
+
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013, 2015 IBM Corporation and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.util;
-
-public interface SimpleComparator<T> {
-
- boolean areObjectsEqual(short version, T obj1, T obj2);
-
-}
@Test
public void testRemoveDescriptor() throws Exception {
deviceFlowRegistry.addMark(key);
- Assert.assertEquals(1, deviceFlowRegistry.getAllFlowDescriptors().size());
+ Assert.assertEquals(0, deviceFlowRegistry.getAllFlowDescriptors().size());
}
@Test
Assert.assertNotNull(flowDescriptor.getTableKey());
}
- @Test(expected = NullPointerException.class)
+ @Test(expected = Exception.class)
public void testCreateNegative1() throws Exception {
FlowDescriptorFactory.create((short) 1, null);
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
+
+public class AddressNormalizationUtilTest {
+
+ @Test
+ public void normalizeProtocolAgnosticPortOF10() throws Exception {
+ final Uri left = new Uri("openflow:1:INPORT");
+ final Uri right = new Uri("INPORT");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeProtocolAgnosticPort(left, OFConstants.OFP_VERSION_1_0)
+ );
+ }
+
+ @Test
+ public void normalizeProtocolAgnosticPortOF13() throws Exception {
+ final Uri left = new Uri("openflow:1:ANY");
+ final Uri right = new Uri("ANY");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeProtocolAgnosticPort(left, OFConstants.OFP_VERSION_1_3)
+ );
+ }
+
+ @Test
+ public void normalizeIpv6Prefix() throws Exception {
+ final Ipv6Prefix left = new Ipv6Prefix("1E3D:5678:9ABC::/24");
+ final Ipv6Prefix right = new Ipv6Prefix("1e3d:5600:0:0:0:0:0:0/24");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeIpv6Prefix(left)
+ );
+ }
+
+ @Test
+ public void normalizeIpv6Arbitrary() throws Exception {
+ final Ipv6Address leftAddress = new Ipv6Address("1E3D:5678:9ABC::");
+ final Ipv6ArbitraryMask leftMask = new Ipv6ArbitraryMask("FFFF:FF00::");
+ final Ipv6Prefix right = new Ipv6Prefix("1e3d:5600:0:0:0:0:0:0/24");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeIpv6Arbitrary(leftAddress, leftMask)
+ );
+ }
+
+ @Test
+ public void normalizeIpv6AddressWithoutMask() throws Exception {
+ final Ipv6Address left = new Ipv6Address("1E3D:5678:9ABC::");
+ final Ipv6Address right = new Ipv6Address("1e3d:5678:9abc:0:0:0:0:0");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeIpv6AddressWithoutMask(left)
+ );
+ }
+
+ @Test
+ public void normalizeIpv4Prefix() throws Exception {
+ final Ipv4Prefix left = new Ipv4Prefix("192.168.72.1/16");
+ final Ipv4Prefix right = new Ipv4Prefix("192.168.0.0/16");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeIpv4Prefix(left)
+ );
+ }
+
+ @Test
+ public void normalizeIpv4Arbitrary() throws Exception {
+ final Ipv4Address leftAddress = new Ipv4Address("192.168.72.1");
+ final DottedQuad leftMask = new DottedQuad("255.255.0.0");
+ final Ipv4Prefix right = new Ipv4Prefix("192.168.0.0/16");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeIpv4Arbitrary(leftAddress, leftMask)
+ );
+ }
+
+ @Test
+ public void normalizeMacAddress() throws Exception {
+ final MacAddress left = new MacAddress("01:23:45:AB:CD:EF");
+ final MacAddress right = new MacAddress("01:23:45:ab:cd:ef");
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeMacAddress(left)
+ );
+ }
+
+ @Test
+ public void normalizeMacAddressMask() throws Exception {
+ final MacAddress left = new MacAddress("FF:FF:FF:FF:FF:FF");
+ final MacAddress right = null;
+
+ assertEquals(
+ right,
+ AddressNormalizationUtil.normalizeMacAddressMask(left)
+ );
+ }
+
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.util;
-
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMaskBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * @author sai.marapareddy@gmail.com (arbitrary masks)
- */
-
-/**
- * test of {@link MatchComparatorHelper}
- */
-public class MatchComparatorHelperTest {
-
- /**
- * mask for /32
- */
- private static final int DEFAULT_IPV4_MASK = 0xffffffff;
-
- /**
- * mask for /30
- */
- private static final int IPV4_30_MASK = 0xfffffffc;
- private static final int IP_ADDRESS = 0xC0A80101;
-
- /**
- * The test of conversion valid IP addres without mask to binary form.
- */
- @Test
- public void validIpWithoutMaskTest() {
- IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1");
- assertEquals(IP_ADDRESS, intIp.getIp());
- assertEquals(DEFAULT_IPV4_MASK, intIp.getMask());
- }
-
- /**
- * The test of conversion of valid IP address with valid mask to binary form.
- */
- @Test
- public void validIpWithValidMaskTest() {
- IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1/30");
- assertEquals(IP_ADDRESS, intIp.getIp());
- assertEquals(IPV4_30_MASK, intIp.getMask());
- }
-
- /**
- * The test of conversion of valid IP address invalid mask to binary form.
- */
- @Test
- public void validIpWithInvalidMaskTest() {
- try {
- MatchComparatorHelper.strIpToIntIp("192.168.1.1/40");
- } catch (IllegalStateException e) {
- assertEquals("Valid values for mask are from range 0 - 32. Value 40 is invalid.", e.getMessage());
- return;
- }
- fail("IllegalStateException was awaited (40 subnet is invalid)");
- }
-
- /**
- * The test of conversion invalid IP address with valid mask to binary form.
- */
- @Test
- public void invalidIpWithValidMaskTest() {
- try {
- MatchComparatorHelper.strIpToIntIp("257.168.1.1/25");
- } catch (IllegalArgumentException e) {
- assertEquals("'257.168.1.1' is not an IP string literal.", e.getMessage());
- }
- }
-
- @Test
- public void ethernetMatchEqualsTest() {
- final EthernetMatchBuilder statsEthernetBuilder = new EthernetMatchBuilder();
- final EthernetMatchBuilder storedEthernetBuilder = new EthernetMatchBuilder();
-
- assertEquals(true, MatchComparatorHelper.ethernetMatchEquals(null, null));
-
- statsEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
- new MacAddress("11:22:33:44:55:66")).build());
- storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
- new MacAddress("11:22:33:44:55:77")).build());
- assertEquals(false,
- MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
-
- storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
- new MacAddress("11:22:33:44:55:66")).build());
- statsEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
- new MacAddress("66:55:44:33:22:11")).build());
- storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
- new MacAddress("77:55:44:33:22:11")).build());
- assertEquals(false,
- MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
-
- storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
- new MacAddress("66:55:44:33:22:11")).build());
- statsEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build());
- storedEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build());
- assertEquals(true,
- MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
-
- statsEthernetBuilder.setEthernetType(null).build();
- assertEquals(false,
- MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
-
- storedEthernetBuilder.setEthernetType(null).build();
- assertEquals(true,
- MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
-
- }
-
- // Please see following bug for more details https://bugs.opendaylight.org/show_bug.cgi?id=7910
- @Test
- public void ethernetMatchWithFullMaskTest() {
- final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder();
- final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder();
-
- assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null));
-
- statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
-
- storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
- storedBuilder.setMask(new MacAddress("FF:FF:FF:FF:FF:FF"));
-
- assertEquals(true,
- MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
- }
-
- @Test
- public void ethernetMatchFieldsEqualsTest() {
- final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder();
- final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder();
-
- assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null));
-
- statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
- storedBuilder.setAddress(new MacAddress("11:22:33:44:55:77"));
- assertEquals(false,
- MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
-
- storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
- assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
- }
-
- @Test
- public void macAddressEqualsTest() {
- assertEquals(true, MatchComparatorHelper.macAddressEquals(null, null));
- assertEquals(true, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress(
- "11:22:33:44:55:66")));
- assertEquals(false, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress(
- "11:22:33:44:55:77")));
- }
-
- @Test
- public void checkNullValuesTest() {
- assertEquals(false, MatchComparatorHelper.checkNullValues(null, ""));
- assertEquals(false, MatchComparatorHelper.checkNullValues("", null));
- assertEquals(true, MatchComparatorHelper.checkNullValues(null, null));
- assertTrue(MatchComparatorHelper.checkNullValues("", "") == null);
- }
-
- @Test
- public void compareIpv4PrefixNullSafeTest() {
- assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(null, null));
- assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"),
- new Ipv4Prefix("192.168.1.1/31")));
-
- assertEquals(false, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"),
- new Ipv4Prefix("191.168.1.1/31")));
- }
-
- @Test
- public void compareStringNullSafeTest() {
- assertEquals(true, MatchComparatorHelper.compareStringNullSafe(null,null));
- assertEquals(true, MatchComparatorHelper.compareStringNullSafe("Hello", "Hello"));
- assertEquals(false, MatchComparatorHelper.compareStringNullSafe("Hello", "hello"));
- }
-
- private static final int ip_192_168_1_1 = 0xC0A80101;
- private static final int ip_192_168_1_4 = 0xC0A80104;
-
- @Test
- public void ipBasedMatchTest() {
- // are equals because only IP address is compared
- assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 32),
- new IntegerIpAddress(ip_192_168_1_1, 16)));
- }
-
- @Test
- public void ipAndMaskBasedMatchTest() {
- // true because both cases are network 192.168.1.0
- assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31),
- new IntegerIpAddress(ip_192_168_1_1, 30)));
-
- // false because first is network 192.168.1.0 and second is 192.168.1.4
- assertEquals(false, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31),
- new IntegerIpAddress(ip_192_168_1_4, 30)));
- }
-
- @Test
- public void layer3MatchEqualsTest() {
- final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
- final Ipv4MatchBuilder storedBuilder = new Ipv4MatchBuilder();
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/30"));
- storedBuilder.setIpv4Destination(new Ipv4Prefix("191.168.1.1/30"));
- assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- assertEquals(true,
- MatchComparatorHelper.layer3MatchEquals(new ArpMatchBuilder().build(), new ArpMatchBuilder().build()));
- }
-
- @Test
- public void layer3MatchEqualsIpv6Test() {
- final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
- final Ipv6MatchBuilder storedBuilder = new Ipv6MatchBuilder();
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
- statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/64"));
- storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
- statsBuilder.setIpv6Destination(new Ipv6Prefix("aabb:1234:2acf:000d:0000:0000:0000:5d99/64"));
- storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
- statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/64"));
- storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
- assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
- statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/63"));
- storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/63"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
- statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/63"));
- storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000E:0000:0000:0000:4D99/63"));
- assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- }
-
- @Test
- public void layer3MatchEqualsIpv4ArbitraryMaskTest(){
- final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
- final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/24"));
- storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
- storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.255.0"));
- statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/24"));
- storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
- storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.255.255.0"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
-
- }
-
- @Test
- public void layer3MatchEqualsIpv4ArbitraryMaskRandomTest() {
- final Ipv4MatchArbitraryBitMaskBuilder statsBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
- final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
- statsBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
- storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
- storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
- statsBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.0.0.1"));
- statsBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
- storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.7.1.1"));
- storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
- @Test
- public void layer3MatchEqualsIpv4ArbitraryMaskEqualsNullTest() {
- final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
- final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.0.1/32"));
- storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
- statsBuilder.setIpv4Destination(new Ipv4Prefix("192.1.0.0/32"));
- storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.1.0.0"));
- assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
- @Test
- public void layer3MatchEqualsIpv4ArbitraryEmptyBitMaskTest(){
- final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
- final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/32"));
- storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
- statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/32"));
- storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
- @Test
- public void extractIpv4AddressTest() {
- Ipv4Address ipAddress = new Ipv4Address("1.1.1.1");
- DottedQuad netMask = new DottedQuad("255.255.255.0");
- String extractedIpAddress;
- extractedIpAddress = MatchComparatorHelper.normalizeIpv4Address(ipAddress,netMask);
- assertEquals(extractedIpAddress,"1.1.1.0");
- }
-
- @Test
- public void convertArbitraryMaskToByteArrayTest() {
- int value = 0xffffffff;
- byte[] bytes = new byte[]{
- (byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };
- byte[] maskBytes;
- maskBytes = MatchComparatorHelper.convertArbitraryMaskToByteArray(new DottedQuad("255.255.255.255"));
- for (int i=0; i<bytes.length;i++) {
- int mask = maskBytes[i];
- assertEquals(bytes[i],mask);
- }
- }
-
- @Test
- public void isArbitraryBitMaskTest() {
- boolean arbitraryBitMask;
- arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {1,1,1,1});
- assertEquals(arbitraryBitMask,true);
- arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,-1,-1});
- assertEquals(arbitraryBitMask,false);
- arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,0,-1});
- assertEquals(arbitraryBitMask,true);
- arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(null);
- assertEquals(arbitraryBitMask,false);
- }
-
- @Test
- public void createPrefixTest() {
- Ipv4Address ipv4Address = new Ipv4Address("1.1.1.1");
- byte [] byteMask = new byte[] {-1,-1,-1,-1};
- Ipv4Prefix ipv4Prefix = MatchComparatorHelper.createPrefix(ipv4Address,byteMask);
- assertEquals(ipv4Prefix,new Ipv4Prefix("1.1.1.1/32"));
- String nullMask = "";
- Ipv4Prefix ipv4PrefixNullMask = MatchComparatorHelper.createPrefix(ipv4Address,nullMask);
- assertEquals(ipv4PrefixNullMask,new Ipv4Prefix("1.1.1.1/32"));
- Ipv4Prefix ipv4PrefixNoMask = MatchComparatorHelper.createPrefix(ipv4Address);
- assertEquals(ipv4PrefixNoMask,new Ipv4Prefix("1.1.1.1/32"));
- }
-
- @Test
- public void layer3MatchEqualsIpv6ArbitraryMaskTest(){
- final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
- final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/16"));
- storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
- storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:0000:0000:0000:0000:0000:0000:0000"));
- statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/32"));
- storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
- storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:FFFF::"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
-
- @Test
- public void layer3MatchEqualsIpv6ArbitraryMaskRandomTest() {
- final Ipv6MatchArbitraryBitMaskBuilder statsBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
- final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1::8"));
- statsBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
- storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
- storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
- statsBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1::8"));
- statsBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
- storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
- storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
- @Test
- public void layer3MatchEqualsIpv6ArbitraryMaskEqualsNullTest() {
- final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
- final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
- storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
- statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6::/128"));
- storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
- assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-
- @Test
- public void layer3MatchEqualsIpv6ArbitraryEmptyBitMaskTest(){
- final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
- final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
- assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
- statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
- storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
- statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6::/128"));
- storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
- assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
- }
-}
public static final byte[] convertIpv6ArbitraryMaskToByteArray(final Ipv6ArbitraryMask mask) {
String maskValue;
- if (mask.getValue() != null) {
+ if (mask != null && mask.getValue() != null) {
maskValue = mask.getValue();
} else {
maskValue = DEFAULT_IPV6_ARBITRARY_BITMASK;