.settings
MANIFEST.MF
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/resolver/
+.gitignore
+.checkstyle
<openflowplugin.distribution.version>0.1.0-SNAPSHOT</openflowplugin.distribution.version>
<openflowplugin-nicira.version>0.1.0-SNAPSHOT</openflowplugin-nicira.version>
<openflowjava.distribution.version>0.6.0-SNAPSHOT</openflowjava.distribution.version>
+ <restconf.project.version>1.2.0-SNAPSHOT</restconf.project.version>
<config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
<groupbasedpolicy.project.version>0.2.0-SNAPSHOT</groupbasedpolicy.project.version>
<config.groupbasedpolicy.ofoverlayconfigfile>15-groupbasedpolicy-ofoverlay.xml</config.groupbasedpolicy.ofoverlayconfigfile>
});
}
- // XXX TODO - age out endpoint data and remove
+ // TODO Be alagalah - age out endpoint data and remove
// endpoint group/condition mappings with no conditions
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
* Utilities useful for resolving the inheritance rules for the various objects
* in the system
*
+ * @author readams
+ *
*/
public class InheritanceUtils {
/**
HashMap<SelectorName, ProviderNamedSelector> resolvedPns =
new HashMap<>();
NetworkDomainId domain = unresolvedEg.getNetworkDomain();
+ IntraGroupPolicy igp = unresolvedEg.getIntraGroupPolicy();
if (unresolvedEg.getConsumerTargetSelector() != null) {
for (ConsumerTargetSelector s : unresolvedEg.getConsumerTargetSelector()) {
if (domain == null) {
domain = parent.getNetworkDomain();
}
+ if (igp == null) {
+ igp = parent.getIntraGroupPolicy();
+ }
}
// Note: do not set parent, or any of the values that only exist
EndpointGroup resolvedEg = new EndpointGroupBuilder()
.setId(unresolvedEg.getId())
.setDescription(unresolvedEg.getDescription())
+ .setName(unresolvedEg.getName())
.setConsumerTargetSelector(ImmutableList.copyOf(resolvedCts.values()))
.setConsumerNamedSelector(ImmutableList.copyOf(resolvedCns.values()))
.setProviderTargetSelector(ImmutableList.copyOf(resolvedPts.values()))
.setProviderNamedSelector(ImmutableList.copyOf(resolvedPns.values()))
.setNetworkDomain(domain)
+ .setIntraGroupPolicy(igp)
.build();
resolvedEgs.put(resolvedEg.getId(), resolvedEg);
}
* The policy resolver is a utility for renderers to help in resolving
* group-based policy into a form that is easier to apply to the actual network.
*
- * <p>
* For any pair of endpoint groups, there is a set of rules that could apply to
* the endpoints on that group based on the policy configuration. The exact list
* of rules that apply to a given pair of endpoints depends on the conditions
* that are active on the endpoints.
*
- * <p>
* We need to be able to query against this policy model, enumerate the relevant
* classes of traffic and endpoints, and notify renderers when there are changes
* to policy as it applies to active sets of endpoints and endpoint groups.
*
- * <p>
* The policy resolver will maintain the necessary state for all tenants in its
* control domain, which is the set of tenants for which policy listeners have
* been registered.
*
*/
-
public class PolicyResolver implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(PolicyResolver.class);
selectSubjects(Table<EgKey, EgKey,
List<ContractMatch>> contractMatches,
Map<EgKey, Set<ConditionSet>> egConditions) {
- // Note that it's possible to further simplify the resulting policy
+ // TODO: Note that it's possible to further simplify the resulting
+ // policy
// in the case of things like repeated rules, condition sets that
// cover other condition sets, etc. This would be a good thing to do
// at some point
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.groupbasedpolicy.endpoint.EndpointRpcRegistry;
import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
import org.opendaylight.groupbasedpolicy.util.SetUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
/**
* Keep track of endpoints on the system. Maintain an index of endpoints and
* In order to render the policy, we need to be able to efficiently enumerate
* all endpoints on a particular switch and also all the switches containing
* each particular endpoint group
+ *
+ * @author readams
*/
public class EndpointManager implements AutoCloseable, DataChangeListener
{
private final ConcurrentHashMap<EpKey, Endpoint> endpoints =
new ConcurrentHashMap<>();
- private final ConcurrentHashMap<NodeId, ConcurrentMap<EgKey, Set<EpKey>>> endpointsByNode =
+ private final ConcurrentHashMap<NodeId, ConcurrentMap<EgKey, Set<EpKey>>> endpointsByGroupByNode =
+ new ConcurrentHashMap<>();
+ private final ConcurrentHashMap<NodeId, Set<EpKey>> endpointsByNode =
new ConcurrentHashMap<>();
+
private final ConcurrentHashMap<EgKey, Set<EpKey>> endpointsByGroup =
new ConcurrentHashMap<>();
* @return a collection of {@link Endpoint} objects.
*/
public Set<EgKey> getGroupsForNode(NodeId nodeId) {
- Map<EgKey, Set<EpKey>> nodeEps = endpointsByNode.get(nodeId);
+ Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
if (nodeEps == null)
return Collections.emptySet();
return Collections.unmodifiableSet(nodeEps.keySet());
/**
* Get the set of nodes
*
- * @param nodeId
- * the nodeId of the switch to get endpoints for
- * @return a collection of {@link Endpoint} objects.
+ * @param egKey
+ * the egKey of the endpointgroup to get nodes for
+ * @return a collection of {@link NodeId} objects.
*/
public Set<NodeId> getNodesForGroup(final EgKey egKey) {
- return Collections.unmodifiableSet(Sets.filter(endpointsByNode.keySet(),
+ return Collections.unmodifiableSet(Sets.filter(endpointsByGroupByNode.keySet(),
new Predicate<NodeId>() {
@Override
public boolean apply(NodeId input) {
Map<EgKey, Set<EpKey>> nodeEps =
- endpointsByNode.get(input);
+ endpointsByGroupByNode.get(input);
return (nodeEps != null &&
nodeEps.containsKey(egKey));
}
* the group to look up
* @return the endpoints
*/
- public Collection<Endpoint> getEPsForNode(NodeId nodeId, EgKey eg) {
- Map<EgKey, Set<EpKey>> nodeEps = endpointsByNode.get(nodeId);
+ public Collection<Endpoint> getEndpointsForNode(NodeId nodeId, EgKey eg) {
+ // TODO: alagalah Create method findEndpointsByNode() that uses
+ // datastore
+
+ Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
if (nodeEps == null)
return Collections.emptyList();
Collection<EpKey> ebn = nodeEps.get(eg);
indexTransform));
}
+ /**
+ * Get the endpoints on a particular node
+ *
+ * @param nodeId
+ * the node ID to look up
+ * @return the endpoints
+ */
+ public Collection<Endpoint> getEndpointsForNode(final NodeId nodeId) {
+ // TODO: alagalah Create method findEndpointsByNode() that uses
+ // datastore. See commented code below.
+
+ Collection<Endpoint> epsByNode = Collections.emptyList();
+ // Blocking for test.
+ // // Predicate for filtering only the endpoints we need for this nodeID
+ // //TODO: This pulls from datastore. Will be more performant to update
+ // // endpointByNode in updateEndpoint.
+ // Predicate<Endpoint> predicate = new Predicate<Endpoint>() {
+ // @Override
+ // public boolean apply(Endpoint ep) {
+ // return
+ // ep.getAugmentation(OfOverlayContext.class).getNodeId().getValue().equals(nodeId.getValue());
+ // }
+ // };
+ //
+ // Optional<Endpoints> epResult;
+ // final InstanceIdentifier<Endpoints> endpointsIid =
+ // InstanceIdentifier.builder(Endpoints.class).build();
+ // try {
+ // epResult =
+ // dataProvider.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
+ // endpointsIid).get();
+ // if(epResult.isPresent()) {
+ // Endpoints endpoints = epResult.get();
+ // epsByNode =
+ // Collections2.filter((Collection<Endpoint>)endpoints.getEndpoint(),predicate);
+ // }
+ // } catch (InterruptedException | ExecutionException e) {
+ // LOG.error("Caught exception in getEPsForNode");
+ // }
+ Collection<EpKey> ebn = endpointsByNode.get(nodeId);
+ if (ebn == null)
+ return Collections.emptyList();
+ return Collections.unmodifiableCollection(Collections2
+ .transform(ebn,
+ indexTransform));
+
+ }
+
/**
* Get the endpoint object for the given key
*
* @return the list of {@link ConditionName}
*/
public List<ConditionName> getCondsForEndpoint(Endpoint endpoint) {
- // XXX TODO consider group conditions as well. Also need to notify
+ // TODO Be alagalah From Helium: consider group conditions as well. Also
+ // need to notify
// endpoint updated if the endpoint group conditions change
if (endpoint.getCondition() != null)
return endpoint.getCondition();
}
}
+ // TODO: alagalah Investigate using the internal project listener structure
+ // for this. ie Endpoint should listen to
+ // SwitchManager updates and update the EP maps accordingly (update
+ // Endpoint). Removal should include the overloaded
+ // method updateEndpoint(Node node)
private class NodesListener implements DataChangeListener {
@Override
public void onDataChanged(
continue;
Node node = (Node) dao;
if (node.getNodeConnector() != null) {
- executor.execute(new UpdateEndpoint(node));
- return;
+ updateEndpoint(node);
}
}
for (DataObject dao : change.getUpdatedData().values()) {
continue;
Node node = (Node) dao;
if (node.getNodeConnector() != null) {
- executor.execute(new UpdateEndpoint(node));
- return;
+ updateEndpoint(node);
}
}
}
}
- private class UpdateEndpoint implements Runnable {
- private final Node node;
- private final InstanceIdentifier<Endpoints> endpointsIid;
+ // TODO Li alagalah move this near to other updateEndpoint()
+ private void updateEndpoint(Node node) {
+ final InstanceIdentifier<Endpoints> endpointsIid = InstanceIdentifier.builder(Endpoints.class).build();
- public UpdateEndpoint(Node node) {
- this.node = node;
- this.endpointsIid = InstanceIdentifier.builder(Endpoints.class).build();
- }
-
- @Override
- public void run() {
- Optional<Endpoints> epResult;
- EpKey epKey = null;
- for (NodeConnector nc : node.getNodeConnector()) {
- FlowCapableNodeConnector fcnc = nc
- .getAugmentation(FlowCapableNodeConnector.class);
- try {
- epResult = dataProvider.newReadOnlyTransaction()
- .read(LogicalDatastoreType.OPERATIONAL, endpointsIid).get();
- if (epResult.isPresent()) {
- Endpoints endpoints = epResult.get();
- if (endpoints.getEndpoint() != null) {
- WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
- Boolean isEmpty = true;
- for (Endpoint ep : endpoints.getEndpoint()) {
- // 2. Search for portname
- OfOverlayContext currentAugmentation = ep.getAugmentation(OfOverlayContext.class);
- if (ep.getPortName().getValue().equals(fcnc.getName())) {
- NodeId nodeId;
- NodeConnectorId nodeConnectorId;
- try {
- nodeId = currentAugmentation.getNodeId();
- nodeConnectorId = currentAugmentation.getNodeConnectorId();
- } catch (Exception e) {
- nodeId = null;
- nodeConnectorId = null;
- }
- Boolean process = false;
- if (nodeId == null && nodeConnectorId == null) {
- LOG.debug("ep NodeID and NC ID Both null");
+ Optional<Endpoints> epResult;
+ EpKey epKey = null;
+ for (NodeConnector nc : node.getNodeConnector()) {
+ FlowCapableNodeConnector fcnc = nc
+ .getAugmentation(FlowCapableNodeConnector.class);
+ try {
+ epResult = dataProvider.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL, endpointsIid)
+ .get();
+ if (epResult.isPresent()) {
+ Endpoints endpoints = epResult.get();
+ if (endpoints.getEndpoint() != null) {
+ Boolean isEmpty = true;
+ for (Endpoint ep : endpoints.getEndpoint()) {
+ // 2. Search for portname
+ OfOverlayContext currentAugmentation = ep.getAugmentation(OfOverlayContext.class);
+ if (ep.getPortName() != null && fcnc.getName() != null
+ && ep.getPortName().getValue().equals(fcnc.getName())) {
+ NodeId nodeId;
+ NodeConnectorId nodeConnectorId;
+ try {
+ nodeId = currentAugmentation.getNodeId();
+ nodeConnectorId = currentAugmentation.getNodeConnectorId();
+ } catch (Exception e) {
+ nodeId = null;
+ nodeConnectorId = null;
+ }
+ Boolean process = false;
+ if (nodeId == null && nodeConnectorId == null) {
+ LOG.debug("ep NodeID and NC ID Both null");
+ process = true;
+ }
+ if (nodeId != null && nodeConnectorId != null) {
+ if (!(nodeConnectorId.getValue().equals(nc.getId().getValue()))) {
+ LOG.debug("ep NodeID and NC ID Both NOT null but epNCID !=nodeNCID");
process = true;
}
+ }
+ if (process) {
+ WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
+ // 3. Update endpoint
+ EndpointBuilder epBuilder = new EndpointBuilder(ep);
+ OfOverlayContextBuilder ofOverlayAugmentation = new OfOverlayContextBuilder();
+ ofOverlayAugmentation.setNodeId(node.getId());
+ ofOverlayAugmentation.setNodeConnectorId(nc.getId());
+ epBuilder.addAugmentation(OfOverlayContext.class, ofOverlayAugmentation.build());
+ epBuilder.setL3Address(ep.getL3Address());
+ InstanceIdentifier<Endpoint> iidEp = InstanceIdentifier.builder(Endpoints.class)
+ .child(Endpoint.class, ep.getKey()).build();
+ tx.put(LogicalDatastoreType.OPERATIONAL, iidEp, epBuilder.build());
+ tx.submit().get();
+ epKey = new EpKey(ep.getKey().getL2Context(), ep.getKey().getMacAddress());
+ notifyEndpointUpdated(epKey);
+ LOG.debug("Values:");
+ LOG.debug("node: Node ID:" + node.getId().getValue());
+ LOG.debug("node: NodeConnectorID: " + nc.getId().getValue());
if (nodeId != null && nodeConnectorId != null) {
- if (!(nodeConnectorId.getValue().equals(nc.getId().getValue()))) {
- LOG.debug("ep NodeID and NC ID Both NOT null but epNCID !=nodeNCID");
- process = true;
- }
- }
- if (process) {
- // 3. Update endpoint
- EndpointBuilder epBuilder = new EndpointBuilder(ep);
- OfOverlayContextBuilder ofOverlayAugmentation = new OfOverlayContextBuilder();
- ofOverlayAugmentation.setNodeId(node.getId());
- ofOverlayAugmentation.setNodeConnectorId(nc.getId());
- epBuilder
- .addAugmentation(OfOverlayContext.class, ofOverlayAugmentation.build());
- // TODO Hack to remove:
- List<L3Address> l3Addresses = new ArrayList<>();
- for (L3Address l3Address : ep.getL3Address()) {
- L3AddressBuilder l3AB = new L3AddressBuilder();
- l3AB.setIpAddress(l3Address.getIpAddress()).setL3Context(
- l3Address.getL3Context());
- l3Addresses.add(l3AB.build());
- }
- epBuilder.setL3Address(l3Addresses);
- InstanceIdentifier<Endpoint> iidEp = InstanceIdentifier
- .builder(Endpoints.class).child(Endpoint.class, ep.getKey()).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, iidEp, epBuilder.build());
- epKey = new EpKey(ep.getKey().getL2Context(), ep.getKey().getMacAddress());
- LOG.debug("Values:");
- LOG.debug("node: Node ID:" + node.getId().getValue());
- LOG.debug("node: NodeConnectorID: " + nc.getId().getValue());
- if (nodeId != null && nodeConnectorId != null) {
- LOG.debug("ep: nodeID:" + nodeId.getValue());
- LOG.debug("ep: nodeConnectorID:" + nodeConnectorId.getValue());
- }
- isEmpty = false;
+ LOG.debug("ep: nodeID:" + nodeId.getValue());
+ LOG.debug("ep: nodeConnectorID:" + nodeConnectorId.getValue());
}
+ isEmpty = false;
}
}
- if (!isEmpty) {
- CheckedFuture<Void, TransactionCommitFailedException> f = tx.submit();
- notifyEndpointUpdated(epKey);
- Futures.addCallback(f, new FutureCallback<Void>() {
- @Override
- public void onFailure(Throwable t) {
- LOG.error("Could not over-write endpoint with augmentation", t);
- }
-
- @Override
- public void onSuccess(Void result) {
- LOG.debug("Success over-writing endpoint augmentation");
- }
- });
- } else {
- LOG.debug("UpdateEndpoint: Empty list");
- }
}
}
- } catch (InterruptedException | ExecutionException e) {
- LOG.error("Caught exception in UpdateEndpoint", e);
}
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Exception in UpdateEndpoint", e);
}
}
}
private boolean validEp(Endpoint endpoint) {
return (endpoint != null && endpoint.getTenant() != null &&
- endpoint.getEndpointGroup() != null &&
+ (endpoint.getEndpointGroup() != null || endpoint.getEndpointGroups() != null) &&
endpoint.getL2Context() != null && endpoint.getMacAddress() != null);
}
return new EpKey(endpoint.getL2Context(), endpoint.getMacAddress());
}
- private EgKey getEgKey(Endpoint endpoint) {
+ public EgKey getEgKey(Endpoint endpoint) {
if (!validEp(endpoint))
return null;
return new EgKey(endpoint.getTenant(), endpoint.getEndpointGroup());
}
+ public Set<EgKey> getEgKeysForEndpoint(Endpoint ep) {
+ Set<EgKey> egKeys = new HashSet<EgKey>();
+
+ if (ep.getEndpointGroup() != null) {
+ egKeys.add(new EgKey(ep.getTenant(), ep.getEndpointGroup()));
+ }
+ if (ep.getEndpointGroups() != null) {
+ for (EndpointGroupId epgId : ep.getEndpointGroups()) {
+ egKeys.add(new EgKey(ep.getTenant(), epgId));
+ }
+ }
+ return egKeys;
+ }
+
private Set<EpKey> getEpNGSet(NodeId location, EgKey eg) {
- ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByNode.get(location);
+ ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByGroupByNode.get(location);
if (map == null) {
map = new ConcurrentHashMap<>();
ConcurrentMap<EgKey, Set<EpKey>> old =
- endpointsByNode.putIfAbsent(location, map);
+ endpointsByGroupByNode.putIfAbsent(location, map);
if (old != null)
map = old;
}
* Update the endpoint indexes. Set newEp to null to remove.
*/
protected void updateEndpoint(Endpoint oldEp, Endpoint newEp) {
- // XXX TODO only keep track of endpoints that are attached
+ // TODO Be alagalah From Helium only keep track of endpoints that are
+ // attached
// to switches that are actually connected to us
+
+ // TODO Li alagalah: This needs a major clean up and refactor. For now
+ // it works.
NodeId oldLoc = getLocation(oldEp);
NodeId newLoc = getLocation(newEp);
-
- EgKey oldKey = getEgKey(oldEp);
- EgKey newKey = getEgKey(newEp);
-
- EpKey epKey = getEpKey(oldEp);
- if (epKey == null)
- epKey = getEpKey(newEp);
- if (epKey == null)
- return;
+ // EgKey oldEgKey = getEgKey(oldEp);
+ EpKey oldEpKey = getEpKey(oldEp);
+ EpKey newEpKey = getEpKey(newEp);
boolean notifyOldLoc = false;
boolean notifyNewLoc = false;
boolean notifyOldEg = false;
boolean notifyNewEg = false;
- if (newEp != null)
- endpoints.put(epKey, newEp);
-
- if (oldLoc != null && oldKey != null &&
- (newLoc == null || !oldLoc.equals(newLoc) ||
- newKey == null || !oldKey.equals(newKey))) {
- ConcurrentMap<EgKey, Set<EpKey>> map =
- endpointsByNode.get(oldLoc);
- Set<EpKey> eps = map.get(oldKey);
- eps.remove(epKey);
- map.remove(oldKey, Collections.emptySet());
- endpointsByNode.remove(oldLoc, EMPTY_MAP);
- notifyOldLoc = true;
- }
- if (oldKey != null &&
- (newKey == null || !oldKey.equals(newKey))) {
- Set<EpKey> gns = getEpGSet(oldKey);
- gns.remove(epKey);
- notifyOldEg = true;
- }
+ // When newLoc and oldLoc are null there is nothing to do
+ if (!(newLoc == null && oldLoc == null)) {
- if (newLoc != null && newKey != null) {
- Set<EpKey> eps = getEpNGSet(newLoc, newKey);
- eps.add(epKey);
- LOG.debug("Endpoint {} added to node {}", epKey, newLoc);
- notifyNewLoc = true;
- }
- if (newKey != null) {
- Set<EpKey> gns = getEpGSet(newKey);
- gns.add(epKey);
- LOG.debug("Endpoint {} added to group {}", epKey, newKey);
- notifyNewEg = true;
- }
+ Set<EndpointGroupId> newEpgIds = new HashSet<EndpointGroupId>();
+ TenantId tenantId = null;
+ if (newEp != null) {
+ if (newEp.getEndpointGroups() != null) {
+ newEpgIds.addAll(newEp.getEndpointGroups());
+ }
+ if (newEp.getEndpointGroup() != null) {
+ newEpgIds.add(newEp.getEndpointGroup());
+ }
+ tenantId = newEp.getTenant();
+ }
+
+ Set<EndpointGroupId> oldEpgIds = new HashSet<EndpointGroupId>();
+ if (oldEp != null) {
+ if (oldEp.getEndpointGroups() != null) {
+ oldEpgIds.addAll(oldEp.getEndpointGroups());
+ }
+ if (oldEp.getEndpointGroup() != null) {
+ oldEpgIds.add(oldEp.getEndpointGroup());
+ }
+ }
- if (newEp == null)
- endpoints.remove(epKey);
+ /*
+ * maintainIndex(endpointsByNode,oldEp,newEp) Maintain following
+ * maps endpoints - <EpKey, Endpoint> endpointsByGroupByNode -
+ * <NodeId, ConcurrentMap<EgKey, Set<EpKey>>> endpointsByNode -
+ * <NodeId,Set<EpKey>> endpointsByGroup ConcurrentHashMap<EgKey,
+ * Set<EpKey>>
+ */
+
+ // Maintain "endpoints" map
+ if (newEp != null) {
+ endpoints.put(newEpKey, newEp);
+ } else {
+ endpoints.remove(oldEpKey);
+ }
- notifyEndpointUpdated(epKey);
+ /*
+ * New endpoint with location information
+ */
+ if (oldEp == null && newEp != null && newLoc != null) {
+ // Update endpointsByNode
+ if (endpointsByNode.get(newLoc) == null) {
+ // TODO: alagalah cleaner way with checking epsNode
+ // then do this.
+ Set<EpKey> epsNode = new HashSet<EpKey>();
+ epsNode.add(newEpKey);
+ endpointsByNode.put(newLoc, epsNode);
+ } else {
+ Set<EpKey> epsNode = endpointsByNode.get(newLoc);
+ epsNode.add(newEpKey);
+ }
+ // Update endpointsByGroupByNode and endpointsByGroup
+ for (EndpointGroupId newEpgId : newEpgIds) {
+ // endpointsByGroupByNode
+ EgKey newEgKey = new EgKey(tenantId, newEpgId);
+ Set<EpKey> eps = getEpNGSet(newLoc, newEgKey);
+ eps.add(newEpKey);
+ // endpointsByGroup
+ Set<EpKey> geps = endpointsByGroup.get(newEgKey);
+ if (geps == null) {
+ geps = new HashSet<>();
+ }
+ geps.add(newEpKey);
+ endpointsByGroup.put(newEgKey, geps);
+ LOG.debug("Endpoint {} added to node {}", newEpKey, newLoc);
- if (notifyOldLoc)
- notifyNodeEndpointUpdated(oldLoc, epKey);
- if (notifyNewLoc)
- notifyNodeEndpointUpdated(newLoc, epKey);
- if (notifyOldEg)
- notifyGroupEndpointUpdated(oldKey, epKey);
- if (notifyNewEg)
- notifyGroupEndpointUpdated(newKey, epKey);
+ }
+
+ notifyNewLoc = true;
+ notifyNewEg = true;
+ }
+
+ /*
+ * Removed endpoint
+ */
+ if (oldEp != null && newEp == null) {
+ // Update endpointsByNode
+ Set<EpKey> epsNode = endpointsByNode.get(oldLoc);
+ if (epsNode != null) {
+ epsNode.remove(oldEpKey);
+ if (epsNode.isEmpty())
+ endpointsByNode.remove(oldLoc);
+ }
+ // Update endpointsByGroupByNode
+ // Update endpointsByGroup
+ // Get map of EPGs and their Endpoints for Node
+ ConcurrentMap<EgKey, Set<EpKey>> map =
+ endpointsByGroupByNode.get(oldLoc);
+ // For each EPG in the removed endpoint...
+ for (EndpointGroupId oldEpgId : newEpgIds) {
+ EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
+ // Get list of endpoints for EPG
+ Set<EpKey> eps = map.get(oldEgKey);
+ // Remove the endpoint from the map
+ if (eps != null) {
+ eps.remove(oldEpKey);
+ if (eps.isEmpty())
+ map.remove(oldEgKey, Collections.emptySet());
+ }
+ // endpointsByGroup
+ Set<EpKey> geps = endpointsByGroup.get(oldEgKey);
+ if (geps != null) {
+ geps.remove(oldEpKey);
+ if (geps.isEmpty())
+ endpointsByGroup.remove(oldEgKey);
+ }
+ }
+ // If map is empty, no more EPGs on this node, remove node from
+ // map
+ if (map.isEmpty())
+ endpointsByGroupByNode.remove(oldLoc, EMPTY_MAP);
+ notifyOldLoc = true;
+ notifyOldEg = true;
+ }
+
+ /*
+ * Moved endpoint (from node to node or from NULL to node)
+ */
+ if ((oldEp != null && newEp != null && oldEpKey != null && newEpKey != null) &&
+ (oldEpKey.toString().equals(newEpKey.toString()))) {
+ // old and new Endpoints have same key. (same endpoint)
+
+ /*
+ * Remove old endpoint if moved.
+ */
+ if (oldLoc != null && !(oldLoc.getValue().equals(newLoc.getValue()))) {
+ // This is an endpoint that has moved, remove from old node
+ Set<EpKey> epsNode = endpointsByNode.get(oldLoc);
+ if (epsNode != null) {
+ epsNode.remove(oldEpKey);
+ if (epsNode.isEmpty())
+ endpointsByNode.remove(oldLoc);
+ }
+ // Update endpointsByGroupByNode
+ // Get map of EPGs and their Endpoints for Node
+ ConcurrentMap<EgKey, Set<EpKey>> map =
+ endpointsByGroupByNode.get(oldLoc);
+ // For each EPG in the removed endpoint...
+ for (EndpointGroupId oldEpgId : oldEpgIds) {
+ EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
+ // Get list of endpoints for EPG
+ Set<EpKey> eps = map.get(oldEgKey);
+ // Remove the endpoint from the map
+ if (eps != null) {
+ eps.remove(oldEpKey);
+ if (eps.isEmpty())
+ map.remove(oldEgKey, Collections.emptySet());
+ }
+ // endpointsByGroup
+ Set<EpKey> geps = endpointsByGroup.get(oldEgKey);
+ if (geps != null)
+ {
+ geps.remove(oldEpKey);
+ if (geps.isEmpty())
+ endpointsByGroup.remove(oldEgKey);
+ }
+ }
+ // If map is empty, no more EPGs on this node, remove node
+ // from map
+ if (map.isEmpty())
+ endpointsByGroupByNode.remove(oldLoc, EMPTY_MAP);
+ notifyOldLoc = true;
+ notifyOldEg = true;
+ }
+
+ /*
+ * Add new endpoint
+ */
+ // Update endpointsByNode
+ if (endpointsByNode.get(newLoc) == null) {
+ Set<EpKey> newEpsNode = new HashSet<EpKey>();
+ newEpsNode.add(newEpKey);
+ endpointsByNode.put(newLoc, newEpsNode);
+ } else {
+ Set<EpKey> newEpsNode = endpointsByNode.get(newLoc);
+ newEpsNode.add(newEpKey);
+ }
+ notifyNewLoc = true;
+
+ // Update endpointsByGroupByNode
+ // Update endpointsByGroup
+ for (EndpointGroupId newEpgId : newEpgIds) {
+ EgKey newEgKey = new EgKey(tenantId, newEpgId);
+ Set<EpKey> eps = getEpNGSet(newLoc, newEgKey);
+ eps.add(newEpKey);
+ // endpointsByGroup
+ Set<EpKey> geps = endpointsByGroup.get(newEgKey);
+ if (geps == null) {
+ geps = new HashSet<>();
+ }
+ geps.add(newEpKey);
+ endpointsByGroup.put(newEgKey, geps);
+ notifyNewEg = true;
+
+ LOG.debug("Endpoint {} added to node {}", newEpKey, newLoc);
+ }
+
+ }
+
+ if (newEp != null)
+ notifyEndpointUpdated(newEpKey);
+ else
+ notifyEndpointUpdated(oldEpKey);
+
+ // TODO alagalah NEXt: ensure right notification flags are set.
+ if (notifyOldLoc)
+ notifyNodeEndpointUpdated(oldLoc, oldEpKey);
+ if (notifyNewLoc)
+ notifyNodeEndpointUpdated(newLoc, newEpKey);
+ if (notifyOldEg)
+ for (EndpointGroupId oldEpgId : oldEpgIds) {
+ EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
+ notifyGroupEndpointUpdated(oldEgKey, oldEpKey);
+ }
+ if (notifyNewEg)
+ for (EndpointGroupId newEpgId : newEpgIds) {
+ EgKey newEgKey = new EgKey(newEp.getTenant(), newEpgId);
+ notifyGroupEndpointUpdated(newEgKey, newEpKey);
+ }
+
+ }
}
private OfOverlayContextBuilder checkAugmentation(RegisterEndpointInput input) {
return ictxBuilder;
}
- // A wrapper class around node, noeConnector info so we can pass a final
+ // A wrapper class around node, nodeConnector info so we can pass a final
// object inside OnSuccess anonymous inner class
private static class NodeInfo {
NodeConnector nodeConnector;
}
}
} catch (InterruptedException | ExecutionException e) {
- LOG.error("Could not fetch Node Augmentation", e);
+ LOG.error("Caught exception in fetchAugmentation portName", e);
}
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.DestinationMapper;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OfTable;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PortSecurity;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.SourceMapper;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
-import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.groupbasedpolicy.resolver.PolicyListener;
import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
import org.opendaylight.groupbasedpolicy.resolver.PolicyScope;
-import org.opendaylight.groupbasedpolicy.util.SetUtils;
import org.opendaylight.groupbasedpolicy.util.SingletonTask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig.LearningMode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
/**
- * Manage policies on switches by subscribing to updates from the
- * policy resolver and information about endpoints from the endpoint
+ * Manage policies on switches by subscribing to updates from the
+ * policy resolver and information about endpoints from the endpoint
* registry
- * @author readams
*/
-public class PolicyManager
+public class PolicyManager
implements SwitchListener, PolicyListener, EndpointListener {
- private static final Logger LOG =
+ private static final Logger LOG =
LoggerFactory.getLogger(PolicyManager.class);
private final SwitchManager switchManager;
private final PolicyResolver policyResolver;
-
+
private final PolicyScope policyScope;
-
- private final AtomicReference<Dirty> dirty;
-
+
private final ScheduledExecutorService executor;
private final SingletonTask flowUpdateTask;
+ private final DataBroker dataBroker;
/**
* The flow tables that make up the processing pipeline
*/
private final static int FLOW_UPDATE_DELAY = 250;
- /**
- * Counter used to allocate ordinal values for forwarding contexts
- * and VNIDs
- */
- private final AtomicInteger policyOrdinal = new AtomicInteger(1);
-
- /**
- * Keep track of currently-allocated ordinals
- */
- // XXX For the endpoint groups, we need a globally unique ordinal, so
- // should ultimately involve some sort of distributed agreement
- // or a leader to allocate them. For now we'll just use a counter and
- // this local map. Also theoretically need to garbage collect periodically
- private final ConcurrentMap<String, Integer> ordinals =
- new ConcurrentHashMap<>();
- // XXX - need to garbage collect
- private final ConcurrentMap<ConditionGroup, Integer> cgOrdinals =
- new ConcurrentHashMap<>();
-
+
+
public PolicyManager(DataBroker dataBroker,
PolicyResolver policyResolver,
SwitchManager switchManager,
- EndpointManager endpointManager,
+ EndpointManager endpointManager,
RpcProviderRegistry rpcRegistry,
ScheduledExecutorService executor) {
super();
this.switchManager = switchManager;
this.executor = executor;
this.policyResolver = policyResolver;
+ this.dataBroker = dataBroker;
+
if (dataBroker != null) {
WriteTransaction t = dataBroker.newWriteOnlyTransaction();
- t.put(LogicalDatastoreType.OPERATIONAL,
+ t.put(LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier
.builder(SubjectFeatureDefinitions.class)
.build(),
}
OfContext ctx = new OfContext(dataBroker, rpcRegistry,
- this, policyResolver, switchManager,
+ this, policyResolver, switchManager,
endpointManager, executor);
flowPipeline = ImmutableList.of(new PortSecurity(ctx),
new GroupTable(ctx),
if (switchManager != null)
switchManager.registerListener(this);
endpointManager.registerListener(this);
-
- dirty = new AtomicReference<>(new Dirty());
-
+
flowUpdateTask = new SingletonTask(executor, new FlowUpdateTask());
scheduleUpdate();
-
+
LOG.debug("Initialized OFOverlay policy manager");
}
@Override
public void switchReady(final NodeId nodeId) {
+ //TODO Apr15 alagalah : OVSDB CRUD tunnels may go here.
// WriteTransaction t = dataBroker.newWriteOnlyTransaction();
-//
+//
// NodeBuilder nb = new NodeBuilder()
// .setId(nodeId)
-// .addAugmentation(FlowCapableNode.class,
+// .addAugmentation(FlowCapableNode.class,
// new FlowCapableNodeBuilder()
// .build());
-// t.merge(LogicalDatastoreType.CONFIGURATION,
+// t.merge(LogicalDatastoreType.CONFIGURATION,
// FlowUtils.createNodePath(nodeId),
// nb.build(), true);
// ListenableFuture<Void> result = t.submit();
-// Futures.addCallback(result,
+// Futures.addCallback(result,
// new FutureCallback<Void>() {
// @Override
// public void onSuccess(Void result) {
// LOG.error("Could not add switch {}", nodeId, t);
// }
// });
-
+
}
@Override
public void switchRemoved(NodeId sw) {
// XXX TODO purge switch flows
- dirty.get().addNode(sw);
scheduleUpdate();
}
-
+
@Override
public void switchUpdated(NodeId sw) {
- dirty.get().addNode(sw);
scheduleUpdate();
}
// ****************
// EndpointListener
// ****************
-
+
@Override
public void endpointUpdated(EpKey epKey) {
- dirty.get().addEndpoint(epKey);
scheduleUpdate();
}
@Override
public void nodeEndpointUpdated(NodeId nodeId, EpKey epKey){
- dirty.get().addNodeEp(nodeId, epKey);
scheduleUpdate();
}
@Override
public void groupEndpointUpdated(EgKey egKey, EpKey epKey) {
- dirty.get().addEndpointGroupEp(egKey, epKey);
policyScope.addToScope(egKey.getTenantId(), egKey.getEgId());
scheduleUpdate();
}
// **************
// PolicyListener
// **************
-
+
@Override
public void policyUpdated(Set<EgKey> updatedConsumers) {
- for (EgKey key : updatedConsumers) {
- dirty.get().addEndpointGroup(key);
- }
scheduleUpdate();
}
// No-op for now
}
- /**
- * Get a unique ordinal for the given condition group, suitable for
- * use in the data plane. This is unique only for this node, and not
- * globally.
- * @param cg the {@link ConditionGroup}
- * @return the unique ID
- */
- public int getCondGroupOrdinal(final ConditionGroup cg) {
- if (cg == null) return 0;
- Integer ord = cgOrdinals.get(cg);
- if (ord == null) {
- ord = policyOrdinal.getAndIncrement();
- Integer old = cgOrdinals.putIfAbsent(cg, ord);
- if (old != null) ord = old;
- }
- return ord.intValue();
- }
-
- /**
- * Get a 32-bit context ordinal suitable for use in the OF data plane
- * for the given policy item.
- * @param tenantId the tenant ID of the element
- * @param id the unique ID for the element
- * @return the 32-bit ordinal value
- */
- public int getContextOrdinal(final TenantId tenantId,
- final UniqueId id) throws Exception {
- if (tenantId == null || id == null) return 0;
- return getContextOrdinal(tenantId.getValue() + "|" + id.getValue());
- }
- /**
- * Get a 32-bit context ordinal suitable for use in the OF data plane
- * for the given policy item.
- * @param id the unique ID for the element
- * @return the 32-bit ordinal value
- */
- public int getContextOrdinal(final String id) throws Exception {
- Integer ord = ordinals.get(id);
- if (ord == null) {
- ord = policyOrdinal.getAndIncrement();
- Integer old = ordinals.putIfAbsent(id, ord);
- if (old != null) ord = old;
- }
- return ord.intValue();
- }
-
// **************
// Implementation
// **************
+ public class FlowMap{
+ private ConcurrentMap<InstanceIdentifier<Table>, TableBuilder> flowMap = new ConcurrentHashMap<>();
+
+ public FlowMap() {
+ }
+
+ public TableBuilder getTableForNode(NodeId nodeId, short tableId) {
+ InstanceIdentifier<Table> tableIid = FlowUtils.createTablePath(nodeId, tableId);
+ if(this.flowMap.get(tableIid) == null) {
+ this.flowMap.put(tableIid, new TableBuilder().setId(tableId));
+ this.flowMap.get(tableIid).setFlow(new ArrayList<Flow>());
+ }
+ return this.flowMap.get(tableIid);
+ }
+
+ public void writeFlow(NodeId nodeId,short tableId, Flow flow) {
+ TableBuilder tableBuilder = this.getTableForNode(nodeId, tableId);
+ if (!tableBuilder.getFlow().contains(flow)) {
+ tableBuilder.getFlow().add(flow);
+ }
+ }
+
+ public void commitToDataStore() {
+ if (dataBroker != null) {
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ for( Entry<InstanceIdentifier<Table>, TableBuilder> entry : flowMap.entrySet()) {
+ t.put(LogicalDatastoreType.CONFIGURATION,
+ entry.getKey(), entry.getValue().build(),true);
+ }
+
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
+ Futures.addCallback(f, new FutureCallback<Void>() {
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.error("Could not write flow table.", t);
+ }
+
+ @Override
+ public void onSuccess(Void result) {
+ LOG.debug("Flow table updated.");
+ }
+ });
+ }
+ }
+
+ }
+
private void scheduleUpdate() {
if (switchManager != null) {
LOG.trace("Scheduling flow update task");
flowUpdateTask.reschedule(FLOW_UPDATE_DELAY, TimeUnit.MILLISECONDS);
}
}
-
+
/**
* Update the flows on a particular switch
*/
private class SwitchFlowUpdateTask implements Callable<Void> {
- private final Dirty dirty;
- private final NodeId nodeId;
+ private FlowMap flowMap;
- public SwitchFlowUpdateTask(Dirty dirty, NodeId nodeId) {
+ public SwitchFlowUpdateTask(FlowMap flowMap) {
super();
- this.dirty = dirty;
- this.nodeId = nodeId;
+ this.flowMap = flowMap;
}
@Override
public Void call() throws Exception {
- if (!switchManager.isSwitchReady(nodeId)) return null;
- PolicyInfo info = policyResolver.getCurrentPolicy();
- if (info == null) return null;
- for (OfTable table : flowPipeline) {
- try {
- table.update(nodeId, info, dirty);
- } catch (Exception e) {
- LOG.error("Failed to write flow table {}",
- table.getClass().getSimpleName(), e);
+ for (NodeId node : switchManager.getReadySwitches()) {
+ if (!switchManager.isSwitchReady(node))
+ return null;
+ PolicyInfo info = policyResolver.getCurrentPolicy();
+ if (info == null)
+ return null;
+ for (OfTable table : flowPipeline) {
+ try {
+ table.update(node, info, flowMap);
+ } catch (Exception e) {
+ LOG.error("Failed to write flow table {}",
+ table.getClass().getSimpleName(), e);
+ }
}
}
return null;
/**
* Update all flows on all switches as needed. Note that this will block
* one of the threads on the executor.
- * @author readams
*/
private class FlowUpdateTask implements Runnable {
@Override
public void run() {
LOG.debug("Beginning flow update task");
- Dirty d = dirty.getAndSet(new Dirty());
CompletionService<Void> ecs
= new ExecutorCompletionService<Void>(executor);
int n = 0;
- for (NodeId node : switchManager.getReadySwitches()) {
- SwitchFlowUpdateTask swut = new SwitchFlowUpdateTask(d, node);
- ecs.submit(swut);
- n += 1;
- }
+
+ FlowMap flowMap = new FlowMap();
+
+ SwitchFlowUpdateTask swut = new SwitchFlowUpdateTask(flowMap);
+ ecs.submit(swut);
+ n+=1;
+
for (int i = 0; i < n; i++) {
try {
ecs.take().get();
+ flowMap.commitToDataStore();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to update flow tables", e);
}
LOG.debug("Flow update completed");
}
}
-
- /**
- * Dirty state since our last successful flow table sync.
- */
- public static class Dirty {
- private Set<EpKey> endpoints;
- private Set<NodeId> nodes;
- private Set<EgKey> groups;
- private ConcurrentMap<EgKey, Set<EpKey>> groupEps;
- private ConcurrentMap<NodeId, Set<EpKey>> nodeEps;
-
- public Dirty() {
- ConcurrentHashMap<EpKey,Boolean> epmap = new ConcurrentHashMap<>();
- endpoints = Collections.newSetFromMap(epmap);
- ConcurrentHashMap<NodeId,Boolean> nomap = new ConcurrentHashMap<>();
- nodes = Collections.newSetFromMap(nomap);
- ConcurrentHashMap<EgKey,Boolean> grmap = new ConcurrentHashMap<>();
- groups = Collections.newSetFromMap(grmap);
-
- groupEps = new ConcurrentHashMap<>();
- nodeEps = new ConcurrentHashMap<>();
- }
-
- public void addEndpointGroupEp(EgKey egKey, EpKey epKey) {
- SetUtils.getNestedSet(egKey, groupEps)
- .add(epKey);
- }
- public void addNodeEp(NodeId id, EpKey epKey) {
- SetUtils.getNestedSet(id, nodeEps).add(epKey);
- }
- public void addNode(NodeId id) {
- nodes.add(id);
- }
- public void addEndpointGroup(EgKey key) {
- groups.add(key);
- }
- public void addEndpoint(EpKey epKey) {
- endpoints.add(epKey);
- }
- public Set<EpKey> getEndpoints() {
- return endpoints;
- }
- public Set<NodeId> getNodes() {
- return nodes;
- }
- public Set<EgKey> getGroups() {
- return groups;
- }
- public ConcurrentMap<EgKey, Set<EpKey>> getGroupEps() {
- return groupEps;
- }
- public ConcurrentMap<NodeId, Set<EpKey>> getNodeEps() {
- return nodeEps;
- }
-
- }
}
return state.externalPorts;
}
+ //TODO OVSDB CRUD belongs in here. (see Trello)
public NodeConnectorId getTunnelPort(NodeId nodeId) {
SwitchState state = switches.get(nodeId);
if (state == null) return null;
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv4;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveRegTunIdAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlDstAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction;
+
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
-import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
-import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
-
/**
- * Manage the table that maps the destination address to the next hop
- * for the path as well as applies any relevant routing transformations.
- * @author readams
+ * Manage the table that maps the destination address to the next hop for the
+ * path as well as applies any relevant routing transformations.
+ *
*/
public class DestinationMapper extends FlowTable {
protected static final Logger LOG =
LoggerFactory.getLogger(DestinationMapper.class);
+ //TODO Li alagalah: Improve UT coverage for this class.
+
+ //TODO Li alagalah: Use EndpointL3 for L3 flows, Endpoint for L2 flows
+ // This ensures we have the appropriate network-containment'
+
public static final short TABLE_ID = 2;
/**
* This is the MAC address of the magical router in the sky
}
@Override
- public void sync(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo, Dirty dirty)
- throws Exception {
- dropFlow(t, tiid, flowMap, Integer.valueOf(1), null);
+ public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap)
+ throws Exception {
+
+ flowMap.writeFlow(nodeId,TABLE_ID,dropFlow(Integer.valueOf(1), null));
- HashSet<EgKey> visitedEgs = new HashSet<>();
- HashSet<Integer> visitedFds = new HashSet<>();
+ Set<EpKey> visitedEps = new HashSet<>();
+ Multimap<Integer,Subnet> subnetsByL3c = HashMultimap.create();
+ Set<Integer> fdIds = new HashSet<>();
for (EgKey epg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
Set<EgKey> peers = Sets.union(Collections.singleton(epg),
- policyInfo.getPeers(epg));
+ policyInfo.getPeers(epg));
for (EgKey peer : peers) {
- syncEPG(t, tiid, flowMap, nodeId,
- policyInfo, peer,
- visitedEgs, visitedFds);
+ for(Endpoint epPeer : ctx.getEndpointManager().getEndpointsForGroup(peer)) {
+ syncEP(flowMap, nodeId, policyInfo, epPeer, visitedEps);
+
+ //Process subnets and flood-domains for epPeer
+ EndpointFwdCtxOrdinals epOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, epPeer);
+
+ subnetsByL3c.putAll(epOrds.getL3Id(),ctx.getPolicyResolver().getTenant(peer.getTenantId()).resolveSubnets(epOrds.getNetworkContainment()));
+ fdIds.add(epOrds.getFdId());
+ }
+ }
+ }
+ // Write subnet flows
+ for (Integer subnetKey : subnetsByL3c.keySet()) {
+ for(Subnet sn:subnetsByL3c.get(subnetKey)) {
+ flowMap.writeFlow(nodeId, TABLE_ID, createRouterArpFlow(nodeId, sn, subnetKey));
+ }
+ }
+ // Write broadcast flows per flood domain.
+ for (Integer fdId : fdIds) {
+ if (groupExists(nodeId, fdId)) {
+ flowMap.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(fdId));
}
}
}
-
// set up next-hop destinations for all the endpoints in the endpoint
// group on the node
- private void syncEPG(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo,
- EgKey key,
- HashSet<EgKey> visitedEgs,
- HashSet<Integer> visitedFds) throws Exception {
- if (visitedEgs.contains(key)) return;
- visitedEgs.add(key);
-
- IndexedTenant tenant = ctx.getPolicyResolver().getTenant(key.getTenantId());
- EndpointGroup eg = tenant.getEndpointGroup(key.getEgId());
- L2FloodDomain fd = tenant.resolveL2FloodDomain(eg.getNetworkDomain());
- Collection<Subnet> sns = tenant.resolveSubnets(eg.getNetworkDomain());
- L3Context l3c = tenant.resolveL3Context(eg.getNetworkDomain());
- int l3Id = 0;
-
- if (l3c != null)
- l3Id = ctx.getPolicyManager().getContextOrdinal(key.getTenantId(),
- l3c.getId());
-
- Collection<Endpoint> egEps = ctx.getEndpointManager()
- .getEndpointsForGroup(key);
-
- for (Endpoint e : egEps) {
- if (e.getTenant() == null || e.getEndpointGroup() == null)
- continue;
- OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
- if (ofc == null || ofc.getNodeId() == null) continue;
-
- syncEP(t, tiid, flowMap, nodeId, policyInfo, e, ofc, tenant, key);
- }
-
- if (fd == null) return;
- Integer fdId = ctx.getPolicyManager().getContextOrdinal(key.getTenantId(),
- fd.getId());
- if (visitedFds.contains(fdId)) return;
- visitedFds.add(fdId);
- //GroupTable must exist before we start adding flows that direct to it via fdId
- if(groupExists(nodeId,fdId)) {
- FlowId flowId = new FlowId(new StringBuilder()
- .append("broadcast|")
- .append(fdId).toString());
- if (visit(flowMap, flowId.getValue())) {
- MatchBuilder mb = new MatchBuilder()
+ private Flow createBroadcastFlow(int fdId) {
+ FlowId flowId = new FlowId(new StringBuilder()
+ .append("broadcast|")
+ .append(fdId).toString());
+ MatchBuilder mb = new MatchBuilder()
.setEthernetMatch(new EthernetMatchBuilder()
- .setEthernetDestination(new EthernetDestinationBuilder()
- .setAddress(MULTICAST_MAC)
- .setMask(MULTICAST_MAC)
- .build())
- .build());
- addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class,Long.valueOf(fdId)));
-
- FlowBuilder flow = base()
- .setPriority(Integer.valueOf(140))
- .setId(flowId)
- .setMatch(mb.build())
- .setInstructions(instructions(applyActionIns(nxMoveRegTunIdAction(NxmNxReg0.class, false),
- groupAction(Long.valueOf(fdId)))));
- writeFlow(t, tiid, flow.build());
- }
- }
- for (Subnet sn : sns) {
- writeRouterArpFlow(t, tiid, flowMap, nodeId, sn, l3Id);
- }
+ .setEthernetDestination(new EthernetDestinationBuilder()
+ .setAddress(MULTICAST_MAC)
+ .setMask(MULTICAST_MAC)
+ .build())
+ .build());
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(fdId)));
+
+ FlowBuilder flowb = base()
+ .setPriority(Integer.valueOf(140))
+ .setId(flowId)
+ .setMatch(mb.build())
+ .setInstructions(instructions(applyActionIns(nxMoveRegTunIdAction(NxmNxReg0.class, false),
+ groupAction(Long.valueOf(fdId)))));
+ return flowb.build();
}
+
+
private boolean groupExists(NodeId nodeId, Integer fdId) throws Exception {
- //Fetch existing GroupTables
- if(ctx.getDataBroker()==null) return false;
+ // Fetch existing GroupTables
+ if(ctx.getDataBroker()==null) {
+ return false;
+ }
ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction();
InstanceIdentifier<Node> niid = createNodePath(nodeId);
Optional<Node> r =
t.read(LogicalDatastoreType.CONFIGURATION, niid).get();
- if (!r.isPresent()) return false;
+ if (!r.isPresent())
+ return false;
FlowCapableNode fcn = r.get().getAugmentation(FlowCapableNode.class);
- if (fcn == null) return false;
+ if (fcn == null)
+ return false;
if (fcn.getGroup() != null) {
for (Group g : fcn.getGroup()) {
- if (g.getGroupId().getValue().equals(Long.valueOf(fdId))) { //Group Exists.
+ if (g.getGroupId().getValue().equals(Long.valueOf(fdId))) { // Group
+ // Exists.
return true;
}
-
}
}
return false;
}
- private void writeRouterArpFlow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId,
- Subnet sn,
- int l3Id) {
+ private Flow createRouterArpFlow(NodeId nodeId,
+ Subnet sn,
+ int l3Id) {
if (sn != null && sn.getVirtualRouterIp() != null) {
if (sn.getVirtualRouterIp().getIpv4Address() != null) {
String ikey = sn.getVirtualRouterIp().getIpv4Address().getValue();
FlowId flowId = new FlowId(new StringBuffer()
- .append("routerarp|")
- .append(sn.getId().getValue())
- .append("|")
- .append(ikey)
- .append("|")
- .append(l3Id)
- .toString());
- if (visit(flowMap, flowId.getValue())) {
+ .append("routerarp|")
+ .append(sn.getId().getValue())
+ .append("|")
+ .append(ikey)
+ .append("|")
+ .append(l3Id)
+ .toString());
MatchBuilder mb = new MatchBuilder()
- .setEthernetMatch(ethernetMatch(null, null, ARP))
- .setLayer3Match(new ArpMatchBuilder()
- .setArpOp(Integer.valueOf(1))
- .setArpTargetTransportAddress(new Ipv4Prefix(ikey+"/32"))
- .build());
+ .setEthernetMatch(ethernetMatch(null, null, ARP))
+ .setLayer3Match(new ArpMatchBuilder()
+ .setArpOp(Integer.valueOf(1))
+ .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32"))
+ .build());
addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class,
- Long.valueOf(l3Id)));
+ Long.valueOf(l3Id)));
BigInteger routerMac =
new BigInteger(1, bytesFromHexString(ROUTER_MAC
- .getValue()));
+ .getValue()));
FlowBuilder flowb = base()
- .setPriority(150)
- .setId(flowId)
- .setMatch(mb.build())
- .setInstructions(instructions(applyActionIns(nxMoveEthSrcToEthDstAction(),
- setDlSrcAction(ROUTER_MAC),
- nxLoadArpOpAction(BigInteger.valueOf(2L)),
- nxMoveArpShaToArpThaAction(),
- nxLoadArpShaAction(routerMac),
- nxMoveArpSpaToArpTpaAction(),
- nxLoadArpSpaAction(ikey),
- outputAction(new NodeConnectorId(nodeId.getValue() + ":INPORT")))));
- writeFlow(t, tiid, flowb.build());
- }
+ .setPriority(150)
+ .setId(flowId)
+ .setMatch(mb.build())
+ .setInstructions(instructions(applyActionIns(nxMoveEthSrcToEthDstAction(),
+ setDlSrcAction(ROUTER_MAC),
+ nxLoadArpOpAction(BigInteger.valueOf(2L)),
+ nxMoveArpShaToArpThaAction(),
+ nxLoadArpShaAction(routerMac),
+ nxMoveArpSpaToArpTpaAction(),
+ nxLoadArpSpaAction(ikey),
+ outputAction(new NodeConnectorId(nodeId.getValue() + ":INPORT")))));
+ return flowb.build();
} else {
LOG.warn("IPv6 virtual router {} for subnet {} not supported",
- sn.getVirtualRouterIp(), sn.getId().getValue());
+ sn.getVirtualRouterIp(), sn.getId().getValue());
}
}
+ return null;
}
- private void syncEP(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo,
- Endpoint e, OfOverlayContext ofc,
- IndexedTenant tenant, EgKey key)
- throws Exception {
+
+ private Flow createLocalL2Flow(Endpoint ep, EndpointFwdCtxOrdinals epFwdCtxOrds, OfOverlayContext ofc) {
+
+ //TODO Li alagalah - refactor common code but keep simple method
ArrayList<Instruction> instructions = new ArrayList<>();
- ArrayList<Instruction> l3instructions = new ArrayList<>();
List<Action> applyActions = new ArrayList<>();
- List<Action> l3ApplyActions = new ArrayList<>();
int order = 0;
- EndpointGroup eg = tenant.getEndpointGroup(e.getEndpointGroup());
- L3Context l3c = tenant.resolveL3Context(eg.getNetworkDomain());
- L2BridgeDomain bd = tenant.resolveL2BridgeDomain(eg.getNetworkDomain());
-
- int egId = 0, bdId = 0, l3Id = 0, cgId = 0;
-
- egId = ctx.getPolicyManager().getContextOrdinal(e.getTenant(),
- e.getEndpointGroup());
- if (bd != null)
- bdId = ctx.getPolicyManager().getContextOrdinal(e.getTenant(),
- bd.getId());
- if (l3c != null)
- l3Id = ctx.getPolicyManager().getContextOrdinal(e.getTenant(),
- l3c.getId());
-
- List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(e);
- ConditionGroup cg =
- policyInfo.getEgCondGroup(new EgKey(e.getTenant(),
- e.getEndpointGroup()),
- conds);
- cgId = ctx.getPolicyManager().getCondGroupOrdinal(cg);
+
Action setdEPG = nxLoadRegAction(NxmNxReg2.class,
- BigInteger.valueOf(egId));
+ BigInteger.valueOf(epFwdCtxOrds.getEpgId()));
Action setdCG = nxLoadRegAction(NxmNxReg3.class,
- BigInteger.valueOf(cgId));
+ BigInteger.valueOf(epFwdCtxOrds.getCgId()));
Action setNextHop;
String nextHop;
+
+
+
+ // BEGIN L2 LOCAL
+ nextHop = ofc.getNodeConnectorId().getValue();
+
+ long portNum;
+ try {
+ portNum = getOfPortNum(ofc.getNodeConnectorId());
+ } catch (NumberFormatException ex) {
+ LOG.warn("Could not parse port number {}",
+ ofc.getNodeConnectorId(), ex);
+ return null;
+ }
+
+ setNextHop = nxLoadRegAction(NxmNxReg7.class,
+ BigInteger.valueOf(portNum));
+
+ //END L2 LOCAL
+
+ order += 1;
+ applyActions.add(setdEPG);
+ applyActions.add(setdCG);
+ applyActions.add(setNextHop);
+ Instruction applyActionsIns = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
+ .build();
+ instructions.add(applyActionsIns);
+
+ Instruction gotoTable = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(gotoTableIns((short) (getTableId() + 1)))
+ .build();
+ instructions.add(gotoTable);
+
+
+ FlowId flowid = new FlowId(new StringBuilder()
+ .append(epFwdCtxOrds.getBdId())
+ .append("|l2|")
+ .append(ep.getMacAddress().getValue())
+ .append("|")
+ .append(nextHop)
+ .toString());
+ MatchBuilder mb = new MatchBuilder()
+ .setEthernetMatch(ethernetMatch(null,
+ ep.getMacAddress(),
+ null));
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(epFwdCtxOrds.getBdId())));
+ FlowBuilder flowb = base()
+ .setId(flowid)
+ .setPriority(Integer.valueOf(50))
+ .setMatch(mb.build())
+ .setInstructions(new InstructionsBuilder()
+ .setInstruction(instructions)
+ .build());
+ return flowb.build();
+ }
+
+
+ private void syncEP(FlowMap flowMap,
+ NodeId nodeId, PolicyInfo policyInfo,
+ Endpoint epPeer, Set<EpKey> visitedEps)
+ throws Exception {
+
+ EpKey epPeerKey = new EpKey(epPeer.getL2Context(),epPeer.getMacAddress());
+
+ if (visitedEps.contains(epPeerKey)) {
+ return;
+ }
+ visitedEps.add(epPeerKey);
+
+ // TODO: Conditions messed up, but for now, send policyInfo until this is fixed.
+ EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, epPeer);
+
+ if (epPeer.getTenant() == null || (epPeer.getEndpointGroup() == null && epPeer.getEndpointGroups() == null))
+ return;
+ OfOverlayContext ofc = epPeer.getAugmentation(OfOverlayContext.class);
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ /*
+ * NOT HANDLING EXTERNALS
+ */
if (LocationType.External.equals(ofc.getLocationType())) {
// XXX - TODO - perform NAT and send to the external network
- nextHop = "external";
+ // TODO: Use case neutron gateway interface
LOG.warn("External endpoints not yet supported");
return;
- } else {
- Action setDlSrc = setDlSrcAction(ROUTER_MAC);
- Action decTtl = decNwTtlAction();
-
- if (Objects.equals(ofc.getNodeId(), nodeId)) {
- // this is a local endpoint; send to the approppriate local
- // port
- nextHop = ofc.getNodeConnectorId().getValue();
-
- long portNum;
- try {
- portNum = getOfPortNum(ofc.getNodeConnectorId());
- } catch (NumberFormatException ex) {
- LOG.warn("Could not parse port number {}",
- ofc.getNodeConnectorId(), ex);
- return;
- }
+ }
- setNextHop = nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(portNum));
+ if (Objects.equals(ofc.getNodeId(), nodeId)) {
+ // this is a local endpoint; send to the approppriate local
+ // port
- Action setDlDst = setDlDstAction(e.getMacAddress());
- l3ApplyActions.add(setDlSrc);
- l3ApplyActions.add(setDlDst);
- l3ApplyActions.add(decTtl);
- order +=1;
- } else {
- // this endpoint is on a different switch; send to the
- // appropriate tunnel
-
- IpAddress tunDst =
- ctx.getSwitchManager().getTunnelIP(ofc.getNodeId());
- NodeConnectorId tunPort =
- ctx.getSwitchManager().getTunnelPort(nodeId);
- if (tunDst == null) return;
- if (tunPort == null) return;
-
- Action tundstAction;
-
- if (tunDst.getIpv4Address() != null) {
- nextHop = tunDst.getIpv4Address().getValue();
- tundstAction = nxLoadTunIPv4Action(nextHop, false);
- } else if (tunDst.getIpv6Address() != null) {
- // nextHop = tunDst.getIpv6Address().getValue();
- LOG.error("IPv6 tunnel destination {} for {} not supported",
- tunDst.getIpv6Address().getValue(),
- ofc.getNodeId());
- return;
+ flowMap.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(epPeer,epFwdCtxOrds,ofc));
+
+ if (epPeer.getL3Address() == null)
+ return;
+ for (L3Address l3a : epPeer.getL3Address()) {
+ if (l3a.getIpAddress() == null || l3a.getL3Context() == null) {
+ LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}",epPeer.getL3Address().toString());
+ continue;
} else {
- // this shouldn't happen
- LOG.error("Tunnel IP for {} invalid", ofc.getNodeId());
- return;
+ flowMap.writeFlow(nodeId, TABLE_ID, createLocalL3Flow(epPeer,l3a, epFwdCtxOrds,ofc));
}
+ }
+ } else {
+ // this endpoint is on a different switch; send to the
+ // appropriate tunnel
+ flowMap.writeFlow(nodeId, TABLE_ID, createRemoteL2Flow(epPeer, nodeId, epFwdCtxOrds, ofc));
- long portNum;
- try {
- portNum = getOfPortNum(tunPort);
- } catch (NumberFormatException ex) {
- LOG.warn("Could not parse port number {}",
- ofc.getNodeConnectorId(), ex);
- return;
+ if (epPeer.getL3Address() == null)
+ return;
+ for (L3Address l3a : epPeer.getL3Address()) {
+ if (l3a.getIpAddress() == null || l3a.getL3Context() == null) {
+ LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}",epPeer.getL3Address().toString());
+ continue;
+ } else {
+ flowMap.writeFlow(nodeId, TABLE_ID, createRemoteL3Flow(l3a, nodeId,epFwdCtxOrds, ofc));
}
+ }
+ } // remote (tunnel)
- setNextHop = nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(portNum));
- Action tunIdAction =
- nxMoveRegTunIdAction(NxmNxReg0.class, false);
- applyActions.add(tunIdAction);
- applyActions.add(tundstAction);
- l3ApplyActions.add(setDlSrc);
- l3ApplyActions.add(decTtl);
- order +=1;
- }
+
+ // }
+
+ }
+
+ /* ##################################
+ * DestMapper Flow methods
+ * ##################################
+ */
+ private Flow createLocalL3Flow(Endpoint ep,L3Address l3a, EndpointFwdCtxOrdinals epFwdCtxOrds,OfOverlayContext ofc) {
+
+ //TODO Li alagalah - refactor common code but keep simple method
+
+ ArrayList<Instruction> l3instructions = new ArrayList<>();
+ List<Action> applyActions = new ArrayList<>();
+ List<Action> l3ApplyActions = new ArrayList<>();
+
+ int order = 0;
+
+ Action setdEPG = nxLoadRegAction(NxmNxReg2.class,
+ BigInteger.valueOf(epFwdCtxOrds.getEpgId()));
+ Action setdCG = nxLoadRegAction(NxmNxReg3.class,
+ BigInteger.valueOf(epFwdCtxOrds.getCgId()));
+ Action setNextHop;
+ String nextHop;
+
+ Action setDlSrc = setDlSrcAction(ROUTER_MAC);
+ Action decTtl = decNwTtlAction();
+
+ // BEGIN L3 LOCAL
+ nextHop = ofc.getNodeConnectorId().getValue();
+
+ long portNum;
+ try {
+ portNum = getOfPortNum(ofc.getNodeConnectorId());
+ } catch (NumberFormatException ex) {
+ LOG.warn("Could not parse port number {}",
+ ofc.getNodeConnectorId(), ex);
+ return null;
+ }
+
+ setNextHop = nxLoadRegAction(NxmNxReg7.class,
+ BigInteger.valueOf(portNum));
+
+ Action setDlDst = setDlDstAction(ep.getMacAddress());
+ l3ApplyActions.add(setDlDst);
+ //END L3 LOCAL
+
+ l3ApplyActions.add(setDlSrc);
+ l3ApplyActions.add(decTtl);
+ order += 1;
+ applyActions.add(setdEPG);
+ applyActions.add(setdCG);
+ applyActions.add(setNextHop);
+
+ applyActions.addAll(l3ApplyActions);
+ Instruction applyActionsIns = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
+ .build();
+
+ l3instructions.add(applyActionsIns);
+ Instruction gotoTable = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(gotoTableIns((short) (getTableId() + 1)))
+ .build();
+ l3instructions.add(gotoTable);
+ Layer3Match m = null;
+ Long etherType = null;
+ String ikey = null;
+ if (l3a.getIpAddress().getIpv4Address() != null) {
+ ikey = l3a.getIpAddress().getIpv4Address().getValue() + "/32";
+ etherType = IPv4;
+ m = new Ipv4MatchBuilder()
+ .setIpv4Destination(new Ipv4Prefix(ikey))
+ .build();
+ } else if (l3a.getIpAddress().getIpv6Address() != null) {
+ ikey = l3a.getIpAddress().getIpv6Address().getValue() + "/128";
+ etherType = IPv6;
+ m = new Ipv6MatchBuilder()
+ .setIpv6Destination(new Ipv6Prefix(ikey))
+ .build();
+ } else {
+ LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.",l3a.toString());
+ return null;
+ }
+
+ FlowId flowid = new FlowId(new StringBuilder()
+ .append(Integer.toString(epFwdCtxOrds.getL3Id()))
+ .append("|l3|")
+ .append(ikey)
+ .append("|")
+ .append(Integer.toString(epFwdCtxOrds.getEpgId()))
+ .append(" ")
+ .append(Integer.toString(epFwdCtxOrds.getCgId()))
+ .append("|")
+ .append(nextHop)
+ .toString());
+ MatchBuilder mb = new MatchBuilder()
+ .setEthernetMatch(ethernetMatch(null,
+ ROUTER_MAC,
+ etherType))
+ .setLayer3Match(m);
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class,
+ Long.valueOf(epFwdCtxOrds.getL3Id())));
+ FlowBuilder flowb = base()
+ .setId(flowid)
+ .setPriority(Integer.valueOf(132))
+ .setMatch(mb.build())
+ .setInstructions(new InstructionsBuilder()
+ .setInstruction(l3instructions)
+ .build());
+ return flowb.build();
+ }
+
+ private Flow createRemoteL2Flow(Endpoint ep, NodeId nodeId, EndpointFwdCtxOrdinals epFwdCtxOrds, OfOverlayContext ofc) {
+
+ //TODO Li alagalah - refactor common code but keep simple method
+
+ // this endpoint is on a different switch; send to the
+ // appropriate tunnel
+
+ ArrayList<Instruction> instructions = new ArrayList<>();
+ List<Action> applyActions = new ArrayList<>();
+
+
+ int order = 0;
+
+ Action setdEPG = nxLoadRegAction(NxmNxReg2.class,
+ BigInteger.valueOf(epFwdCtxOrds.getEpgId()));
+ Action setdCG = nxLoadRegAction(NxmNxReg3.class,
+ BigInteger.valueOf(epFwdCtxOrds.getCgId()));
+ Action setNextHop;
+ String nextHop;
+
+ // BEGIN TUNNEL HANDLING
+ IpAddress tunDst =
+ ctx.getSwitchManager().getTunnelIP(ofc.getNodeId());
+ NodeConnectorId tunPort =
+ ctx.getSwitchManager().getTunnelPort(nodeId);
+ if (tunDst == null)
+ return null;
+ if (tunPort == null)
+ return null;
+
+ Action tundstAction;
+
+ if (tunDst.getIpv4Address() != null) {
+ nextHop = tunDst.getIpv4Address().getValue();
+ tundstAction = nxLoadTunIPv4Action(nextHop, false);
+ } else if (tunDst.getIpv6Address() != null) {
+ // nextHop = tunDst.getIpv6Address().getValue();
+ LOG.error("IPv6 tunnel destination {} for {} not supported",
+ tunDst.getIpv6Address().getValue(),
+ ofc.getNodeId());
+ return null;
+ } else {
+ // this shouldn't happen
+ LOG.error("Tunnel IP for {} invalid", ofc.getNodeId());
+ return null;
}
+
+ long portNum;
+ try {
+ portNum = getOfPortNum(tunPort);
+ } catch (NumberFormatException ex) {
+ LOG.warn("Could not parse port number {}",
+ ofc.getNodeConnectorId(), ex);
+ return null;
+ }
+
+ setNextHop = nxLoadRegAction(NxmNxReg7.class,
+ BigInteger.valueOf(portNum));
+ Action tunIdAction =
+ nxMoveRegTunIdAction(NxmNxReg0.class, false);
+
+ applyActions.add(tunIdAction);
+ applyActions.add(tundstAction);
+ // END TUNNEL
+
+ order += 1;
applyActions.add(setdEPG);
applyActions.add(setdCG);
applyActions.add(setNextHop);
Instruction applyActionsIns = new InstructionBuilder()
- .setOrder(order++)
- .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
- .build();
+ .setOrder(order++)
+ .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
+ .build();
instructions.add(applyActionsIns);
- applyActions.addAll(l3ApplyActions);
applyActionsIns = new InstructionBuilder()
- .setOrder(order++)
- .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
- .build();
- l3instructions.add(applyActionsIns);
+ .setOrder(order++)
+ .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
+ .build();
Instruction gotoTable = new InstructionBuilder()
- .setOrder(order++)
- .setInstruction(gotoTableIns((short)(getTableId()+1)))
- .build();
+ .setOrder(order++)
+ .setInstruction(gotoTableIns((short) (getTableId() + 1)))
+ .build();
instructions.add(gotoTable);
- l3instructions.add(gotoTable);
FlowId flowid = new FlowId(new StringBuilder()
- .append(bdId)
- .append("|l2|")
- .append(e.getMacAddress().getValue())
- .append("|")
- .append(nextHop)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- MatchBuilder mb = new MatchBuilder()
+ .append(epFwdCtxOrds.getBdId())
+ .append("|l2|")
+ .append(ep.getMacAddress().getValue())
+ .append("|")
+ .append(nextHop)
+ .toString());
+ MatchBuilder mb = new MatchBuilder()
.setEthernetMatch(ethernetMatch(null,
- e.getMacAddress(),
- null));
- addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(bdId)));
- FlowBuilder flowb = base()
+ ep.getMacAddress(),
+ null));
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(epFwdCtxOrds.getBdId())));
+ FlowBuilder flowb = base()
.setId(flowid)
.setPriority(Integer.valueOf(50))
.setMatch(mb.build())
.setInstructions(new InstructionsBuilder()
- .setInstruction(instructions)
- .build());
+ .setInstruction(instructions)
+ .build());
+
+ return flowb.build();
+ }
+
+
+ private Flow createRemoteL3Flow(L3Address l3a, NodeId nodeId, EndpointFwdCtxOrdinals epFwdCtxOrds,OfOverlayContext ofc) {
+
+ //TODO Li alagalah - refactor common code but keep simple method
+
+
+ // this endpoint is on a different switch; send to the
+ // appropriate tunnel
+
+ ArrayList<Instruction> l3instructions = new ArrayList<>();
+ List<Action> applyActions = new ArrayList<>();
+ List<Action> l3ApplyActions = new ArrayList<>();
+
+
+ int order = 0;
+
+ Action setdEPG = nxLoadRegAction(NxmNxReg2.class,
+ BigInteger.valueOf(epFwdCtxOrds.getEpgId()));
+ Action setdCG = nxLoadRegAction(NxmNxReg3.class,
+ BigInteger.valueOf(epFwdCtxOrds.getCgId()));
+ Action setNextHop;
+ String nextHop;
+
+ Action setDlSrc = setDlSrcAction(ROUTER_MAC);
+ Action decTtl = decNwTtlAction();
+
+ // BEGIN TUNNEL HANDLING
+ IpAddress tunDst =
+ ctx.getSwitchManager().getTunnelIP(ofc.getNodeId());
+ NodeConnectorId tunPort =
+ ctx.getSwitchManager().getTunnelPort(nodeId);
+ if (tunDst == null)
+ return null;
+ if (tunPort == null)
+ return null;
+
+ Action tundstAction;
+
+ if (tunDst.getIpv4Address() != null) {
+ nextHop = tunDst.getIpv4Address().getValue();
+ tundstAction = nxLoadTunIPv4Action(nextHop, false);
+ } else if (tunDst.getIpv6Address() != null) {
+ // nextHop = tunDst.getIpv6Address().getValue();
+ LOG.error("IPv6 tunnel destination {} for {} not supported",
+ tunDst.getIpv6Address().getValue(),
+ ofc.getNodeId());
+ return null;
+ } else {
+ // this shouldn't happen
+ LOG.error("Tunnel IP for {} invalid", ofc.getNodeId());
+ return null;
+ }
- writeFlow(t, tiid, flowb.build());
+ long portNum;
+ try {
+ portNum = getOfPortNum(tunPort);
+ } catch (NumberFormatException ex) {
+ LOG.warn("Could not parse port number {}",
+ ofc.getNodeConnectorId(), ex);
+ return null;
}
- if (e.getL3Address() == null) return;
- for (L3Address l3a : e.getL3Address()) {
- if (l3a.getIpAddress() == null || l3a.getL3Context() == null)
- continue;
- Layer3Match m = null;
- Long etherType = null;
- String ikey = null;
- if (l3a.getIpAddress().getIpv4Address() != null) {
- ikey = l3a.getIpAddress().getIpv4Address().getValue() + "/32";
- etherType = IPv4;
- m = new Ipv4MatchBuilder()
+
+ setNextHop = nxLoadRegAction(NxmNxReg7.class,
+ BigInteger.valueOf(portNum));
+ Action tunIdAction =
+ nxMoveRegTunIdAction(NxmNxReg0.class, false);
+
+ applyActions.add(tunIdAction);
+ applyActions.add(tundstAction);
+ // END TUNNEL
+
+
+ l3ApplyActions.add(setDlSrc);
+ l3ApplyActions.add(decTtl);
+ order += 1;
+ applyActions.add(setdEPG);
+ applyActions.add(setdCG);
+ applyActions.add(setNextHop);
+ l3ApplyActions.add(setDlSrc);
+ l3ApplyActions.add(decTtl);
+
+ applyActions.addAll(l3ApplyActions);
+ Instruction applyActionsIns = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
+ .build();
+
+ l3instructions.add(applyActionsIns);
+ Instruction gotoTable = new InstructionBuilder()
+ .setOrder(order++)
+ .setInstruction(gotoTableIns((short) (getTableId() + 1)))
+ .build();
+ l3instructions.add(gotoTable);
+ Layer3Match m = null;
+ Long etherType = null;
+ String ikey = null;
+ if (l3a.getIpAddress().getIpv4Address() != null) {
+ ikey = l3a.getIpAddress().getIpv4Address().getValue() + "/32";
+ etherType = IPv4;
+ m = new Ipv4MatchBuilder()
.setIpv4Destination(new Ipv4Prefix(ikey))
.build();
- } else if (l3a.getIpAddress().getIpv6Address() != null) {
- ikey = l3a.getIpAddress().getIpv6Address().getValue() + "/128";
- etherType = IPv6;
- m = new Ipv6MatchBuilder()
+ } else if (l3a.getIpAddress().getIpv6Address() != null) {
+ ikey = l3a.getIpAddress().getIpv6Address().getValue() + "/128";
+ etherType = IPv6;
+ m = new Ipv6MatchBuilder()
.setIpv6Destination(new Ipv6Prefix(ikey))
.build();
- } else
- continue;
+ } else {
+ LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.",l3a.toString());
+ return null;
+ }
- flowid = new FlowId(new StringBuilder()
- .append(l3a.getL3Context().getValue())
+ FlowId flowid = new FlowId(new StringBuilder()
+ .append(Integer.toString(epFwdCtxOrds.getL3Id()))
.append("|l3|")
.append(ikey)
.append("|")
+ .append(Integer.toString(epFwdCtxOrds.getEpgId()))
+ .append(" ")
+ .append(Integer.toString(epFwdCtxOrds.getCgId()))
+ .append("|")
.append(nextHop)
.toString());
- if (visit(flowMap, flowid.getValue())) {
- MatchBuilder mb = new MatchBuilder()
- .setEthernetMatch(ethernetMatch(null,
- ROUTER_MAC,
- etherType))
- .setLayer3Match(m);
- addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class,
- Long.valueOf(l3Id)));
- FlowBuilder flowb = base()
- .setId(flowid)
- .setPriority(Integer.valueOf(132))
- .setMatch(mb.build())
- .setInstructions(new InstructionsBuilder()
+ MatchBuilder mb = new MatchBuilder()
+ .setEthernetMatch(ethernetMatch(null,
+ ROUTER_MAC,
+ etherType))
+ .setLayer3Match(m);
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class,
+ Long.valueOf(epFwdCtxOrds.getL3Id())));
+ FlowBuilder flowb = base()
+ .setId(flowid)
+ .setPriority(Integer.valueOf(132))
+ .setMatch(mb.build())
+ .setInstructions(new InstructionsBuilder()
.setInstruction(l3instructions)
.build());
-
- writeFlow(t, tiid, flowb.build());
- }
- }
+ return flowb.build();
}
+
static byte[] bytesFromHexString(String values) {
String target = "";
if (values != null) {
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
/**
* Base class for managing flow tables
* @author readams
@Override
public void update(NodeId nodeId, PolicyInfo policyInfo,
- Dirty dirty) throws Exception {
- ReadWriteTransaction t = ctx.getDataBroker().newReadWriteTransaction();
- InstanceIdentifier<Table> tiid =
- FlowUtils.createTablePath(nodeId, getTableId());
- Optional<Table> r =
- t.read(LogicalDatastoreType.CONFIGURATION, tiid).get();
-
- // Unfortunately, we need to construct a unique string ID for each
- // flow which is redundant with all the information in the flow itself
- // We'll build this map so at least we don't have to be O(n^2)
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
-
- if (r.isPresent()) {
- Table curTable = (Table)r.get();
-
- if (curTable.getFlow() != null) {
- for (Flow f : curTable.getFlow()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- }
- }
- }
-
- sync(t, tiid, flowMap, nodeId, policyInfo, dirty);
-
- for (FlowCtx fx : flowMap.values()) {
- if (!fx.visited) {
- t.delete(LogicalDatastoreType.CONFIGURATION,
- FlowUtils.createFlowPath(tiid, fx.f.getKey()));
- }
- }
-
- t.submit().get();
- //ListenableFuture<Void> result = t.submit();
- //Futures.addCallback(result, updateCallback);
+ FlowMap flowMap) throws Exception {
+
+ sync(nodeId, policyInfo, flowMap);
+
}
// *********
* Sync flow state using the flow map
* @throws Exception
*/
- public abstract void sync(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo,
- Dirty dirty) throws Exception;
+ public abstract void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception;
/**
* Get the table ID being manipulated
.setIdleTimeout(0);
}
- /**
- * "Visit" a flow ID by checking if it already exists and if so marking
- * the {@link FlowCtx} visited bit.
- * @param flowMap the map containing the existing flows for this table
- * @param flowId the ID for the flow
- * @return <code>true</code> if the flow needs to be added
- */
- protected static boolean visit(Map<String, FlowCtx> flowMap,
- String flowId) {
- FlowCtx c = flowMap.get(flowId);
- if (c != null) {
- c.visited = true;
- return false;
- }
- return true;
- }
-
- /**
- * Write the given flow to the transaction
- */
- protected static void writeFlow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Flow flow) {
- LOG.trace("{} {}", flow.getId(), flow);
- t.put(LogicalDatastoreType.CONFIGURATION,
- FlowUtils.createFlowPath(tiid, flow.getId()),
- flow, true);
- }
-
/**
* Write a drop flow for the given ethertype at the given priority.
* If the ethertype is null, then drop all traffic
*/
- protected void dropFlow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Integer priority, Long etherType) {
+ public Flow dropFlow(Integer priority, Long etherType) {
FlowId flowid = new FlowId(new StringBuilder()
- .append("drop|")
- .append(etherType)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- FlowBuilder flowb = base()
+ .append("drop|")
+ .append(etherType)
+ .toString());
+
+ FlowBuilder flowb = base()
.setId(flowid)
.setPriority(priority)
.setInstructions(FlowUtils.dropInstructions());
- if (etherType != null)
- flowb.setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(null, null,
- etherType))
- .build());
- writeFlow(t, tiid, flowb.build());
- }
+ if (etherType != null)
+ flowb.setMatch(new MatchBuilder()
+ .setEthernetMatch(FlowUtils.ethernetMatch(null, null,
+ etherType))
+ .build());
+ return flowb.build();
}
- /**
- * Context object for keeping track of flow state
- */
- protected static class FlowCtx {
- Flow f;
- boolean visited = false;
-
- public FlowCtx(Flow f) {
- super();
- this.f = f;
- }
- }
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.actionList;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createBucketPath;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createGroupPath;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
-import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import com.google.common.base.Optional;
import com.google.common.collect.Ordering;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
-
/**
* Manage the group tables for handling broadcast/multicast
- * @author readams
+ *
*/
+
public class GroupTable extends OfTable {
private static final Logger LOG =
LoggerFactory.getLogger(GroupTable.class);
super(ctx);
}
+ // @Override
@Override
- public void update(NodeId nodeId, PolicyInfo policyInfo, Dirty dirty)
+ public void update(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap)
throws Exception {
// there appears to be no way of getting only the existing group
// tables unfortunately, so we have to get the whole goddamned node.
InstanceIdentifier<Node> niid = createNodePath(nodeId);
Optional<Node> r =
t.read(LogicalDatastoreType.CONFIGURATION, niid).get();
- if (!r.isPresent()) return;
+ if (!r.isPresent())
+ return;
FlowCapableNode fcn = r.get().getAugmentation(FlowCapableNode.class);
- if (fcn == null) return;
+ if (fcn == null)
+ return;
HashMap<GroupId, GroupCtx> groupMap = new HashMap<>();
Buckets bs = g.getBuckets();
if (bs != null && bs.getBucket() != null)
- for (Bucket b : bs.getBucket()) {
- gctx.bucketMap.put(b.getBucketId(), new BucketCtx(b));
- }
+ for (Bucket b : bs.getBucket()) {
+ gctx.bucketMap.put(b.getBucketId(), new BucketCtx(b));
+ }
}
}
- sync(nodeId, policyInfo, dirty, groupMap);
+ // sync(nodeId, policyInfo, dirty, groupMap);
+ sync(nodeId, policyInfo, groupMap);
WriteTransaction wt = ctx.getDataBroker().newWriteOnlyTransaction();
boolean wrote = syncGroupToStore(wt, nodeId, groupMap);
}
protected boolean syncGroupToStore(WriteTransaction wt,
- NodeId nodeId,
- HashMap<GroupId, GroupCtx> groupMap) {
+ NodeId nodeId,
+ HashMap<GroupId, GroupCtx> groupMap) {
boolean wrote = false;
for (GroupCtx gctx : groupMap.values()) {
InstanceIdentifier<Group> giid =
// update group table
for (BucketCtx bctx : gctx.bucketMap.values()) {
BucketId bid;
- if (bctx.b != null) bid = bctx.b.getBucketId();
- else bid = bctx.newb.getBucketId();
+ if (bctx.b != null)
+ bid = bctx.b.getBucketId();
+ else
+ bid = bctx.newb.getBucketId();
InstanceIdentifier<Bucket> biid =
createBucketPath(nodeId,
- gctx.groupId,
- bid);
+ gctx.groupId,
+ bid);
if (!bctx.visited) {
// remove bucket
wrote = true;
// new bucket
buckets.add(bctx.newb);
} else if (!Objects.equal(bctx.newb.getAction(),
- Ordering.from(ActionComparator.INSTANCE)
- .sortedCopy(bctx.b.getAction()))) {
+ Ordering.from(ActionComparator.INSTANCE)
+ .sortedCopy(bctx.b.getAction()))) {
// update bucket
buckets.add(bctx.newb);
}
}
if (buckets.size() > 0) {
GroupBuilder gb = new GroupBuilder()
- .setGroupId(gctx.groupId)
- .setGroupType(GroupTypes.GroupAll)
- .setBuckets(new BucketsBuilder()
- .setBucket(buckets)
- .build());
+ .setGroupId(gctx.groupId)
+ .setGroupType(GroupTypes.GroupAll)
+ .setBuckets(new BucketsBuilder()
+ .setBucket(buckets)
+ .build());
wrote = true;
wt.merge(LogicalDatastoreType.CONFIGURATION,
- giid, gb.build());
+ giid, gb.build());
}
}
}
return wrote;
}
- protected void sync(NodeId nodeId, PolicyInfo policyInfo, Dirty dirty,
- HashMap<GroupId, GroupCtx> groupMap) throws Exception {
-
- for (EgKey epg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
- IndexedTenant it = ctx.getPolicyResolver().getTenant(epg.getTenantId());
- if (it == null) continue;
- EndpointGroup eg = it.getEndpointGroup(epg.getEgId());
- if (eg == null || eg.getNetworkDomain() == null) continue;
- L2FloodDomain fd = it.resolveL2FloodDomain(eg.getNetworkDomain());
- if (fd == null) continue;
-
- int fdId = ctx.getPolicyManager().getContextOrdinal(epg.getTenantId(),
- fd.getId());
- GroupId gid = new GroupId(Long.valueOf(fdId));
- GroupCtx gctx = groupMap.get(gid);
- if (gctx == null) {
- groupMap.put(gid, gctx = new GroupCtx(gid));
- }
- gctx.visited = true;
-
- // we'll use the fdId with the high bit set for remote bucket
- // and just the local port number for local bucket
- for (NodeId destNode : ctx.getEndpointManager().getNodesForGroup(epg)) {
- if (nodeId.equals(destNode)) continue;
-
- long bucketId = ctx.getPolicyManager()
- .getContextOrdinal(destNode.getValue());
- bucketId |= 1L << 31;
-
- IpAddress tunDst =
- ctx.getSwitchManager().getTunnelIP(destNode);
- NodeConnectorId tunPort =
- ctx.getSwitchManager().getTunnelPort(nodeId);
- if (tunDst == null || tunPort == null) continue;
- Action tundstAction = null;
- if (tunDst.getIpv4Address() != null) {
- String nextHop = tunDst.getIpv4Address().getValue();
- tundstAction = nxLoadTunIPv4Action(nextHop, true);
- } else {
- LOG.error("IPv6 tunnel destination {} for {} not supported",
- tunDst.getIpv6Address().getValue(),
- destNode);
- continue;
+ protected void sync(NodeId nodeId, PolicyInfo policyInfo, HashMap<GroupId, GroupCtx> groupMap) throws Exception {
+
+
+ for (Endpoint localEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+ EndpointFwdCtxOrdinals localEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, localEp);
+ GroupId gid = new GroupId(Long.valueOf(localEpFwdCtxOrds.getFdId()));
+ GroupCtx gctx = groupMap.get(gid);
+ if (gctx == null) {
+ groupMap.put(gid, gctx = new GroupCtx(gid));
}
+ gctx.visited = true;
- BucketBuilder bb = new BucketBuilder()
- .setBucketId(new BucketId(Long.valueOf(bucketId)))
- .setAction(actionList(tundstAction,
- outputAction(tunPort)));
- updateBucket(gctx, bb);
- }
- for (Endpoint localEp : ctx.getEndpointManager().getEPsForNode(nodeId, epg)) {
+ for (EgKey epg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
+
+
+ // we'll use the fdId with the high bit set for remote bucket
+ // and just the local port number for local bucket
+ for (NodeId destNode : ctx.getEndpointManager().getNodesForGroup(epg)) {
+ if (nodeId.equals(destNode))
+ continue;
+
+ long bucketId = OrdinalFactory.getContextOrdinal(destNode);
+ bucketId |= 1L << 31;
+
+ IpAddress tunDst =
+ ctx.getSwitchManager().getTunnelIP(destNode);
+ NodeConnectorId tunPort =
+ ctx.getSwitchManager().getTunnelPort(nodeId);
+ if (tunDst == null || tunPort == null)
+ continue;
+ Action tundstAction = null;
+ if (tunDst.getIpv4Address() != null) {
+ String nextHop = tunDst.getIpv4Address().getValue();
+ tundstAction = nxLoadTunIPv4Action(nextHop, true);
+ } else {
+ LOG.error("IPv6 tunnel destination {} for {} not supported",
+ tunDst.getIpv6Address().getValue(),
+ destNode);
+ continue;
+ }
+
+ BucketBuilder bb = new BucketBuilder()
+ .setBucketId(new BucketId(Long.valueOf(bucketId)))
+ .setAction(actionList(tundstAction,
+ outputAction(tunPort)));
+ updateBucket(gctx, bb);
+ }
OfOverlayContext ofc =
localEp.getAugmentation(OfOverlayContext.class);
if (ofc == null || ofc.getNodeConnectorId() == null ||
- (LocationType.External.equals(ofc.getLocationType())))
+ (LocationType.External.equals(ofc.getLocationType())))
continue;
long bucketId;
bucketId = getOfPortNum(ofc.getNodeConnectorId());
} catch (NumberFormatException e) {
LOG.warn("Could not parse port number {}",
- ofc.getNodeConnectorId(), e);
+ ofc.getNodeConnectorId(), e);
continue;
}
Action output = outputAction(ofc.getNodeConnectorId());
BucketBuilder bb = new BucketBuilder()
- .setBucketId(new BucketId(Long.valueOf(bucketId)))
- .setAction(actionList(output));
+ .setBucketId(new BucketId(Long.valueOf(bucketId)))
+ .setAction(actionList(output));
updateBucket(gctx, bb);
}
}
BucketCtx bctx = gctx.bucketMap.get(bb.getBucketId());
if (bctx == null) {
gctx.bucketMap.put(bb.getBucketId(),
- bctx = new BucketCtx(null));
+ bctx = new BucketCtx(null));
}
bctx.visited = true;
bctx.newb = bb.build();
this.groupId = groupId;
}
}
-
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.SwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
-import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* Update the relevant flow table for the node
* @param nodeId the node to update
* @param dirty the dirty set
+ * @param policyInfo
+ * @param flowMap
* @throws Exception
*/
- public abstract void update(NodeId nodeId,
+ public abstract void update(NodeId nodeId,
PolicyInfo policyInfo,
- Dirty dirty) throws Exception;
+ FlowMap flowMap) throws Exception;
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
+import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
+import org.opendaylight.groupbasedpolicy.resolver.EgKey;
+import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
+import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OrdinalFactory {
+
+ private final static Logger LOG = LoggerFactory.getLogger(OrdinalFactory.class);
+
+ /**
+ * Counter used to allocate ordinal values for forwarding contexts and VNIDs
+ */
+ private final static AtomicInteger policyOrdinal = new AtomicInteger(1);
+
+ private final static ConcurrentMap<String, Integer> ordinals =
+ new ConcurrentHashMap<>();
+ // XXX - need to garbage collect
+ private final static ConcurrentMap<ConditionGroup, Integer> cgOrdinals =
+ new ConcurrentHashMap<>();
+
+ public static int getContextOrdinal(final TenantId tenantId,
+ final UniqueId id) throws Exception {
+ if (tenantId == null || id == null)
+ return 0;
+ return getContextOrdinalFromString(tenantId.getValue() + "|" + id.getValue());
+ }
+
+ /**
+ * Get a unique ordinal for the given condition group, suitable for use in
+ * the data plane. This is unique only for this node, and not globally.
+ *
+ * @param cg
+ * the {@link ConditionGroup}
+ * @return the unique ID
+ */
+ public static int getCondGroupOrdinal(final ConditionGroup cg) {
+ if (cg == null)
+ return 0;
+ Integer ord = cgOrdinals.get(cg);
+ if (ord == null) {
+ ord = policyOrdinal.getAndIncrement();
+ Integer old = cgOrdinals.putIfAbsent(cg, ord);
+ if (old != null)
+ ord = old;
+ }
+ return ord.intValue();
+ }
+
+ /**
+ * Get a 32-bit context ordinal suitable for use in the OF data plane for
+ * the given policy item.
+ *
+ * @param tenantId
+ * the tenant ID of the element
+ * @param id
+ * the unique ID for the element
+ * @return the 32-bit ordinal value
+ * @throws Exception
+ */
+
+ public static int getContextOrdinal(NodeId destNode) throws Exception {
+ return getContextOrdinalFromString(destNode.getValue());
+ }
+
+ public static int getContextOrdinal(Endpoint ep, NetworkDomainId networkContainment) throws Exception {
+ // TODO: Define private static final Comparator<EndpointGroupId>
+ // COMPARATOR = new Comparator<EndpointGroupId>() { ... }
+ // pass to constructor: new TreeSet<>(COMPARATOR);
+
+ Set<String> epgs = new TreeSet<>();
+
+ // Get EPGs and add to ordered Set
+ if (ep.getEndpointGroup() != null) {
+ epgs.add(ep.getEndpointGroup().getValue());
+ }
+ if (ep.getEndpointGroups() != null) {
+ for (EndpointGroupId epgId : ep.getEndpointGroups()) {
+ epgs.add(epgId.getValue());
+ }
+ }
+
+ StringBuilder key = new StringBuilder(ep.getTenant().getValue());
+
+ for (String epg : epgs) {
+ key.append('|');
+ key.append(epg);
+ }
+
+ key.append("|")
+ .append(networkContainment);
+
+ return getContextOrdinalFromString(key.toString());
+
+ }
+
+ /**
+ * Get a 32-bit context ordinal suitable for use in the OF data plane for
+ * the given policy item.
+ *
+ * @param id
+ * the unique ID for the element
+ * @return the 32-bit ordinal value
+ */
+ private static int getContextOrdinalFromString(final String id) throws Exception {
+
+ Integer ord = ordinals.get(id);
+ if (ord == null) {
+ ord = policyOrdinal.getAndIncrement();
+ Integer old = ordinals.putIfAbsent(id, ord);
+ if (old != null)
+ ord = old;
+ }
+ return ord.intValue();
+ }
+
+ public static final EndpointFwdCtxOrdinals getEndpointFwdCtxOrdinals(OfContext ctx, PolicyInfo policyInfo,
+ Endpoint ep) throws Exception {
+ return new EndpointFwdCtxOrdinals(ep, policyInfo, ctx);
+ }
+
+ // TODO alagalah Li: Move to either OrdinalFactory or EndpointManager
+ public static class EndpointFwdCtxOrdinals {
+
+ private NetworkDomainId networkContainment;
+ private EpKey ep;
+ private int epgId = 0, bdId = 0, fdId = 0, l3Id = 0, cgId = 0;
+
+ private EndpointFwdCtxOrdinals(Endpoint ep, PolicyInfo policyInfo, OfContext ctx) throws Exception {
+ this.ep = new EpKey(ep.getL2Context(), ep.getMacAddress());
+
+ IndexedTenant tenant = ctx.getPolicyResolver().getTenant(ep.getTenant());
+ // Set network containment either from ep, or from primary EPG
+ if (ep.getNetworkContainment() != null) {
+ this.networkContainment = ep.getNetworkContainment();
+ } else {
+ EndpointGroup epg = tenant.getEndpointGroup(ep.getEndpointGroup());
+ if (epg.getNetworkDomain() != null) {
+ this.networkContainment = epg.getNetworkDomain();
+ } else {
+ LOG.info(
+ "endPoint ordinals for {} not processed in SourceMapper. Must be able to resolve network containment either directly, or from primary EPG",
+ ep.getKey());
+ return;
+ }
+ }
+
+ // TODO: alagalah: I have a draft to address structure of mEPG
+ // conditions, but
+ // out of scope until broader bugs with conditions are fixed.
+ List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(ep);
+ ConditionGroup cg =
+ policyInfo.getEgCondGroup(new EgKey(ep.getTenant(), ep.getEndpointGroup()), conds);
+ this.cgId = getCondGroupOrdinal(cg);
+
+ // Based on network containment, determine components of
+ // forwarding context
+ L3Context l3c = tenant.resolveL3Context(networkContainment);
+ L2BridgeDomain bd = tenant.resolveL2BridgeDomain(networkContainment);
+ L2FloodDomain fd = tenant.resolveL2FloodDomain(networkContainment);
+
+ // Set ordinal id's for use in flows for each forwarding context
+ // component
+
+ this.epgId = getContextOrdinal(ep, networkContainment);
+ if (bd != null)
+ this.bdId = getContextOrdinal(ep.getTenant(),
+ bd.getId());
+ if (fd != null)
+ this.fdId = getContextOrdinal(ep.getTenant(),
+ fd.getId());
+ if (l3c != null)
+ this.l3Id = getContextOrdinal(ep.getTenant(),
+ l3c.getId());
+
+ }
+
+ public int getEpgId() {
+ return this.epgId;
+ }
+
+ public NetworkDomainId getNetworkContainment() {
+ return this.networkContainment;
+ }
+
+ public EpKey getEp() {
+ return this.ep;
+ }
+
+ public int getBdId() {
+ return this.bdId;
+ }
+
+ public int getFdId() {
+ return this.fdId;
+ }
+
+ public int getL3Id() {
+ return this.l3Id;
+ }
+
+ public int getCgId() {
+ return this.cgId;
+ }
+ }
+}
import javax.annotation.concurrent.Immutable;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
import org.opendaylight.groupbasedpolicy.resolver.RuleGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
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.openflowjava.nx.match.rev140421.NxmNxReg2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Ordering;
/**
- * Manage the table that enforces policy on the traffic. Traffic is denied
+ * Manage the table that enforces policy on the traffic. Traffic is denied
* unless specifically allowed by policy
- * @author readams
*/
public class PolicyEnforcer extends FlowTable {
protected static final Logger LOG =
}
@Override
- public void sync(ReadWriteTransaction t, InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId,
- PolicyInfo policyInfo, Dirty dirty)
- throws Exception {
- dropFlow(t, tiid, flowMap, Integer.valueOf(1), null);
- allowFromTunnel(t, tiid, flowMap, nodeId);
+ public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
- HashSet<CgPair> visitedPairs = new HashSet<>();
-
- for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
- // Allow traffic within the same endpoint group if the policy
- // specifies
- IndexedTenant tenant =
- ctx.getPolicyResolver().getTenant(sepg.getTenantId());
- EndpointGroup group =
- tenant.getEndpointGroup(sepg.getEgId());
- IntraGroupPolicy igp = group.getIntraGroupPolicy();
- int sepgId =
- ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
- sepg.getEgId());
- if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
- allowSameEpg(t, tiid, flowMap, nodeId, sepgId);
- }
-
- for (Endpoint src : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
- if (src.getTenant() == null || src.getEndpointGroup() == null)
- continue;
+ flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
- List<ConditionName> conds =
- ctx.getEndpointManager().getCondsForEndpoint(src);
- ConditionGroup scg = policyInfo.getEgCondGroup(sepg, conds);
- int scgId = ctx.getPolicyManager().getCondGroupOrdinal(scg);
+ flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(nodeId));
- Set<EgKey> peers = policyInfo.getPeers(sepg);
- for (EgKey depg : peers) {
- int depgId =
- ctx.getPolicyManager().getContextOrdinal(depg.getTenantId(),
- depg.getEgId());
-
- for (Endpoint dst : ctx.getEndpointManager().getEndpointsForGroup(depg)) {
+ HashSet<CgPair> visitedPairs = new HashSet<>();
- conds = ctx.getEndpointManager().getCondsForEndpoint(dst);
- ConditionGroup dcg =
- policyInfo.getEgCondGroup(new EgKey(dst.getTenant(),
- dst.getEndpointGroup()),
- conds);
- int dcgId = ctx.getPolicyManager().getCondGroupOrdinal(dcg);
+ for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+ for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
+ Set<EgKey> peers = policyInfo.getPeers(srcEpgKey);
+ for (EgKey dstEpgKey : peers) {
+ for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(dstEpgKey)) {
+ // mEPG ordinals
+ EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp);
+ EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dstEp);
+ int dcgId = dstEpFwdCxtOrds.getCgId();
+ int depgId = dstEpFwdCxtOrds.getEpgId();
+ int scgId = srcEpFwdCxtOrds.getCgId();
+ int sepgId = srcEpFwdCxtOrds.getEpgId();
+
+ List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(srcEp);
+ ConditionGroup scg = policyInfo.getEgCondGroup(srcEpgKey, conds);
+ conds = ctx.getEndpointManager().getCondsForEndpoint(dstEp);
+ ConditionGroup dcg = policyInfo.getEgCondGroup(dstEpgKey, conds);
CgPair p = new CgPair(depgId, sepgId, dcgId, scgId);
- if (visitedPairs.contains(p)) continue;
+ if (visitedPairs.contains(p))
+ continue;
visitedPairs.add(p);
- syncPolicy(t, tiid, flowMap, nodeId, policyInfo,
- p, depg, sepg, dcg, scg);
+ syncPolicy(flowMap, nodeId, policyInfo,
+ p, dstEpgKey, srcEpgKey, dcg, scg);
+ //Reverse
p = new CgPair(sepgId, depgId, scgId, dcgId);
- if (visitedPairs.contains(p)) continue;
+ if (visitedPairs.contains(p))
+ continue;
visitedPairs.add(p);
- syncPolicy(t, tiid, flowMap, nodeId, policyInfo,
- p, sepg, depg, scg, dcg);
+ syncPolicy(flowMap, nodeId, policyInfo,
+ p, srcEpgKey, dstEpgKey, scg, dcg);
+ }
+ }
+ }
+ }
+
+ // Allow same EPG
+// Set<Endpoint> visitedEps = new HashSet<>();
+ for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+// visitedEps.add(srcEp);
+ for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
+
+ IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
+ EndpointGroup group = tenant.getEndpointGroup(srcEpgKey.getEgId());
+ IntraGroupPolicy igp = group.getIntraGroupPolicy();
+
+ if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
+ for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(srcEpgKey)) {
+ // mEPG ordinals
+// if(visitedEps.contains(dstEp)) {
+// continue;
+// }
+// visitedEps.add(dstEp);
+ EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp);
+ EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dstEp);
+ int depgId = dstEpFwdCxtOrds.getEpgId();
+ int sepgId = srcEpFwdCxtOrds.getEpgId();
+ flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
+ flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
}
}
}
}
+
}
- private void allowSameEpg(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId,
- int sepgId) {
+ private Flow allowSameEpg(int sepgId, int depgId) {
FlowId flowId = new FlowId(new StringBuilder()
- .append("intraallow|")
- .append(sepgId).toString());
- if (visit(flowMap, flowId.getValue())) {
+ .append("intraallow|")
+ .append(sepgId).toString());
MatchBuilder mb = new MatchBuilder();
addNxRegMatch(mb,
- RegMatch.of(NxmNxReg0.class,Long.valueOf(sepgId)),
- RegMatch.of(NxmNxReg2.class,Long.valueOf(sepgId)));
+ RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
FlowBuilder flow = base()
- .setId(flowId)
- .setMatch(mb.build())
- .setPriority(65000)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
- writeFlow(t, tiid, flow.build());
- }
+ .setId(flowId)
+ .setMatch(mb.build())
+ .setPriority(65000)
+ .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+ return flow.build();
}
- private void allowFromTunnel(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId) {
+ private Flow allowFromTunnel(NodeId nodeId) {
NodeConnectorId tunPort =
ctx.getSwitchManager().getTunnelPort(nodeId);
- if (tunPort == null) return;
+ if (tunPort == null)
+ return null;
FlowId flowId = new FlowId("tunnelallow");
- if (visit(flowMap, flowId.getValue())) {
- MatchBuilder mb = new MatchBuilder()
+ MatchBuilder mb = new MatchBuilder()
.setInPort(tunPort);
- addNxRegMatch(mb,
- RegMatch.of(NxmNxReg1.class,Long.valueOf(0xffffff)));
- FlowBuilder flow = base()
+ addNxRegMatch(mb,
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
+ FlowBuilder flow = base()
.setId(flowId)
.setMatch(mb.build())
.setPriority(65000)
.setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
- writeFlow(t, tiid, flow.build());
- }
+ return flow.build();
+
}
- private void syncPolicy(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId,
- PolicyInfo policyInfo,
- CgPair p, EgKey sepg, EgKey depg,
- ConditionGroup scg, ConditionGroup dcg)
- throws Exception {
+ private void syncPolicy(FlowMap flowMap, NodeId nodeId,
+ PolicyInfo policyInfo,
+ CgPair p, EgKey sepg, EgKey depg,
+ ConditionGroup scg, ConditionGroup dcg)
+ throws Exception {
// XXX - TODO raise an exception for rules between the same
// endpoint group that are asymmetric
Policy policy = policyInfo.getPolicy(sepg, depg);
TenantId tenantId = rg.getContractTenant().getId();
IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
for (Rule r : rg.getRules()) {
- syncDirection(t, tiid, flowMap, nodeId, tenant,
- p, r, Direction.In, priority);
- syncDirection(t, tiid, flowMap, nodeId, tenant,
- p, r, Direction.Out, priority);
+ syncDirection(flowMap, nodeId, tenant,
+ p, r, Direction.In, priority);
+ syncDirection(flowMap, nodeId, tenant,
+ p, r, Direction.Out, priority);
priority -= 1;
}
}
/**
- * Private internal class for ordering Actions in Rules. The
- * order is determined first by the value of the order parameter,
- * with the lower order actions being applied first; for Actions
- * with either the same order or no order, ordering is lexicographical
- * by name.
- *
- * @author tbachman
+ * Private internal class for ordering Actions in Rules. The order is
+ * determined first by the value of the order parameter, with the lower
+ * order actions being applied first; for Actions with either the same order
+ * or no order, ordering is lexicographical by name.
*
*/
private static class ActionRefComparator implements Comparator<ActionRef> {
public int compare(ActionRef arg0, ActionRef arg1) {
return ComparisonChain.start()
.compare(arg0.getOrder(), arg1.getOrder(),
- Ordering.natural().nullsLast())
+ Ordering.natural().nullsLast())
.compare(arg0.getName().getValue(), arg1.getName().getValue(),
- Ordering.natural().nullsLast())
+ Ordering.natural().nullsLast())
.result();
}
}
- private void syncDirection(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId,
- IndexedTenant contractTenant,
- CgPair p, Rule r, Direction d, int priority) {
+ private void syncDirection(FlowMap flowMap, NodeId nodeId, IndexedTenant contractTenant,
+ CgPair cgPair, Rule rule, Direction direction, int priority) {
/*
- * Create the ordered action list. The implicit action is
- * "allow", and is therefore always in the list
+ * Create the ordered action list. The implicit action is "allow", and
+ * is therefore always in the list
*
- * TODO: revisit implicit vs. default for "allow"
- * TODO: look into incorporating operational policy for actions
+ * TODO: revisit implicit vs. default for "allow" TODO: look into
+ * incorporating operational policy for actions
*/
+
+ //TODO: can pass Comparator ActionRefComparator to List constructor, rather than referencing in sort
List<ActionBuilder> abl = new ArrayList<ActionBuilder>();
- if (r.getActionRef() != null) {
+ if (rule.getActionRef() != null) {
/*
* Pre-sort by references using order, then name
*/
- List<ActionRef> arl = new ArrayList<ActionRef>(r.getActionRef());
+ List<ActionRef> arl = new ArrayList<ActionRef>(rule.getActionRef());
Collections.sort(arl, ActionRefComparator.INSTANCE);
- for (ActionRef ar: arl) {
+ for (ActionRef ar : arl) {
ActionInstance ai = contractTenant.getAction(ar.getName());
if (ai == null) {
// XXX TODO fail the match and raise an exception
LOG.warn("Action instance {} not found",
- ar.getName().getValue());
+ ar.getName().getValue());
return;
}
Action act = SubjectFeatures.getAction(ai.getActionDefinitionId());
if (act == null) {
// XXX TODO fail the match and raise an exception
LOG.warn("Action definition {} not found",
- ai.getActionDefinitionId().getValue());
+ ai.getActionDefinitionId().getValue());
return;
}
- Map<String,Object> params = new HashMap<>();
+ Map<String, Object> params = new HashMap<>();
if (ai.getParameterValue() != null) {
for (ParameterValue v : ai.getParameterValue()) {
- if (v.getName() == null) continue;
+ if (v.getName() == null)
+ continue;
if (v.getIntValue() != null) {
params.put(v.getName().getValue(), v.getIntValue());
} else if (v.getStringValue() != null) {
}
}
/*
- * Convert the GBP Action to one or more OpenFlow
- * Actions
+ * Convert the GBP Action to one or more OpenFlow Actions
*/
abl = act.updateAction(abl, params, ar.getOrder());
}
}
else {
Action act = SubjectFeatures.getAction(AllowAction.DEFINITION.getId());
- abl = act.updateAction(abl, new HashMap<String,Object>(), 0);
+ abl = act.updateAction(abl, new HashMap<String, Object>(), 0);
}
- for (ClassifierRef cr : r.getClassifierRef()) {
+ for (ClassifierRef cr : rule.getClassifierRef()) {
if (cr.getDirection() != null &&
- !cr.getDirection().equals(Direction.Bidirectional) &&
- !cr.getDirection().equals(d))
+ !cr.getDirection().equals(Direction.Bidirectional) &&
+ !cr.getDirection().equals(direction)) {
continue;
+ }
StringBuilder idb = new StringBuilder();
// XXX - TODO - implement connection tracking (requires openflow
MatchBuilder baseMatch = new MatchBuilder();
- if (d.equals(Direction.In)) {
- idb.append(p.sepg)
- .append("|")
- .append(p.scgId)
- .append("|")
- .append(p.depg)
- .append("|")
- .append(p.dcgId)
- .append("|")
- .append(priority);
+ if (direction.equals(Direction.In)) {
+ idb.append(cgPair.sepg)
+ .append("|")
+ .append(cgPair.scgId)
+ .append("|")
+ .append(cgPair.depg)
+ .append("|")
+ .append(cgPair.dcgId)
+ .append("|")
+ .append(priority);
addNxRegMatch(baseMatch,
- RegMatch.of(NxmNxReg0.class,Long.valueOf(p.sepg)),
- RegMatch.of(NxmNxReg1.class,Long.valueOf(p.scgId)),
- RegMatch.of(NxmNxReg2.class,Long.valueOf(p.depg)),
- RegMatch.of(NxmNxReg3.class,Long.valueOf(p.dcgId)));
+ RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
} else {
- idb.append(p.depg)
- .append("|")
- .append(p.dcgId)
- .append("|")
- .append(p.sepg)
- .append("|")
- .append(p.scgId)
- .append("|")
- .append(priority);
+ idb.append(cgPair.depg)
+ .append("|")
+ .append(cgPair.dcgId)
+ .append("|")
+ .append(cgPair.sepg)
+ .append("|")
+ .append(cgPair.scgId)
+ .append("|")
+ .append(priority);
addNxRegMatch(baseMatch,
- RegMatch.of(NxmNxReg0.class,Long.valueOf(p.depg)),
- RegMatch.of(NxmNxReg1.class,Long.valueOf(p.dcgId)),
- RegMatch.of(NxmNxReg2.class,Long.valueOf(p.sepg)),
- RegMatch.of(NxmNxReg3.class,Long.valueOf(p.scgId)));
+ RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
}
ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
if (ci == null) {
// XXX TODO fail the match and raise an exception
LOG.warn("Classifier instance {} not found",
- cr.getName().getValue());
+ cr.getName().getValue());
return;
}
Classifier cfier = SubjectFeatures
if (cfier == null) {
// XXX TODO fail the match and raise an exception
LOG.warn("Classifier definition {} not found",
- ci.getClassifierDefinitionId().getValue());
+ ci.getClassifierDefinitionId().getValue());
return;
}
Map<String,ParameterValue> params = new HashMap<>();
for (ParameterValue v : ci.getParameterValue()) {
+
if (v.getIntValue() != null) {
params.put(v.getName().getValue(), v);
} else if (v.getStringValue() != null) {
for (MatchBuilder match : result.getMatchBuilders()) {
Match m = match.build();
FlowId flowId = new FlowId(baseId + "|" + m.toString());
- if (visit(flowMap, flowId.getValue())) {
- flow.setMatch(m).setId(flowId).setPriority(Integer.valueOf(priority))
- .setInstructions(instructions(applyActionIns(abl)));
- writeFlow(t, tiid, flow.build());
- }
+ flow.setMatch(m)
+ .setId(flowId)
+ .setPriority(Integer.valueOf(priority))
+ .setInstructions(instructions(applyActionIns(abl)));
+ flowMap.writeFlow(nodeId, TABLE_ID, flow.build());
+
+
}
}
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
-import java.util.Map;
import java.util.Set;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
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.Ipv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manage the table that enforces port security
- * @author readams
+ *
*/
public class PortSecurity extends FlowTable {
protected static final Logger LOG =
}
@Override
- public void sync(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo, Dirty dirty) {
+ public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) {
+
// Allow traffic from tunnel and external ports
NodeConnectorId tunnelIf = ctx.getSwitchManager().getTunnelPort(nodeId);
if (tunnelIf != null)
- allowFromPort(t, tiid, flowMap, tunnelIf);
+ flowMap.writeFlow(nodeId, TABLE_ID, allowFromPort(tunnelIf));
Set<NodeConnectorId> external =
ctx.getSwitchManager().getExternalPorts(nodeId);
- for (NodeConnectorId extIf: external) {
- allowFromPort(t, tiid, flowMap, extIf);
+ for (NodeConnectorId extIf : external) {
+ flowMap.writeFlow(nodeId, TABLE_ID, allowFromPort(extIf));
}
// Default drop all
- dropFlow(t, tiid, flowMap, 1, null);
+ flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
// Drop IP traffic that doesn't match a source IP rule
- dropFlow(t, tiid, flowMap, 110, FlowUtils.ARP);
- dropFlow(t, tiid, flowMap, 111, FlowUtils.IPv4);
- dropFlow(t, tiid, flowMap, 112, FlowUtils.IPv6);
+ flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP));
+ flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4));
+ flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6));
for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
- for (Endpoint e : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
- OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
+ for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId, sepg)) {
+ OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
+
if (ofc != null && ofc.getNodeConnectorId() != null &&
(ofc.getLocationType() == null ||
LocationType.Internal.equals(ofc.getLocationType()))) {
// Allow layer 3 traffic (ARP and IP) with the correct
// source IP, MAC, and source port
- l3flow(t, tiid, flowMap, e, ofc, 120, false);
- l3flow(t, tiid, flowMap, e, ofc, 121, true);
- l3DhcpDoraFlow(t, tiid, flowMap, e, ofc, 115);
+ l3flow(flowMap, nodeId, ep, ofc, 120, false);
+ l3flow(flowMap, nodeId, ep, ofc, 121, true);
+ flowMap.writeFlow(nodeId, TABLE_ID, l3DhcpDoraFlow(ep, ofc, 115));
// Allow layer 2 traffic with the correct source MAC and
// source port (note lower priority than drop IP rules)
- l2flow(t, tiid, flowMap, e, ofc, 100);
+ flowMap.writeFlow(nodeId, TABLE_ID, l2flow(ep, ofc, 100));
}
}
}
}
- private void allowFromPort(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeConnectorId port) {
+ private Flow allowFromPort(
+ NodeConnectorId port) {
FlowId flowid = new FlowId(new StringBuilder()
- .append("allow|")
- .append(port.getValue())
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- FlowBuilder flowb = base()
+ .append("allow|")
+ .append(port.getValue())
+ .toString());
+ FlowBuilder flowb = base()
.setId(flowid)
.setPriority(Integer.valueOf(200))
.setMatch(new MatchBuilder()
- .setInPort(port)
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(getTableId()+1)));
- writeFlow(t, tiid, flowb.build());
- }
+ .setInPort(port)
+ .build())
+ .setInstructions(FlowUtils.gotoTableInstructions((short) (getTableId() + 1)));
+ return flowb.build();
+
}
- private void l2flow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority) {
+ private Flow l2flow(Endpoint ep, OfOverlayContext ofc, Integer priority) {
FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- FlowBuilder flowb = base()
+ .append(ofc.getNodeConnectorId().getValue())
+ .append("|")
+ .append(ep.getMacAddress().getValue())
+ .toString());
+ FlowBuilder flowb = base()
.setPriority(priority)
.setId(flowid)
.setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null, null))
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)));
+ .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
+ null, null))
+ .setInPort(ofc.getNodeConnectorId())
+ .build())
+ .setInstructions(FlowUtils.gotoTableInstructions((short) (TABLE_ID + 1)));
- writeFlow(t, tiid, flowb.build());
- }
+ return flowb.build();
}
- private void l3DhcpDoraFlow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority) {
+ private Flow l3DhcpDoraFlow(Endpoint ep, OfOverlayContext ofc, Integer priority) {
- Long etherType= FlowUtils.IPv4;
+ //TODO: Handle IPv6 DORA
+ Long etherType = FlowUtils.IPv4;
// DHCP DORA destination is broadcast
- String ikey="255.255.255.255/32";
- Layer3Match m=new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
+ String ikey = "255.255.255.255/32";
+ Layer3Match m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .append("|dhcp|")
- .append(etherType)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- Flow flow = base()
- .setPriority(priority)
- .setId(flowid)
- .setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null,
- etherType))
- .setLayer3Match(m)
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
- .build();
+ .append(ofc.getNodeConnectorId().getValue())
+ .append("|")
+ .append(ep.getMacAddress().getValue())
+ .append("|dhcp|")
+ .append(etherType)
+ .toString());
+ Flow flow = base()
+ .setPriority(priority)
+ .setId(flowid)
+ .setMatch(new MatchBuilder()
+ .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
+ null,
+ etherType))
+ .setLayer3Match(m)
+ .setInPort(ofc.getNodeConnectorId())
+ .build())
+ .setInstructions(FlowUtils.gotoTableInstructions((short) (TABLE_ID + 1)))
+ .build();
- writeFlow(t, tiid, flow);
- }
+ return flow;
}
- private void l3flow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority,
- boolean arp) {
- if (e.getL3Address() == null) return;
- for (L3Address l3 : e.getL3Address()) {
- if (l3.getIpAddress() == null) continue;
+ private void l3flow(FlowMap flowMap, NodeId nodeId,
+ Endpoint ep, OfOverlayContext ofc,
+ Integer priority, boolean arp) {
+ if (ep.getL3Address() == null)
+ return;
+ for (L3Address l3 : ep.getL3Address()) {
+ if (l3.getIpAddress() == null)
+ continue;
Layer3Match m = null;
Long etherType = null;
String ikey = null;
if (l3.getIpAddress().getIpv4Address() != null) {
- ikey = l3.getIpAddress().getIpv4Address().getValue()+"/32";
+ ikey = l3.getIpAddress().getIpv4Address().getValue() + "/32";
if (arp) {
m = new ArpMatchBuilder()
- .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
- .build();
+ .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
+ .build();
etherType = FlowUtils.ARP;
} else {
m = new Ipv4MatchBuilder()
- .setIpv4Source(new Ipv4Prefix(ikey))
- .build();
+ .setIpv4Source(new Ipv4Prefix(ikey))
+ .build();
etherType = FlowUtils.IPv4;
}
} else if (l3.getIpAddress().getIpv6Address() != null) {
- if (arp) continue;
- ikey = l3.getIpAddress().getIpv6Address().getValue()+"/128";
+ if (arp)
+ continue;
+ ikey = l3.getIpAddress().getIpv6Address().getValue() + "/128";
m = new Ipv6MatchBuilder()
- .setIpv6Source(new Ipv6Prefix(ikey))
- .build();
+ .setIpv6Source(new Ipv6Prefix(ikey))
+ .build();
etherType = FlowUtils.IPv6;
} else {
continue;
}
FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .append("|")
- .append(ikey)
- .append("|")
- .append(etherType)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- Flow flow = base()
+ .append(ofc.getNodeConnectorId().getValue())
+ .append("|")
+ .append(ep.getMacAddress().getValue())
+ .append("|")
+ .append(ikey)
+ .append("|")
+ .append(etherType)
+ .toString());
+ Flow flow = base()
.setPriority(priority)
.setId(flowid)
.setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null,
- etherType))
- .setLayer3Match(m)
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
+ .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
+ null,
+ etherType))
+ .setLayer3Match(m)
+ .setInPort(ofc.getNodeConnectorId())
+ .build())
+ .setInstructions(FlowUtils.gotoTableInstructions((short) (TABLE_ID + 1)))
.build();
- writeFlow(t, tiid, flow);
- }
+ flowMap.writeFlow(nodeId, TABLE_ID,flow);
}
}
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIdMatch;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
+
import java.math.BigInteger;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
+import java.util.Set;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
+import com.google.common.collect.Sets;
/**
- * Manage the table that assigns source endpoint group, bridge domain, and
+ * Manage the table that assigns source endpoint group, bridge domain, and
* router domain to registers to be used by other tables.
- * @author readams
*/
public class SourceMapper extends FlowTable {
protected static final Logger LOG =
LoggerFactory.getLogger(SourceMapper.class);
+ //TODO Li alagalah Improve UT coverage for this class.
public static final short TABLE_ID = 1;
public SourceMapper(OfContext ctx) {
}
@Override
- public void sync(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo,
- Dirty dirty) throws Exception {
- dropFlow(t, tiid, flowMap, Integer.valueOf(1), null);
-
- for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
- IndexedTenant tenant =
- ctx.getPolicyResolver().getTenant(sepg.getTenantId());
- if (tenant == null) continue;
-
- EndpointGroup eg = tenant.getEndpointGroup(sepg.getEgId());
- L3Context l3c = tenant.resolveL3Context(eg.getNetworkDomain());
- L2BridgeDomain bd = tenant.resolveL2BridgeDomain(eg.getNetworkDomain());
- L2FloodDomain fd = tenant.resolveL2FloodDomain(eg.getNetworkDomain());
- int egId = 0, bdId = 0, fdId = 0, l3Id = 0;
-
- egId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
- sepg.getEgId());
- if (bd != null)
- bdId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
- bd.getId());
- if (fd != null)
- fdId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
- fd.getId());
- if (l3c != null)
- l3Id = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
- l3c.getId());
-
- NodeConnectorId tunPort =
- ctx.getSwitchManager().getTunnelPort(nodeId);
- if (tunPort != null) {
- FlowId flowid = new FlowId(new StringBuilder()
+ public void sync(NodeId nodeId,
+ PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+
+ flowMap.writeFlow(nodeId,TABLE_ID,dropFlow(Integer.valueOf(1), null));
+
+ /*
+ * 1. Retrieve all endpoints connected to node 2. For each endpoint: -
+ * calculate and update index for multi-EPG ordinal for flow sEPG - set
+ * bdId, fdId, L3c based from following order: : 1. EP specific
+ * NetworkContextId : 2. Primary EPG : 3. "First" EPG in endpoint-groups
+ * - capture information for adding appropriate tunnel (sEPG ordinal,
+ * ep.bd, ep.fd, ep.l3c) - write flow 3. For each EPG captured above: -
+ * write tunnel flow
+ */
+
+ for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+
+ OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
+ if (ofc != null && ofc.getNodeConnectorId() != null &&
+ (ofc.getLocationType() == null ||
+ LocationType.Internal.equals(ofc.getLocationType())) &&
+ ep.getTenant() != null && (ep.getEndpointGroup() != null || ep.getEndpointGroups() != null)) {
+
+ IndexedTenant tenant =
+ ctx.getPolicyResolver().getTenant(ep.getTenant());
+ if (tenant == null)
+ continue;
+
+ // TODO: MOVE TO NEW CLASS BEGIN____>>>>>>>>>
+ /*
+ * sepg currently set for conditions.
+ * TODO: conditions are broken beyond repair. This will do for now.
+ * Bug raised already to be fixed in Li
+ *
+ */
+ EgKey sepg = new EgKey(ep.getTenant(), ep.getEndpointGroup());
+
+ createRemoteTunnels(flowMap,nodeId,ep,policyInfo);
+
+ /**
+ * Sync the local EP information.
+ */
+ syncEP(flowMap, policyInfo, nodeId, ep, ofc, sepg);
+ }
+ }
+ }
+
+ private void createRemoteTunnels(FlowMap flowMap,NodeId nodeId, Endpoint ep,
+ PolicyInfo policyInfo) throws Exception {
+ Set<EgKey> epgs = new HashSet<>();
+
+ EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, ep);
+
+ // Get EPGs and add to Set to remove duplicates
+ //TODO alagalah Li: test EndpointManager.getEgKeys
+ if (ep.getEndpointGroup() != null) {
+ epgs.add(new EgKey(ep.getTenant(), ep.getEndpointGroup()));
+ }
+ if (ep.getEndpointGroups() != null) {
+ for (EndpointGroupId epgId : ep.getEndpointGroups()) {
+ epgs.add(new EgKey(ep.getTenant(), epgId));
+ }
+ }
+
+ // Create tunnels on remote Nodes that may talk to us.
+ for (EgKey epg : epgs) {
+ Set<EgKey> peers = Sets.union(Collections.singleton(epg),
+ policyInfo.getPeers(epg));
+ for (EgKey peer : peers) {
+ for (NodeId remoteNodeId : ctx.getEndpointManager().getNodesForGroup(peer)) {
+
+ // Only put tunnels on destination nodes
+ if(remoteNodeId == nodeId) continue;
+ NodeConnectorId tunPort =
+ ctx.getSwitchManager().getTunnelPort(remoteNodeId);
+ if(tunPort == null) {
+ continue;
+ }
+ flowMap.writeFlow(remoteNodeId, TABLE_ID, createTunnelFlow(tunPort,epFwdCtxOrds));
+
+ }
+ }
+ }
+ }
+
+ private Flow createTunnelFlow(NodeConnectorId tunPort, EndpointFwdCtxOrdinals epFwdCtxOrds) {
+ // ... this is a remote node.
+
+ int egId=epFwdCtxOrds.getEpgId();
+ int bdId=epFwdCtxOrds.getBdId();
+ int fdId=epFwdCtxOrds.getFdId();
+ int l3Id=epFwdCtxOrds.getL3Id();
+
+ FlowId flowid = new FlowId(new StringBuilder()
.append(tunPort.getValue())
.append("|tunnel|")
.append(egId)
.append("|")
.append(l3Id)
.toString());
- if (visit(flowMap, flowid.getValue())) {
- MatchBuilder mb = new MatchBuilder()
- .setInPort(tunPort);
- addNxTunIdMatch(mb, egId);
- Action segReg = nxLoadRegAction(NxmNxReg0.class,
- BigInteger.valueOf(egId));
- // set condition group register to all ones to bypass
- // policy enforcement
- Action scgReg = nxLoadRegAction(NxmNxReg1.class,
- BigInteger.valueOf(0xffffff));
- Action bdReg = nxLoadRegAction(NxmNxReg4.class,
- BigInteger.valueOf(bdId));
- Action fdReg = nxLoadRegAction(NxmNxReg5.class,
- BigInteger.valueOf(fdId));
- Action vrfReg = nxLoadRegAction(NxmNxReg6.class,
- BigInteger.valueOf(l3Id));
- FlowBuilder flowb = base()
- .setId(flowid)
- .setPriority(Integer.valueOf(150))
- .setMatch(mb.build())
- .setInstructions(instructions(applyActionIns(segReg,
- scgReg,
- bdReg,
- fdReg,
- vrfReg),
- gotoTableIns((short)(TABLE_ID + 1))));
- writeFlow(t, tiid, flowb.build());
- }
- }
-
- for (Endpoint e : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
- OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
- if (ofc != null && ofc.getNodeConnectorId() != null &&
- (ofc.getLocationType() == null ||
- LocationType.Internal.equals(ofc.getLocationType())) &&
- e.getTenant() != null && e.getEndpointGroup() != null) {
- syncEP(t, tiid, flowMap, policyInfo, nodeId, e, ofc,
- egId, bdId, fdId, l3Id);
- }
- }
- }
+
+ MatchBuilder mb = new MatchBuilder()
+ .setInPort(tunPort);
+ addNxTunIdMatch(mb, egId);
+ Action segReg = nxLoadRegAction(NxmNxReg0.class,
+ BigInteger.valueOf(egId));
+ // set condition group register to all ones to
+ // bypass
+ // policy enforcement
+ /*
+ * TODO: This breaks distributed policy enforcement
+ * especially wrt multi-action. BAD. Must be addressed
+ * (this is why we can't have nice things)
+ */
+ Action scgReg = nxLoadRegAction(NxmNxReg1.class,
+ BigInteger.valueOf(0xffffff));
+ Action bdReg = nxLoadRegAction(NxmNxReg4.class,
+ BigInteger.valueOf(bdId));
+ Action fdReg = nxLoadRegAction(NxmNxReg5.class,
+ BigInteger.valueOf(fdId));
+ Action vrfReg = nxLoadRegAction(NxmNxReg6.class,
+ BigInteger.valueOf(l3Id));
+ FlowBuilder flowb = base()
+ .setId(flowid)
+ .setPriority(Integer.valueOf(150))
+ .setMatch(mb.build())
+ .setInstructions(instructions(applyActionIns(segReg,
+ scgReg,
+ bdReg,
+ fdReg,
+ vrfReg),
+ gotoTableIns((short) (TABLE_ID + 1))));
+ return flowb.build();
}
-
- private void syncEP(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- PolicyInfo policyInfo,
- NodeId nodeId, Endpoint e, OfOverlayContext ofc,
- int egId, int bdId, int fdId, int l3Id)
- throws Exception {
- // Set sEPG, flood domain, bridge domain, and layer 3 context
+
+ private void syncEP(FlowMap flowMap,
+ PolicyInfo policyInfo,
+ NodeId nodeId, Endpoint ep, OfOverlayContext ofc,
+ EgKey egKey)
+ throws Exception {
+
+
+ //TODO alagalah Li/Be: We should also match on EndpointL3 with the appropriate
+ // network containment. This would solve a lot of problems and prepare for EndpointL3 RPC.
+
+ EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, ep);
+
+ int egId=epFwdCtxOrds.getEpgId();
+ int bdId=epFwdCtxOrds.getBdId();
+ int fdId=epFwdCtxOrds.getFdId();
+ int l3Id=epFwdCtxOrds.getL3Id();
+
+ // Set sEPG, flood domain, bridge domain, and layer 3 context
// for internal endpoints by directly matching each endpoint
- List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(e);
- ConditionGroup cg =
- policyInfo.getEgCondGroup(new EgKey(e.getTenant(),
- e.getEndpointGroup()),
- conds);
- int cgId = ctx.getPolicyManager().getCondGroupOrdinal(cg);
+ List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(ep);
+ ConditionGroup cg =
+ policyInfo.getEgCondGroup(new EgKey(ep.getTenant(),
+ egKey.getEgId()),
+ conds);
+
+ int cgId = OrdinalFactory.getCondGroupOrdinal(cg);
FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .append("|")
- .append(egId)
- .append("|")
- .append(bdId)
- .append("|")
- .append(fdId)
- .append("|")
- .append(l3Id)
- .append("|")
- .append(cgId)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- Action segReg = nxLoadRegAction(NxmNxReg0.class,
- BigInteger.valueOf(egId));
- Action scgReg = nxLoadRegAction(NxmNxReg1.class,
- BigInteger.valueOf(cgId));
- Action bdReg = nxLoadRegAction(NxmNxReg4.class,
- BigInteger.valueOf(bdId));
- Action fdReg = nxLoadRegAction(NxmNxReg5.class,
- BigInteger.valueOf(fdId));
- Action vrfReg = nxLoadRegAction(NxmNxReg6.class,
- BigInteger.valueOf(l3Id));
- FlowBuilder flowb = base()
+ .append(ofc.getNodeConnectorId().getValue())
+ .append("|")
+ .append(ep.getMacAddress().getValue())
+ .append("|")
+ .append(egId)
+ .append("|")
+ .append(bdId)
+ .append("|")
+ .append(fdId)
+ .append("|")
+ .append(l3Id)
+ .append("|")
+ .append(cgId)
+ .toString());
+ Action segReg = nxLoadRegAction(NxmNxReg0.class,
+ BigInteger.valueOf(egId));
+ Action scgReg = nxLoadRegAction(NxmNxReg1.class,
+ BigInteger.valueOf(cgId));
+ Action bdReg = nxLoadRegAction(NxmNxReg4.class,
+ BigInteger.valueOf(bdId));
+ Action fdReg = nxLoadRegAction(NxmNxReg5.class,
+ BigInteger.valueOf(fdId));
+ Action vrfReg = nxLoadRegAction(NxmNxReg6.class,
+ BigInteger.valueOf(l3Id));
+ FlowBuilder flowb = base()
.setPriority(Integer.valueOf(100))
.setId(flowid)
.setMatch(new MatchBuilder()
- .setEthernetMatch(ethernetMatch(e.getMacAddress(),
- null, null))
- .setInPort(ofc.getNodeConnectorId())
- .build())
+ .setEthernetMatch(ethernetMatch(ep.getMacAddress(),
+ null, null))
+ .setInPort(ofc.getNodeConnectorId())
+ .build())
.setInstructions(instructions(applyActionIns(segReg,
- scgReg,
- bdReg,
- fdReg,
- vrfReg),
- gotoTableIns((short)(TABLE_ID + 1))));
- writeFlow(t, tiid, flowb.build());
- }
+ scgReg,
+ bdReg,
+ fdReg,
+ vrfReg),
+ gotoTableIns((short) (TABLE_ID + 1))));
+ flowMap.writeFlow(nodeId, TABLE_ID, flowb.build());
}
+
+
}
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.Ipv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import static org.junit.Assert.*;
-
-import static org.mockito.Matchers.*;
-
-import static org.mockito.Mockito.*;
-
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
-
-public class DestinationMapperTest extends FlowTableTest {
- protected static final Logger LOG =
- LoggerFactory.getLogger(DestinationMapperTest.class);
-
- NodeConnectorId remoteTunnelId =
- new NodeConnectorId(remoteNodeId.getValue() + ":101");
-
- @Override
- @Before
- public void setup() throws Exception {
- initCtx();
- table = new DestinationMapper(ctx);
- super.setup();
- }
-
- @Test
- public void testNoEps() throws Exception {
- ReadWriteTransaction t = dosync(null);
- verify(t, times(1)).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- private void verifyDMap(Endpoint remoteEp,
- Endpoint localEp) throws Exception {
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
-
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() == null) {
- assertEquals(dropInstructions(),
- f.getInstructions());
- count += 1;
- } else if (Objects.equals(ethernetMatch(null, null, ARP),
- f.getMatch().getEthernetMatch())) {
- // router ARP reply
- Instruction ins = f.getInstructions().getInstruction().get(0);
- ins = f.getInstructions().getInstruction().get(0);
- assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- assertEquals(nxMoveEthSrcToEthDstAction(),
- actions.get(0).getAction());
- assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
- assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
- actions.get(1).getAction());
- assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
- assertEquals(nxLoadArpOpAction(BigInteger.valueOf(2L)),
- actions.get(2).getAction());
- assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
- assertEquals(nxMoveArpShaToArpThaAction(),
- actions.get(3).getAction());
- assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
- assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper
- .bytesFromHexString(DestinationMapper.ROUTER_MAC
- .getValue()))),
- actions.get(4).getAction());
- assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
- assertEquals(nxMoveArpSpaToArpTpaAction(),
- actions.get(5).getAction());
- assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
- assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) ||
- nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) ||
- nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction()));
- assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
- count += 1;
- } else if (Objects.equals(localEp.getMacAddress(),
- f.getMatch().getEthernetMatch()
- .getEthernetDestination().getAddress())) {
- int icount = 0;
- for (Instruction ins : f.getInstructions().getInstruction()) {
- if (ins.getInstruction() instanceof ApplyActionsCase) {
- long p = getOfPortNum(nodeConnectorId);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- assertEquals(nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(p)),
- actions.get(2).getAction());
- icount += 1;
- } else if (ins.getInstruction() instanceof GoToTableCase) {
- assertEquals(gotoTableIns((short)(table.getTableId()+1)),
- ins.getInstruction());
- icount += 1;
- }
- }
- assertEquals(2, icount);
- LOG.info("{}", f);
- count += 1;
- } else if (Objects.equals(remoteEp.getMacAddress(),
- f.getMatch().getEthernetMatch()
- .getEthernetDestination().getAddress())) {
- int icount = 0;
- for (Instruction ins : f.getInstructions().getInstruction()) {
- if (ins.getInstruction() instanceof ApplyActionsCase) {
- long p = getOfPortNum(tunnelId);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- assertEquals(nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(p)),
- actions.get(4).getAction());
- icount += 1;
- } else if (ins.getInstruction() instanceof GoToTableCase) {
- assertEquals(gotoTableIns((short)(table.getTableId()+1)),
- ins.getInstruction());
- icount += 1;
- }
- }
- assertEquals(2, icount);
- LOG.info("{}", f);
- count += 1;
- } else if (Objects.equals(DestinationMapper.ROUTER_MAC,
- f.getMatch().getEthernetMatch()
- .getEthernetDestination()
- .getAddress())) {
- if (f.getMatch().getLayer3Match() instanceof Ipv4Match) {
- // should be local port with rewrite dlsrc and dldst plus
- // ttl decr
- Instruction ins = f.getInstructions().getInstruction().get(0);
- assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- long p = getOfPortNum(nodeConnectorId);
- assertEquals(nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(p)),
- actions.get(2).getAction());
- assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
- assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
- actions.get(3).getAction());
- assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
- assertEquals(setDlDstAction(localEp.getMacAddress()),
- actions.get(4).getAction());
- assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
- assertEquals(decNwTtlAction(),
- actions.get(5).getAction());
- assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
- count += 1;
- } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) {
- // should be remote port with rewrite dlsrc plus
- // ttl decr
- Instruction ins = f.getInstructions().getInstruction().get(0);
- assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- long p = getOfPortNum(tunnelId);
- assertEquals(nxLoadRegAction(NxmNxReg7.class,
- BigInteger.valueOf(p)),
- actions.get(4).getAction());
- assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
- assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
- actions.get(5).getAction());
- assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
- assertEquals(decNwTtlAction(),
- actions.get(6).getAction());
- assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
- count += 1;
- }
- } else if (Objects.equals(DestinationMapper.MULTICAST_MAC,
- f.getMatch().getEthernetMatch()
- .getEthernetDestination()
- .getAddress())) {
- // broadcast/multicast flow should output to group table
- Instruction ins = f.getInstructions().getInstruction().get(0);
- ins = f.getInstructions().getInstruction().get(0);
- assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- assertEquals(nxMoveRegTunIdAction(NxmNxReg0.class, false),
- actions.get(0).getAction());
- assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
- Long v = Long.valueOf(policyManager.getContextOrdinal(tid, fd));
- assertEquals(groupAction(v), actions.get(1).getAction());
- assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
- count += 1;
- }
- }
-
- assertEquals(8, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Override
- protected EndpointBuilder localEP() {
- return super.localEP()
- .setL3Address(ImmutableList.of(new L3AddressBuilder()
- .setL3Context(l3c)
- .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1")))
- .build()));
- }
- @Override
- protected EndpointBuilder remoteEP(NodeId remoteNodeId) {
- return super.remoteEP(remoteNodeId)
- .setL3Address(ImmutableList.of(new L3AddressBuilder()
- .setL3Context(l3c)
- .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0::10.0.0.2")))
- .build()));
- }
-
- private void addSwitches() {
- switchManager.addSwitch(nodeId, tunnelId,
- Collections.<NodeConnectorId>emptySet(),
- new OfOverlayNodeConfigBuilder()
- .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
- .build());
- switchManager.addSwitch(remoteNodeId, remoteTunnelId,
- Collections.<NodeConnectorId>emptySet(),
- new OfOverlayNodeConfigBuilder()
- .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.5")))
- .build());
- }
-
- @Test
- public void testSame() throws Exception {
- Endpoint localEp = localEP().build();
- endpointManager.addEndpoint(localEp);
- Endpoint remoteEp = remoteEP(remoteNodeId).build();
- endpointManager.addEndpoint(remoteEp);
- addSwitches();
-
- policyResolver.addTenant(baseTenant().build());
- verifyDMap(remoteEp, localEp);
- }
-
- @Test
- public void testDiff() throws Exception {
- Endpoint localEp = localEP().build();
- endpointManager.addEndpoint(localEp);
- Endpoint remoteEp = remoteEP(remoteNodeId)
- .setEndpointGroup(eg2)
- .build();
- endpointManager.addEndpoint(remoteEp);
- addSwitches();
-
- policyResolver.addTenant(baseTenant().build());
- verifyDMap(remoteEp, localEp);
- }
-
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import java.math.BigInteger;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Objects;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.ImmutableList;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;\r
+\r
+public class DestinationMapperTest extends FlowTableTest {\r
+ protected static final Logger LOG =\r
+ LoggerFactory.getLogger(DestinationMapperTest.class);\r
+\r
+ NodeConnectorId remoteTunnelId =\r
+ new NodeConnectorId(remoteNodeId.getValue() + ":101");\r
+\r
+ @Override\r
+ @Before\r
+ public void setup() throws Exception {\r
+ initCtx();\r
+ table = new DestinationMapper(ctx);\r
+ super.setup();\r
+ }\r
+\r
+ @Test\r
+ public void testNoEps() throws Exception {\r
+ FlowMap fm = dosync(null);\r
+ assertEquals(1 ,fm.getTableForNode(nodeId, (short) 2).getFlow().size());\r
+ }\r
+\r
+ private void verifyDMap(Endpoint remoteEp,\r
+ Endpoint localEp) throws Exception {\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0 ,fm.getTableForNode(nodeId, (short) 2).getFlow().size());\r
+\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f :fm.getTableForNode(nodeId, (short) 2).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() == null) {\r
+ assertEquals(dropInstructions(),\r
+ f.getInstructions());\r
+ count += 1;\r
+ } else if (Objects.equals(ethernetMatch(null, null, ARP),\r
+ f.getMatch().getEthernetMatch())) {\r
+ // router ARP reply\r
+ Instruction ins = f.getInstructions().getInstruction().get(0);\r
+ ins = f.getInstructions().getInstruction().get(0);\r
+ assertTrue(ins.getInstruction() instanceof ApplyActionsCase);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ assertEquals(nxMoveEthSrcToEthDstAction(),\r
+ actions.get(0).getAction());\r
+ assertEquals(Integer.valueOf(0), actions.get(0).getOrder());\r
+ assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),\r
+ actions.get(1).getAction());\r
+ assertEquals(Integer.valueOf(1), actions.get(1).getOrder());\r
+ assertEquals(nxLoadArpOpAction(BigInteger.valueOf(2L)),\r
+ actions.get(2).getAction());\r
+ assertEquals(Integer.valueOf(2), actions.get(2).getOrder());\r
+ assertEquals(nxMoveArpShaToArpThaAction(),\r
+ actions.get(3).getAction());\r
+ assertEquals(Integer.valueOf(3), actions.get(3).getOrder());\r
+ assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper\r
+ .bytesFromHexString(DestinationMapper.ROUTER_MAC\r
+ .getValue()))),\r
+ actions.get(4).getAction());\r
+ assertEquals(Integer.valueOf(4), actions.get(4).getOrder());\r
+ assertEquals(nxMoveArpSpaToArpTpaAction(),\r
+ actions.get(5).getAction());\r
+ assertEquals(Integer.valueOf(5), actions.get(5).getOrder());\r
+ assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) ||\r
+ nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) ||\r
+ nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction()));\r
+ assertEquals(Integer.valueOf(6), actions.get(6).getOrder());\r
+ count += 1;\r
+ } else if (Objects.equals(localEp.getMacAddress(),\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetDestination().getAddress())) {\r
+ int icount = 0;\r
+ for (Instruction ins : f.getInstructions().getInstruction()) {\r
+ if (ins.getInstruction() instanceof ApplyActionsCase) {\r
+ long p = getOfPortNum(nodeConnectorId);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ assertEquals(nxLoadRegAction(NxmNxReg7.class,\r
+ BigInteger.valueOf(p)),\r
+ actions.get(2).getAction());\r
+ icount += 1;\r
+ } else if (ins.getInstruction() instanceof GoToTableCase) {\r
+ assertEquals(gotoTableIns((short)(table.getTableId()+1)),\r
+ ins.getInstruction());\r
+ icount += 1;\r
+ }\r
+ }\r
+ assertEquals(2, icount);\r
+ LOG.info("{}", f);\r
+ count += 1;\r
+ } else if (Objects.equals(remoteEp.getMacAddress(),\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetDestination().getAddress())) {\r
+ int icount = 0;\r
+ for (Instruction ins : f.getInstructions().getInstruction()) {\r
+ if (ins.getInstruction() instanceof ApplyActionsCase) {\r
+ long p = getOfPortNum(tunnelId);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ assertEquals(nxLoadRegAction(NxmNxReg7.class,\r
+ BigInteger.valueOf(p)),\r
+ actions.get(4).getAction());\r
+ icount += 1;\r
+ } else if (ins.getInstruction() instanceof GoToTableCase) {\r
+ assertEquals(gotoTableIns((short)(table.getTableId()+1)),\r
+ ins.getInstruction());\r
+ icount += 1;\r
+ }\r
+ }\r
+ assertEquals(2, icount);\r
+ LOG.info("{}", f);\r
+ count += 1;\r
+ } else if (Objects.equals(DestinationMapper.ROUTER_MAC,\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetDestination()\r
+ .getAddress())) {\r
+ if (f.getMatch().getLayer3Match() instanceof Ipv4Match) {\r
+ // should be local port with rewrite dlsrc and dldst plus\r
+ // ttl decr\r
+ Instruction ins = f.getInstructions().getInstruction().get(0);\r
+ assertTrue(ins.getInstruction() instanceof ApplyActionsCase);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ long p = getOfPortNum(nodeConnectorId);\r
+ assertEquals(nxLoadRegAction(NxmNxReg7.class,\r
+ BigInteger.valueOf(p)),\r
+ actions.get(2).getAction());\r
+ assertEquals(Integer.valueOf(2), actions.get(2).getOrder());\r
+ assertEquals(Integer.valueOf(3), actions.get(3).getOrder());\r
+ assertEquals(Integer.valueOf(4), actions.get(4).getOrder());\r
+ assertEquals(decNwTtlAction(),\r
+ actions.get(5).getAction());\r
+ assertEquals(Integer.valueOf(5), actions.get(5).getOrder());\r
+ count += 1;\r
+ } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) {\r
+ // should be remote port with rewrite dlsrc plus\r
+ // ttl decr\r
+ Instruction ins = f.getInstructions().getInstruction().get(0);\r
+ assertTrue(ins.getInstruction() instanceof ApplyActionsCase);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ long p = getOfPortNum(tunnelId);\r
+ assertEquals(nxLoadRegAction(NxmNxReg7.class,\r
+ BigInteger.valueOf(p)),\r
+ actions.get(4).getAction());\r
+ assertEquals(Integer.valueOf(4), actions.get(4).getOrder());\r
+ assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),\r
+ actions.get(5).getAction());\r
+ assertEquals(Integer.valueOf(5), actions.get(5).getOrder());\r
+ assertEquals(decNwTtlAction(),\r
+ actions.get(6).getAction());\r
+ assertEquals(Integer.valueOf(6), actions.get(6).getOrder());\r
+ count += 1;\r
+ }\r
+ } else if (Objects.equals(DestinationMapper.MULTICAST_MAC,\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetDestination()\r
+ .getAddress())) {\r
+ // broadcast/multicast flow should output to group table\r
+ Instruction ins = f.getInstructions().getInstruction().get(0);\r
+ ins = f.getInstructions().getInstruction().get(0);\r
+ assertTrue(ins.getInstruction() instanceof ApplyActionsCase);\r
+ List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();\r
+ assertEquals(nxMoveRegTunIdAction(NxmNxReg0.class, false),\r
+ actions.get(0).getAction());\r
+ assertEquals(Integer.valueOf(0), actions.get(0).getOrder());\r
+ \r
+ Long v = Long.valueOf(OrdinalFactory.getContextOrdinal(tid, fd));\r
+ assertEquals(groupAction(v), actions.get(1).getAction());\r
+ assertEquals(Integer.valueOf(1), actions.get(1).getOrder());\r
+ count += 1;\r
+ }\r
+ }\r
+\r
+ assertEquals(8, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 2).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 2).getFlow().size());\r
+ }\r
+\r
+ @Override\r
+ protected EndpointBuilder localEP() {\r
+ return super.localEP()\r
+ .setL3Address(ImmutableList.of(new L3AddressBuilder()\r
+ .setL3Context(l3c)\r
+ .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1")))\r
+ .build()));\r
+ }\r
+ @Override\r
+ protected EndpointBuilder remoteEP(NodeId remoteNodeId) {\r
+ return super.remoteEP(remoteNodeId)\r
+ .setL3Address(ImmutableList.of(new L3AddressBuilder()\r
+ .setL3Context(l3c)\r
+ .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0::10.0.0.2")))\r
+ .build()));\r
+ }\r
+\r
+ private void addSwitches() {\r
+ switchManager.addSwitch(nodeId, tunnelId,\r
+ Collections.<NodeConnectorId>emptySet(),\r
+ new OfOverlayNodeConfigBuilder()\r
+ .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))\r
+ .build());\r
+ switchManager.addSwitch(remoteNodeId, remoteTunnelId,\r
+ Collections.<NodeConnectorId>emptySet(),\r
+ new OfOverlayNodeConfigBuilder()\r
+ .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.5")))\r
+ .build());\r
+ }\r
+\r
+ @Test\r
+ public void testSame() throws Exception {\r
+ Endpoint localEp = localEP().build();\r
+ endpointManager.addEndpoint(localEp);\r
+ Endpoint remoteEp = remoteEP(remoteNodeId).build();\r
+ endpointManager.addEndpoint(remoteEp);\r
+ addSwitches();\r
+\r
+ policyResolver.addTenant(baseTenant().build());\r
+ verifyDMap(remoteEp, localEp);\r
+ }\r
+\r
+ @Test\r
+ public void testDiff() throws Exception {\r
+ Endpoint localEp = localEP().build();\r
+ endpointManager.addEndpoint(localEp);\r
+ Endpoint remoteEp = remoteEP(remoteNodeId)\r
+ .setEndpointGroup(eg2)\r
+ .build();\r
+ endpointManager.addEndpoint(remoteEp);\r
+ addSwitches();\r
+\r
+ policyResolver.addTenant(baseTenant().build());\r
+ verifyDMap(remoteEp, localEp);\r
+ }\r
+\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import static org.mockito.Mockito.*;
-
-public class FlowTableTest extends OfTableTest {
- FlowTable table;
- InstanceIdentifier<Table> tiid;
-
- protected void setup() throws Exception {
- tiid = FlowUtils.createTablePath(nodeId,
- table.getTableId());
- }
-
- protected ReadWriteTransaction dosync(Map<String, FlowCtx> flowMap)
- throws Exception {
- ReadWriteTransaction t = mock(ReadWriteTransaction.class);
- if (flowMap == null)
- flowMap = Collections.emptyMap();
- table.sync(t, tiid, flowMap, nodeId, policyResolver.getCurrentPolicy(),
- null);
- return t;
- }
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import java.util.Map;\r
+\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+\r
+public class FlowTableTest extends OfTableTest {\r
+ FlowTable table;\r
+ InstanceIdentifier<Table> tiid;\r
+\r
+ protected void setup() throws Exception {\r
+ tiid = FlowUtils.createTablePath(nodeId,\r
+ table.getTableId());\r
+ }\r
+\r
+ protected FlowMap dosync(Map<String, Flow> flows) throws Exception {\r
+ FlowMap flowMap = policyManager.new FlowMap();\r
+ if (flows != null) {\r
+ for (String key : flows.keySet()) {\r
+ Flow flow = flows.get(key);\r
+ if (flow != null) {\r
+ flowMap.writeFlow(nodeId, flow.getTableId(), flow);\r
+ }\r
+ }\r
+ }\r
+ table.sync(nodeId, policyResolver.getCurrentPolicy(), flowMap);\r
+ return flowMap;\r
+ }\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.util.Collections;
-import java.util.HashMap;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.BucketCtx;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.GroupCtx;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-
-import static org.junit.Assert.*;
-
-public class GroupTableTest extends OfTableTest {
- protected static final Logger LOG =
- LoggerFactory.getLogger(GroupTableTest.class);
-
- GroupTable table;
-
- NodeConnectorId tunnelId =
- new NodeConnectorId(nodeId.getValue() + ":42");
- NodeConnectorId remoteTunnelId =
- new NodeConnectorId(remoteNodeId.getValue() + ":101");
-
- @Before
- public void setup() throws Exception {
- initCtx();
- table = new GroupTable(ctx);
- }
-
- @Test
- public void testGroup() throws Exception {
- Endpoint localEp = localEP().build();
- endpointManager.addEndpoint(localEp);
- Endpoint remoteEp = remoteEP(remoteNodeId).build();
- endpointManager.addEndpoint(remoteEp);
-
- switchManager.addSwitch(nodeId, tunnelId,
- Collections.<NodeConnectorId>emptySet(),
- new OfOverlayNodeConfigBuilder()
- .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
- .build());
- switchManager.addSwitch(remoteNodeId, remoteTunnelId,
- Collections.<NodeConnectorId>emptySet(),
- new OfOverlayNodeConfigBuilder()
- .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.5")))
- .build());
-
- policyResolver.addTenant(baseTenant().build());
-
- HashMap<GroupId, GroupCtx> groupMap = new HashMap<>();
- table.sync(nodeId, ctx.getPolicyResolver().getCurrentPolicy(),
- null, groupMap);
-
- assertEquals(1, groupMap.size());
- int fdId = ctx.getPolicyManager().getContextOrdinal(tid, fd);
- GroupCtx ctx = groupMap.get(new GroupId(Long.valueOf(fdId)));
- assertNotNull(ctx);
- long tunBucketId =
- (long)policyManager.getContextOrdinal(remoteNodeId.getValue());
- tunBucketId |= 1L << 31;
-
- int count = 0;
- for (BucketCtx bctx : ctx.bucketMap.values()) {
- if (Objects.equal(Long.valueOf(4),
- bctx.newb.getBucketId().getValue())) {
- count += 1;
- } else if (Objects.equal(Long.valueOf(tunBucketId),
- bctx.newb.getBucketId().getValue())) {
-
- count += 1;
- }
- }
- assertEquals(2, count);
- }
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.BucketCtx;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.GroupCtx;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.base.Objects;\r
+\r
+public class GroupTableTest extends OfTableTest {\r
+ protected static final Logger LOG =\r
+ LoggerFactory.getLogger(GroupTableTest.class);\r
+\r
+ GroupTable table;\r
+\r
+ NodeConnectorId tunnelId =\r
+ new NodeConnectorId(nodeId.getValue() + ":42");\r
+ NodeConnectorId remoteTunnelId =\r
+ new NodeConnectorId(remoteNodeId.getValue() + ":101");\r
+\r
+ @Before\r
+ public void setup() throws Exception {\r
+ initCtx();\r
+ table = new GroupTable(ctx);\r
+ }\r
+\r
+ @Test\r
+ public void testGroup() throws Exception {\r
+ Endpoint localEp = localEP().build();\r
+ endpointManager.addEndpoint(localEp);\r
+ Endpoint remoteEp = remoteEP(remoteNodeId).build();\r
+ endpointManager.addEndpoint(remoteEp);\r
+\r
+ switchManager.addSwitch(nodeId, tunnelId,\r
+ Collections.<NodeConnectorId>emptySet(),\r
+ new OfOverlayNodeConfigBuilder()\r
+ .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))\r
+ .build());\r
+ switchManager.addSwitch(remoteNodeId, remoteTunnelId,\r
+ Collections.<NodeConnectorId>emptySet(),\r
+ new OfOverlayNodeConfigBuilder()\r
+ .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.5")))\r
+ .build());\r
+\r
+ policyResolver.addTenant(baseTenant().build());\r
+\r
+ HashMap<GroupId, GroupCtx> groupMap = new HashMap<>();\r
+ table.sync(nodeId, ctx.getPolicyResolver().getCurrentPolicy(), groupMap);\r
+\r
+ assertEquals(1, groupMap.size());\r
+ int fdId = OrdinalFactory.getContextOrdinal(tid, fd);\r
+ GroupCtx ctx = groupMap.get(new GroupId(Long.valueOf(fdId)));\r
+ assertNotNull(ctx);\r
+ long tunBucketId =\r
+ OrdinalFactory.getContextOrdinal(remoteNodeId);\r
+ tunBucketId |= 1L << 31;\r
+\r
+ int count = 0;\r
+ for (BucketCtx bctx : ctx.bucketMap.values()) {\r
+ if (Objects.equal(Long.valueOf(4),\r
+ bctx.newb.getBucketId().getValue())) {\r
+ count += 1;\r
+ } else if (Objects.equal(Long.valueOf(tunBucketId),\r
+ bctx.newb.getBucketId().getValue())) {\r
+\r
+ count += 1;\r
+ }\r
+ }\r
+ assertEquals(2, count);\r
+ }\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockEndpointManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockSwitchManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
-import org.opendaylight.groupbasedpolicy.resolver.MockPolicyResolver;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubjectFeatureInstancesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstanceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-
-import com.google.common.collect.ImmutableList;
-
-public class OfTableTest {
- OfContext ctx;
-
- MockEndpointManager endpointManager;
- MockPolicyResolver policyResolver;
- MockPolicyManager policyManager;
- MockSwitchManager switchManager;
-
- NodeId nodeId = new NodeId("openflow:1");
- NodeId remoteNodeId = new NodeId("openflow:2");
- NodeConnectorId nodeConnectorId =
- new NodeConnectorId(nodeId.getValue() + ":4");
-
- NodeConnectorId tunnelId =
- new NodeConnectorId(nodeId.getValue() + ":42");
-
- L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d");
- L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639");
- L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");
- SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");
- SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");
- SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec");
- TenantId tid = new TenantId("1118c691-8520-47ad-80b8-4cf5e3fe3302");
- EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");
- EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");
- ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f");
-
- protected void initCtx() {
- endpointManager = new MockEndpointManager();
- policyResolver = new MockPolicyResolver();
- policyManager = new MockPolicyManager(policyResolver, endpointManager);
- switchManager = new MockSwitchManager();
-
- ctx = new OfContext(null,
- null,
- policyManager,
- policyResolver,
- switchManager,
- endpointManager,
- null);
- }
-
- protected TenantBuilder baseTenant() {
- return baseTenant(null);
- }
-
- protected TenantBuilder baseTenant(Direction direction) {
- return new TenantBuilder()
- .setId(tid)
- .setEndpointGroup(ImmutableList.of(new EndpointGroupBuilder()
- .setId(eg)
- .setNetworkDomain(sub)
- .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder()
- .setName(new SelectorName("cns1"))
- .setContract(ImmutableList.of(cid))
- .build()))
- .build(),
- new EndpointGroupBuilder()
- .setId(eg2)
- .setNetworkDomain(sub2)
- .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder()
- .setName(new SelectorName("pns1"))
- .setContract(ImmutableList.of(cid))
- .build()))
- .build()))
- .setL3Context(ImmutableList.of(new L3ContextBuilder()
- .setId(l3c)
- .build()))
- .setL2BridgeDomain(ImmutableList.of(new L2BridgeDomainBuilder()
- .setId(bd)
- .setParent(l3c)
- .build()))
- .setL2FloodDomain(ImmutableList.of(new L2FloodDomainBuilder()
- .setId(fd)
- .setParent(bd)
- .build()))
- .setSubnet(ImmutableList.of(new SubnetBuilder()
- .setId(sub2)
- .setParent(fd)
- .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.1/24")))
- .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.1.1")))
- .build(),
- new SubnetBuilder()
- .setId(sub)
- .setParent(fd)
- .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.1/24")))
- .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1")))
- .build(),
- new SubnetBuilder()
- .setId(sub3)
- .setParent(bd)
- .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.1/24")))
- .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))
- .build()))
- .setSubjectFeatureInstances(new SubjectFeatureInstancesBuilder()
- .setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder()
- .setName(new ClassifierName("tcp_80"))
- .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
- .setParameterValue(ImmutableList.of(new ParameterValueBuilder()
- .setName(new ParameterName("destport"))
- .setIntValue(Long.valueOf(80))
- .build(),
- new ParameterValueBuilder()
- .setName(new ParameterName("proto"))
- .setIntValue(Long.valueOf(6))
- .build()))
- .build()))
- .setActionInstance(ImmutableList.of(new ActionInstanceBuilder()
- .setName(new ActionName("allow"))
- .setActionDefinitionId(new AllowAction().getId())
- .build()))
- .build())
- .setContract(ImmutableList.of(new ContractBuilder()
- .setId(cid)
- .setSubject(ImmutableList.of(baseSubject(direction).build()))
- .setClause(ImmutableList.of(new ClauseBuilder()
- .setName(new ClauseName("test"))
- .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
- .build()))
- .build()));
- }
-
- protected SubjectBuilder baseSubject(Direction direction) {
- return new SubjectBuilder()
- .setName(new SubjectName("s1"))
- .setRule(ImmutableList.of(new RuleBuilder()
- .setActionRef(ImmutableList.of(new ActionRefBuilder()
- .setName(new ActionName("allow"))
- .build()))
- .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder()
- .setName(new ClassifierName("tcp_80"))
- .setDirection(direction)
- .build()))
- .build()));
- }
-
- protected EndpointBuilder baseEP() {
- return new EndpointBuilder()
- .setL2Context(bd)
- .setTenant(tid)
- .setEndpointGroup(eg)
- .setMacAddress(new MacAddress("00:00:00:00:00:01"));
- }
-
- protected EndpointBuilder localEP() {
- OfOverlayContext ofc = new OfOverlayContextBuilder()
- .setNodeId(nodeId)
- .setNodeConnectorId(nodeConnectorId)
- .build();
- return baseEP()
- .addAugmentation(OfOverlayContext.class, ofc);
- }
-
- protected EndpointBuilder remoteEP(NodeId id) {
- OfOverlayContext ofc = new OfOverlayContextBuilder()
- .setNodeId(id)
- .setNodeConnectorId(new NodeConnectorId(id.getValue() + ":5"))
- .build();
- return baseEP()
- .setMacAddress(new MacAddress("00:00:00:00:00:02"))
- .addAugmentation(OfOverlayContext.class, ofc);
- }
-
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockEndpointManager;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockSwitchManager;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;\r
+import org.opendaylight.groupbasedpolicy.resolver.MockPolicyResolver;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubjectFeatureInstancesBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstanceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
+\r
+import com.google.common.collect.ImmutableList;\r
+\r
+public class OfTableTest {\r
+ OfContext ctx;\r
+\r
+ MockEndpointManager endpointManager;\r
+ MockPolicyResolver policyResolver;\r
+ MockPolicyManager policyManager;\r
+ MockSwitchManager switchManager;\r
+ NodeId nodeId = new NodeId("openflow:1");\r
+ NodeId remoteNodeId = new NodeId("openflow:2");\r
+ NodeConnectorId nodeConnectorId =\r
+ new NodeConnectorId(nodeId.getValue() + ":4");\r
+\r
+ NodeConnectorId tunnelId =\r
+ new NodeConnectorId(nodeId.getValue() + ":42");\r
+\r
+ L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d");\r
+ L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639");\r
+ L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");\r
+ SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");\r
+ SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");\r
+ SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec");\r
+ TenantId tid = new TenantId("1118c691-8520-47ad-80b8-4cf5e3fe3302");\r
+ EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");\r
+ EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");\r
+ ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f");\r
+\r
+ protected void initCtx() {\r
+ endpointManager = new MockEndpointManager();\r
+ policyResolver = new MockPolicyResolver();\r
+ policyManager = new MockPolicyManager(policyResolver, endpointManager);\r
+ switchManager = new MockSwitchManager();\r
+ ctx = new OfContext(null,\r
+ null,\r
+ policyManager,\r
+ policyResolver,\r
+ switchManager,\r
+ endpointManager,\r
+ null);\r
+ }\r
+\r
+ protected TenantBuilder baseTenant() {\r
+ return baseTenant(null);\r
+ }\r
+\r
+ protected TenantBuilder baseTenant(Direction direction) {\r
+ return new TenantBuilder()\r
+ .setId(tid)\r
+ .setEndpointGroup(ImmutableList.of(new EndpointGroupBuilder()\r
+ .setId(eg)\r
+ .setNetworkDomain(sub)\r
+ .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder()\r
+ .setName(new SelectorName("cns1"))\r
+ .setContract(ImmutableList.of(cid))\r
+ .build()))\r
+ .build(),\r
+ new EndpointGroupBuilder()\r
+ .setId(eg2)\r
+ .setNetworkDomain(sub2)\r
+ .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder()\r
+ .setName(new SelectorName("pns1"))\r
+ .setContract(ImmutableList.of(cid))\r
+ .build()))\r
+ .build()))\r
+ .setL3Context(ImmutableList.of(new L3ContextBuilder()\r
+ .setId(l3c)\r
+ .build()))\r
+ .setL2BridgeDomain(ImmutableList.of(new L2BridgeDomainBuilder()\r
+ .setId(bd)\r
+ .setParent(l3c)\r
+ .build()))\r
+ .setL2FloodDomain(ImmutableList.of(new L2FloodDomainBuilder()\r
+ .setId(fd)\r
+ .setParent(bd)\r
+ .build()))\r
+ .setSubnet(ImmutableList.of(new SubnetBuilder()\r
+ .setId(sub2)\r
+ .setParent(fd)\r
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.1/24")))\r
+ .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.1.1")))\r
+ .build(),\r
+ new SubnetBuilder()\r
+ .setId(sub)\r
+ .setParent(fd)\r
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.1/24")))\r
+ .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1")))\r
+ .build(),\r
+ new SubnetBuilder()\r
+ .setId(sub3)\r
+ .setParent(bd)\r
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.1/24")))\r
+ .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))\r
+ .build()))\r
+ .setSubjectFeatureInstances(new SubjectFeatureInstancesBuilder()\r
+ .setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder()\r
+ .setName(new ClassifierName("tcp_80"))\r
+ .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())\r
+ .setParameterValue(ImmutableList.of(new ParameterValueBuilder()\r
+ .setName(new ParameterName("destport"))\r
+ .setIntValue(Long.valueOf(80))\r
+ .build(),\r
+ new ParameterValueBuilder()\r
+ .setName(new ParameterName("proto"))\r
+ .setIntValue(Long.valueOf(6))\r
+ .build()))\r
+ .build()))\r
+ .setActionInstance(ImmutableList.of(new ActionInstanceBuilder()\r
+ .setName(new ActionName("allow"))\r
+ .setActionDefinitionId(new AllowAction().getId())\r
+ .build()))\r
+ .build())\r
+ .setContract(ImmutableList.of(new ContractBuilder()\r
+ .setId(cid)\r
+ .setSubject(ImmutableList.of(baseSubject(direction).build()))\r
+ .setClause(ImmutableList.of(new ClauseBuilder()\r
+ .setName(new ClauseName("test"))\r
+ .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))\r
+ .build()))\r
+ .build()));\r
+ }\r
+\r
+ protected SubjectBuilder baseSubject(Direction direction) {\r
+ return new SubjectBuilder()\r
+ .setName(new SubjectName("s1"))\r
+ .setRule(ImmutableList.of(new RuleBuilder()\r
+ .setActionRef(ImmutableList.of(new ActionRefBuilder()\r
+ .setName(new ActionName("allow"))\r
+ .build()))\r
+ .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder()\r
+ .setName(new ClassifierName("tcp_80"))\r
+ .setDirection(direction)\r
+ .build()))\r
+ .build()));\r
+ }\r
+\r
+ protected EndpointBuilder baseEP() {\r
+ return new EndpointBuilder()\r
+ .setL2Context(bd)\r
+ .setTenant(tid)\r
+ .setEndpointGroup(eg)\r
+ .setMacAddress(new MacAddress("00:00:00:00:00:01"));\r
+ }\r
+\r
+ protected EndpointBuilder localEP() {\r
+ OfOverlayContext ofc = new OfOverlayContextBuilder()\r
+ .setNodeId(nodeId)\r
+ .setNodeConnectorId(nodeConnectorId)\r
+ .build();\r
+ return baseEP()\r
+ .addAugmentation(OfOverlayContext.class, ofc);\r
+ }\r
+\r
+ protected EndpointBuilder remoteEP(NodeId id) {\r
+ OfOverlayContext ofc = new OfOverlayContextBuilder()\r
+ .setNodeId(id)\r
+ .setNodeConnectorId(new NodeConnectorId(id.getValue() + ":5"))\r
+ .build();\r
+ return baseEP()\r
+ .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
+ .addAugmentation(OfOverlayContext.class, ofc);\r
+ }\r
+\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
-import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
-import org.opendaylight.groupbasedpolicy.resolver.EgKey;
-import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import static org.junit.Assert.*;
-
-import static org.mockito.Matchers.*;
-
-import static org.mockito.Mockito.*;
-
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
-
-public class PolicyEnforcerTest extends FlowTableTest {
- protected static final Logger LOG =
- LoggerFactory.getLogger(PolicyEnforcerTest.class);
-
- @Before
- public void setup() throws Exception {
- initCtx();
- table = new PolicyEnforcer(ctx);
- super.setup();
-
- switchManager.addSwitch(nodeId, tunnelId,
- Collections.<NodeConnectorId>emptySet(),
- new OfOverlayNodeConfigBuilder()
- .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
- .build());
- }
-
- @Test
- public void testNoEps() throws Exception {
- ReadWriteTransaction t = dosync(null);
- verify(t, times(2)).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testSameEg() throws Exception {
- Endpoint ep1 = localEP().build();
- endpointManager.addEndpoint(ep1);
- Endpoint ep2 = localEP()
- .setMacAddress(new MacAddress("00:00:00:00:00:02"))
- .build();
- endpointManager.addEndpoint(ep2);
- policyResolver.addTenant(baseTenant().build());
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getId().getValue().indexOf("intraallow") == 0)
- count += 1;
- }
- assertEquals(1, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testDifferentEg() throws Exception {
- doTestDifferentEg(null);
- doTestDifferentEg(Direction.Bidirectional);
- doTestDifferentEg(Direction.In);
- doTestDifferentEg(Direction.Out);
- }
-
- public void doTestDifferentEg(Direction direction) throws Exception {
- Endpoint ep1 = localEP().build();
- endpointManager.addEndpoint(ep1);
- Endpoint ep2 = localEP()
- .setMacAddress(new MacAddress("00:00:00:00:00:02"))
- .setEndpointGroup(eg2)
- .build();
- endpointManager.addEndpoint(ep2);
- policyResolver.addTenant(baseTenant(direction).build());
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getId().getValue().indexOf("intraallow") == 0) {
- count += 1;
- } else if (f.getMatch() != null &&
- Objects.equals(tunnelId, f.getMatch().getInPort())) {
- assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))),
- f.getInstructions());
- count += 1;
- } else if (f.getMatch() != null &&
- f.getMatch().getEthernetMatch() != null &&
- Objects.equals(FlowUtils.IPv4,
- f.getMatch().getEthernetMatch()
- .getEthernetType().getType().getValue()) &&
- f.getMatch().getIpMatch() != null &&
- Objects.equals(Short.valueOf((short)6),
- f.getMatch().getIpMatch().getIpProtocol()) &&
- Objects.equals(Integer.valueOf(80),
- ((TcpMatch)f.getMatch().getLayer4Match())
- .getTcpDestinationPort().getValue())) {
- count += 1;
- } else if (f.getMatch() != null &&
- f.getMatch().getEthernetMatch() != null &&
- Objects.equals(FlowUtils.IPv6,
- f.getMatch().getEthernetMatch()
- .getEthernetType().getType().getValue()) &&
- f.getMatch().getIpMatch() != null &&
- Objects.equals(Short.valueOf((short)6),
- f.getMatch().getIpMatch().getIpProtocol()) &&
- Objects.equals(Integer.valueOf(80),
- ((TcpMatch)f.getMatch().getLayer4Match())
- .getTcpDestinationPort().getValue())) {
- count += 1;
- }
- }
- if (direction == null || direction.equals(Direction.Bidirectional))
- assertEquals(7, count);
- else
- assertEquals(5, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testConditions() throws Exception {
- Condition cond1 = new ConditionBuilder()
- .setName(new ConditionName("cond1"))
- .build();
- Condition cond2 = new ConditionBuilder()
- .setName(new ConditionName("cond2"))
- .build();
-
- Endpoint ep1 = localEP()
- .setCondition(ImmutableList.of(cond1.getName()))
- .build();
- endpointManager.addEndpoint(ep1);
- Endpoint ep2 = localEP()
- .setMacAddress(new MacAddress("00:00:00:00:00:02"))
- .setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))
- .setEndpointGroup(eg2)
- .build();
- endpointManager.addEndpoint(ep2);
-
- TenantBuilder tb = baseTenant()
- .setContract(ImmutableList.of(new ContractBuilder()
- .setId(cid)
- .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
- .setClause(ImmutableList.of(new ClauseBuilder()
- .setName(new ClauseName("test"))
- .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
- .setConsumerMatchers(new ConsumerMatchersBuilder()
- .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
- .setName(new ConditionMatcherName("m1"))
- .setCondition(ImmutableList.of(cond1, cond2))
- .setMatchType(MatchType.Any)
- .build()))
- .build())
- .setProviderMatchers(new ProviderMatchersBuilder()
- .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
- .setName(new ConditionMatcherName("m2"))
- .setCondition(ImmutableList.of(cond1, cond2))
- .setMatchType(MatchType.All)
- .build()))
- .build())
- .build()))
- .build()));
- policyResolver.addTenant(tb.build());
-
- PolicyInfo policy = policyResolver.getCurrentPolicy();
- List<ConditionName> ep1c = endpointManager.getCondsForEndpoint(ep1);
- ConditionGroup cg1 =
- policy.getEgCondGroup(new EgKey(tb.getId(),
- ep1.getEndpointGroup()),
- ep1c);
- List<ConditionName> ep2c = endpointManager.getCondsForEndpoint(ep2);
- ConditionGroup cg2 =
- policy.getEgCondGroup(new EgKey(tb.getId(),
- ep2.getEndpointGroup()),
- ep2c);
- int cg1Id = policyManager.getCondGroupOrdinal(cg1);
- int cg2Id = policyManager.getCondGroupOrdinal(cg2);
- int eg1Id = policyManager.getContextOrdinal(ep1.getTenant(),
- ep1.getEndpointGroup());
- int eg2Id = policyManager.getContextOrdinal(ep1.getTenant(),
- ep2.getEndpointGroup());
-
- assertNotEquals(cg1Id, cg2Id);
-
- MatchBuilder mb = new MatchBuilder();
- FlowUtils.addNxRegMatch(mb,
- RegMatch.of(NxmNxReg0.class, Long.valueOf(eg1Id)),
- RegMatch.of(NxmNxReg1.class, Long.valueOf(cg1Id)),
- RegMatch.of(NxmNxReg2.class, Long.valueOf(eg2Id)),
- RegMatch.of(NxmNxReg3.class, Long.valueOf(cg2Id)));
- GeneralAugMatchNodesNodeTableFlow m1 =
- mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
- FlowUtils.addNxRegMatch(mb,
- RegMatch.of(NxmNxReg0.class, Long.valueOf(eg2Id)),
- RegMatch.of(NxmNxReg1.class, Long.valueOf(cg2Id)),
- RegMatch.of(NxmNxReg2.class, Long.valueOf(eg1Id)),
- RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));
- GeneralAugMatchNodesNodeTableFlow m2 =
- mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() != null &&
- f.getMatch().getEthernetMatch() != null) {
- GeneralAugMatchNodesNodeTableFlow fm =
- f.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
- assertTrue(Objects.equals(fm, m1) ||
- Objects.equals(fm, m2));
- count += 1;
- }
- }
- assertEquals(2, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Objects;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;\r
+import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;\r
+import org.opendaylight.groupbasedpolicy.resolver.EgKey;\r
+import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.ImmutableList;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;\r
+\r
+public class PolicyEnforcerTest extends FlowTableTest {\r
+ protected static final Logger LOG = \r
+ LoggerFactory.getLogger(PolicyEnforcerTest.class);\r
+\r
+ @Before\r
+ public void setup() throws Exception {\r
+ initCtx();\r
+ table = new PolicyEnforcer(ctx);\r
+ super.setup();\r
+ \r
+ switchManager.addSwitch(nodeId, tunnelId, \r
+ Collections.<NodeConnectorId>emptySet(),\r
+ new OfOverlayNodeConfigBuilder()\r
+ .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))\r
+ .build());\r
+ }\r
+\r
+ @Test\r
+ public void testNoEps() throws Exception {\r
+ FlowMap fm = dosync(null);\r
+ assertEquals(2, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testSameEg() throws Exception {\r
+ Endpoint ep1 = localEP().build();\r
+ endpointManager.addEndpoint(ep1);\r
+ Endpoint ep2 = localEP()\r
+ .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
+ .build();\r
+ endpointManager.addEndpoint(ep2);\r
+ policyResolver.addTenant(baseTenant().build());\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getId().getValue().indexOf("intraallow") == 0)\r
+ count += 1;\r
+ }\r
+ assertEquals(1, count);\r
+ assertEquals(3, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ fm = dosync(flowMap);\r
+ assertEquals(3, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testDifferentEg() throws Exception {\r
+ doTestDifferentEg(null);\r
+ doTestDifferentEg(Direction.Bidirectional);\r
+ doTestDifferentEg(Direction.In);\r
+ doTestDifferentEg(Direction.Out);\r
+ }\r
+\r
+ public void doTestDifferentEg(Direction direction) throws Exception {\r
+ Endpoint ep1 = localEP().build();\r
+ endpointManager.addEndpoint(ep1);\r
+ Endpoint ep2 = localEP()\r
+ .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
+ .setEndpointGroup(eg2)\r
+ .build();\r
+ endpointManager.addEndpoint(ep2);\r
+ policyResolver.addTenant(baseTenant(direction).build());\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getId().getValue().indexOf("intraallow") == 0) {\r
+ count += 1;\r
+ } else if (f.getMatch() != null &&\r
+ Objects.equals(tunnelId, f.getMatch().getInPort())) {\r
+ assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))),\r
+ f.getInstructions());\r
+ count += 1;\r
+ } else if (f.getMatch() != null &&\r
+ f.getMatch().getEthernetMatch() != null &&\r
+ Objects.equals(FlowUtils.IPv4,\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetType().getType().getValue()) &&\r
+ f.getMatch().getIpMatch() != null &&\r
+ Objects.equals(Short.valueOf((short)6),\r
+ f.getMatch().getIpMatch().getIpProtocol()) &&\r
+ Objects.equals(Integer.valueOf(80),\r
+ ((TcpMatch)f.getMatch().getLayer4Match())\r
+ .getTcpDestinationPort().getValue())) {\r
+ count += 1;\r
+ } else if (f.getMatch() != null &&\r
+ f.getMatch().getEthernetMatch() != null &&\r
+ Objects.equals(FlowUtils.IPv6,\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetType().getType().getValue()) &&\r
+ f.getMatch().getIpMatch() != null &&\r
+ Objects.equals(Short.valueOf((short)6),\r
+ f.getMatch().getIpMatch().getIpProtocol()) &&\r
+ Objects.equals(Integer.valueOf(80),\r
+ ((TcpMatch)f.getMatch().getLayer4Match())\r
+ .getTcpDestinationPort().getValue())) {\r
+ count += 1;\r
+ } \r
+ }\r
+ if (direction == null || direction.equals(Direction.Bidirectional))\r
+ assertEquals(7, count);\r
+ else\r
+ assertEquals(5, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 3).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testConditions() throws Exception {\r
+ Condition cond1 = new ConditionBuilder()\r
+ .setName(new ConditionName("cond1"))\r
+ .build();\r
+ Condition cond2 = new ConditionBuilder()\r
+ .setName(new ConditionName("cond2"))\r
+ .build();\r
+\r
+ Endpoint ep1 = localEP()\r
+ .setCondition(ImmutableList.of(cond1.getName()))\r
+ .build();\r
+ endpointManager.addEndpoint(ep1);\r
+ Endpoint ep2 = localEP()\r
+ .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
+ .setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))\r
+ .setEndpointGroup(eg2)\r
+ .build();\r
+ endpointManager.addEndpoint(ep2); \r
+\r
+ TenantBuilder tb = baseTenant()\r
+ .setContract(ImmutableList.of(new ContractBuilder()\r
+ .setId(cid)\r
+ .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))\r
+ .setClause(ImmutableList.of(new ClauseBuilder()\r
+ .setName(new ClauseName("test"))\r
+ .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))\r
+ .setConsumerMatchers(new ConsumerMatchersBuilder()\r
+ .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()\r
+ .setName(new ConditionMatcherName("m1"))\r
+ .setCondition(ImmutableList.of(cond1, cond2))\r
+ .setMatchType(MatchType.Any)\r
+ .build()))\r
+ .build())\r
+ .setProviderMatchers(new ProviderMatchersBuilder()\r
+ .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()\r
+ .setName(new ConditionMatcherName("m2"))\r
+ .setCondition(ImmutableList.of(cond1, cond2))\r
+ .setMatchType(MatchType.All)\r
+ .build()))\r
+ .build())\r
+ .build()))\r
+ .build()));\r
+ policyResolver.addTenant(tb.build());\r
+\r
+ PolicyInfo policy = policyResolver.getCurrentPolicy();\r
+ List<ConditionName> ep1c = endpointManager.getCondsForEndpoint(ep1);\r
+ ConditionGroup cg1 = \r
+ policy.getEgCondGroup(new EgKey(tb.getId(), \r
+ ep1.getEndpointGroup()),\r
+ ep1c);\r
+ List<ConditionName> ep2c = endpointManager.getCondsForEndpoint(ep2);\r
+ ConditionGroup cg2 = \r
+ policy.getEgCondGroup(new EgKey(tb.getId(), \r
+ ep2.getEndpointGroup()),\r
+ ep2c);\r
+ int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);\r
+ int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);\r
+ int eg1Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),\r
+ ep1.getEndpointGroup());\r
+ int eg2Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),\r
+ ep2.getEndpointGroup());\r
+\r
+ assertNotEquals(cg1Id, cg2Id);\r
+\r
+ MatchBuilder mb = new MatchBuilder();\r
+ FlowUtils.addNxRegMatch(mb, \r
+ RegMatch.of(NxmNxReg0.class, Long.valueOf(eg1Id)),\r
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cg1Id)),\r
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(eg2Id)),\r
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cg2Id)));\r
+ GeneralAugMatchNodesNodeTableFlow m1 =\r
+ mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);\r
+ FlowUtils.addNxRegMatch(mb, \r
+ RegMatch.of(NxmNxReg0.class, Long.valueOf(eg2Id)),\r
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cg2Id)),\r
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(eg1Id)),\r
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));\r
+ GeneralAugMatchNodesNodeTableFlow m2 =\r
+ mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);\r
+ int count = 0;\r
+ FlowMap fm = dosync(null);\r
+ assertEquals(6, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() != null &&\r
+ f.getMatch().getEthernetMatch() != null) {\r
+ count++;\r
+ }\r
+ }\r
+ assertEquals(2, count);\r
+ fm = dosync(flowMap);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 3).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
+ }\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.Ipv6Match;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import static org.junit.Assert.*;
-
-import static org.mockito.Matchers.*;
-
-import static org.mockito.Mockito.*;
-
-public class PortSecurityTest extends FlowTableTest {
- protected static final Logger LOG =
- LoggerFactory.getLogger(PortSecurityTest.class);
-
- @Override
- @Before
- public void setup() throws Exception {
- initCtx();
- table = new PortSecurity(ctx);
- super.setup();
- }
-
- @Test
- public void testDefaultDeny() throws Exception {
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, times(4)).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
- int count = 0;
-
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- Long etherType = null;
- if (f.getMatch() != null) {
- etherType = f.getMatch().getEthernetMatch()
- .getEthernetType().getType().getValue();
- }
- if (f.getMatch() == null ||
- FlowUtils.ARP.equals(etherType) ||
- FlowUtils.IPv4.equals(etherType) ||
- FlowUtils.IPv6.equals(etherType)) {
- count += 1;
- assertEquals(FlowUtils.dropInstructions(),
- f.getInstructions());
- }
- }
- assertEquals(4, count);
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testNonLocalAllow() throws Exception {
- switchManager
- .addSwitch(new NodeId("openflow:1"),
- new NodeConnectorId("openflow:1:1"),
- ImmutableSet.of(new NodeConnectorId("openflow:1:2")),
- null);
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
-
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- Set<String> ncs = ImmutableSet.of("openflow:1:1", "openflow:1:2");
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() != null && f.getMatch().getInPort() != null &&
- ncs.contains(f.getMatch().getInPort().getValue())) {
- assertEquals(f.getInstructions(),
- FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)));
- count += 1;
- }
- }
- assertEquals(2, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testL2() throws Exception {
- List<L3Address> l3 = Collections.emptyList();
- Endpoint ep = localEP()
- .setL3Address(l3)
- .build();
-
- endpointManager.addEndpoint(ep);
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
-
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() != null &&
- f.getMatch().getEthernetMatch() != null &&
- f.getMatch().getEthernetMatch().getEthernetSource() != null &&
- Objects.equals(ep.getMacAddress(),
- f.getMatch().getEthernetMatch()
- .getEthernetSource().getAddress()) &&
- Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),
- f.getMatch().getInPort())) {
- count += 1;
- assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
- f.getInstructions());
- }
- }
- assertEquals(2, count);
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testL3() throws Exception {
- Endpoint ep = localEP()
- .setL3Address(ImmutableList.of(new L3AddressBuilder()
- .setIpAddress(new IpAddress(new Ipv4Address("10.10.10.10")))
- .build(),
- new L3AddressBuilder()
- .setIpAddress(new IpAddress(new Ipv6Address("2001:db8:85a3::8a2e:370:7334")))
- .build()))
- .build();
-
- endpointManager.addEndpoint(ep);
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
-
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() != null &&
- Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),
- f.getMatch().getInPort()) &&
- ((f.getMatch().getLayer3Match() != null &&
- f.getMatch().getLayer3Match() instanceof Ipv4Match &&
- ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source() != null &&
- Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
- ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source().getValue().split("/")[0])) ||
- (f.getMatch().getLayer3Match() != null &&
- f.getMatch().getLayer3Match() instanceof Ipv4Match &&
- ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination() != null &&
- Objects.equals("255.255.255.255",
- ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination().getValue().split("/")[0])) ||
- (f.getMatch().getLayer3Match() != null &&
- f.getMatch().getLayer3Match() instanceof ArpMatch &&
- Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
- ((ArpMatch)f.getMatch().getLayer3Match()).getArpSourceTransportAddress().getValue().split("/")[0])) ||
- (f.getMatch().getLayer3Match() != null &&
- f.getMatch().getLayer3Match() instanceof Ipv6Match &&
- Objects.equals(ep.getL3Address().get(1).getIpAddress().getIpv6Address().getValue(),
- ((Ipv6Match)f.getMatch().getLayer3Match()).getIpv6Source().getValue().split("/")[0])))) {
- count += 1;
- assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
- f.getInstructions());
- }
- }
- assertEquals(4, count);
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Objects;\r
+import java.util.Set;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.ImmutableList;\r
+import com.google.common.collect.ImmutableSet;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+public class PortSecurityTest extends FlowTableTest {\r
+ protected static final Logger LOG =\r
+ LoggerFactory.getLogger(PortSecurityTest.class);\r
+\r
+ @Override\r
+ @Before\r
+ public void setup() throws Exception {\r
+ initCtx();\r
+ table = new PortSecurity(ctx);\r
+ super.setup();\r
+ }\r
+\r
+ @Test\r
+ public void testDefaultDeny() throws Exception {\r
+ FlowMap fm = dosync(null);\r
+ int count = 0;\r
+ Map<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 0).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ Long etherType = null;\r
+ if (f.getMatch() != null) {\r
+ etherType = f.getMatch().getEthernetMatch().getEthernetType().getType().getValue();\r
+ }\r
+ if (f.getMatch() == null || FlowUtils.ARP.equals(etherType) || FlowUtils.IPv4.equals(etherType)\r
+ || FlowUtils.IPv6.equals(etherType)) {\r
+ count += 1;\r
+ assertEquals(FlowUtils.dropInstructions(), f.getInstructions());\r
+ }\r
+ }\r
+ assertEquals(4, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 0).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testNonLocalAllow() throws Exception {\r
+ switchManager\r
+ .addSwitch(new NodeId("openflow:1"),\r
+ new NodeConnectorId("openflow:1:1"),\r
+ ImmutableSet.of(new NodeConnectorId("openflow:1:2")),\r
+ null);\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0 ,fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ Set<String> ncs = ImmutableSet.of("openflow:1:1", "openflow:1:2");\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 0).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() != null && f.getMatch().getInPort() != null &&\r
+ ncs.contains(f.getMatch().getInPort().getValue())) {\r
+ assertEquals(f.getInstructions(),\r
+ FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)));\r
+ count += 1;\r
+ }\r
+ }\r
+ assertEquals(2, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 0).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testL2() throws Exception {\r
+ List<L3Address> l3 = Collections.emptyList();\r
+ Endpoint ep = localEP()\r
+ .setL3Address(l3)\r
+ .build();\r
+\r
+ endpointManager.addEndpoint(ep);\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0 ,fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 0).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() != null &&\r
+ f.getMatch().getEthernetMatch() != null &&\r
+ f.getMatch().getEthernetMatch().getEthernetSource() != null &&\r
+ Objects.equals(ep.getMacAddress(),\r
+ f.getMatch().getEthernetMatch()\r
+ .getEthernetSource().getAddress()) &&\r
+ Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),\r
+ f.getMatch().getInPort())) {\r
+ count += 1;\r
+ assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),\r
+ f.getInstructions());\r
+ }\r
+ }\r
+ assertEquals(2, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 0).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testL3() throws Exception {\r
+ Endpoint ep = localEP()\r
+ .setL3Address(ImmutableList.of(new L3AddressBuilder()\r
+ .setIpAddress(new IpAddress(new Ipv4Address("10.10.10.10")))\r
+ .build(),\r
+ new L3AddressBuilder()\r
+ .setIpAddress(new IpAddress(new Ipv6Address("2001:db8:85a3::8a2e:370:7334")))\r
+ .build()))\r
+ .build();\r
+\r
+ endpointManager.addEndpoint(ep);\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertNotEquals(0 ,fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 0).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() != null &&\r
+ Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),\r
+ f.getMatch().getInPort()) &&\r
+ ((f.getMatch().getLayer3Match() != null &&\r
+ f.getMatch().getLayer3Match() instanceof Ipv4Match &&\r
+ ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source() != null &&\r
+ Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),\r
+ ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source().getValue().split("/")[0])) ||\r
+ (f.getMatch().getLayer3Match() != null &&\r
+ f.getMatch().getLayer3Match() instanceof Ipv4Match &&\r
+ ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination() != null &&\r
+ Objects.equals("255.255.255.255",\r
+ ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination().getValue().split("/")[0])) ||\r
+ (f.getMatch().getLayer3Match() != null &&\r
+ f.getMatch().getLayer3Match() instanceof ArpMatch &&\r
+ Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),\r
+ ((ArpMatch)f.getMatch().getLayer3Match()).getArpSourceTransportAddress().getValue().split("/")[0])) ||\r
+ (f.getMatch().getLayer3Match() != null &&\r
+ f.getMatch().getLayer3Match() instanceof Ipv6Match &&\r
+ Objects.equals(ep.getL3Address().get(1).getIpAddress().getIpv6Address().getValue(),\r
+ ((Ipv6Match)f.getMatch().getLayer3Match()).getIpv6Source().getValue().split("/")[0])))) {\r
+ count += 1;\r
+ assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),\r
+ f.getInstructions());\r
+ }\r
+ }\r
+ assertEquals(4, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 0).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 0).getFlow().size());\r
+ }\r
+}\r
-/*
- * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
-
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
-import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
-import org.opendaylight.groupbasedpolicy.resolver.EgKey;
-import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.junit.Assert.*;
-
-import static org.mockito.Matchers.*;
-
-import static org.mockito.Mockito.*;
-
-public class SourceMapperTest extends FlowTableTest {
- protected static final Logger LOG =
- LoggerFactory.getLogger(SourceMapperTest.class);
- @Before
- public void setup() throws Exception {
- initCtx();
- table = new SourceMapper(ctx);
- super.setup();
- }
-
- @Test
- public void testNoPolicy() throws Exception {
- endpointManager.addEndpoint(localEP().build());
- ReadWriteTransaction t = dosync(null);
- verify(t, times(1)).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
- @Test
- public void testMap() throws Exception {
- Endpoint ep = localEP().build();
- endpointManager.addEndpoint(ep);
- policyResolver.addTenant(baseTenant().build());
-
- ReadWriteTransaction t = dosync(null);
- ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
- verify(t, times(2)).put(eq(LogicalDatastoreType.CONFIGURATION),
- Matchers.<InstanceIdentifier<Flow>>any(),
- ac.capture(), anyBoolean());
-
- int count = 0;
- HashMap<String, FlowCtx> flowMap = new HashMap<>();
- for (Flow f : ac.getAllValues()) {
- flowMap.put(f.getId().getValue(), new FlowCtx(f));
- if (f.getMatch() == null) {
- assertEquals(FlowUtils.dropInstructions(),
- f.getInstructions());
- count += 1;
- } else if (Objects.equals(ep.getMacAddress(),
- f.getMatch().getEthernetMatch()
- .getEthernetSource().getAddress())) {
- PolicyInfo pi = policyResolver.getCurrentPolicy();
- List<ConditionName> cset = endpointManager.getCondsForEndpoint(ep);
- ConditionGroup cg = pi.getEgCondGroup(new EgKey(tid, eg), cset);
-
- Instruction ins = f.getInstructions().getInstruction().get(0);
- assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
- List<Action> actions = ((ApplyActionsCase)ins.getInstruction()).getApplyActions().getAction();
- int v = policyManager.getContextOrdinal(tid, eg);
- assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg0.class,
- BigInteger.valueOf(v)),
- actions.get(0).getAction());
- v = policyManager.getCondGroupOrdinal(cg);
- assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg1.class,
- BigInteger.valueOf(v)),
- actions.get(1).getAction());
- v = policyManager.getContextOrdinal(tid, bd);
- assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg4.class,
- BigInteger.valueOf(v)),
- actions.get(2).getAction());
- v = policyManager.getContextOrdinal(tid, fd);
- assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg5.class,
- BigInteger.valueOf(v)),
- actions.get(3).getAction());
- v = policyManager.getContextOrdinal(tid, l3c);
- assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg6.class,
- BigInteger.valueOf(v)),
- actions.get(4).getAction());
- count += 1;
- }
- }
- assertEquals(2, count);
-
- t = dosync(flowMap);
- verify(t, never()).put(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<Flow>>any(),
- any(Flow.class), anyBoolean());
- }
-
-}
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ * \r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
+\r
+import java.math.BigInteger;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Objects;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;\r
+import org.opendaylight.groupbasedpolicy.resolver.EgKey;\r
+import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+public class SourceMapperTest extends FlowTableTest {\r
+\r
+ protected static final Logger LOG = LoggerFactory.getLogger(SourceMapperTest.class);\r
+\r
+ @Before\r
+ public void setup() throws Exception {\r
+ initCtx();\r
+ table = new SourceMapper(ctx);\r
+ super.setup();\r
+ }\r
+\r
+ @Test\r
+ public void testNoPolicy() throws Exception {\r
+ endpointManager.addEndpoint(localEP().build());\r
+ FlowMap fm = dosync(null);\r
+ assertEquals(1, fm.getTableForNode(nodeId, (short) 1).getFlow().size());\r
+ }\r
+\r
+ @Test\r
+ public void testMap() throws Exception {\r
+ Endpoint ep = localEP().build();\r
+ endpointManager.addEndpoint(ep);\r
+ policyResolver.addTenant(baseTenant().build());\r
+\r
+ FlowMap fm = dosync(null);\r
+ assertEquals(2, fm.getTableForNode(nodeId, (short) 1).getFlow().size());\r
+\r
+ int count = 0;\r
+ HashMap<String, Flow> flowMap = new HashMap<>();\r
+ for (Flow f : fm.getTableForNode(nodeId, (short) 1).getFlow()) {\r
+ flowMap.put(f.getId().getValue(), f);\r
+ if (f.getMatch() == null) {\r
+ assertEquals(FlowUtils.dropInstructions(), f.getInstructions());\r
+ count += 1;\r
+ } else if (Objects.equals(ep.getMacAddress(), f.getMatch()\r
+ .getEthernetMatch()\r
+ .getEthernetSource()\r
+ .getAddress())) {\r
+ PolicyInfo pi = policyResolver.getCurrentPolicy();\r
+ List<ConditionName> cset = endpointManager.getCondsForEndpoint(ep);\r
+ ConditionGroup cg = pi.getEgCondGroup(new EgKey(tid, eg), cset);\r
+\r
+ Instruction ins = f.getInstructions().getInstruction().get(0);\r
+ assertTrue(ins.getInstruction() instanceof ApplyActionsCase);\r
+ List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();\r
+ NetworkDomainId networkContainement = policyResolver.getTenant(tid)\r
+ .getEndpointGroup(eg)\r
+ .getNetworkDomain();\r
+ int v = OrdinalFactory.getContextOrdinal(ep, networkContainement);\r
+ assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(v)), actions.get(0)\r
+ .getAction());\r
+ v = OrdinalFactory.getCondGroupOrdinal(cg);\r
+ assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(v)), actions.get(1)\r
+ .getAction());\r
+ v = OrdinalFactory.getContextOrdinal(tid, bd);\r
+ assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(v)), actions.get(2)\r
+ .getAction());\r
+ v = OrdinalFactory.getContextOrdinal(tid, fd);\r
+ assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(v)), actions.get(3)\r
+ .getAction());\r
+ v = OrdinalFactory.getContextOrdinal(tid, l3c);\r
+ assertEquals(FlowUtils.nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(v)), actions.get(4)\r
+ .getAction());\r
+ count += 1;\r
+ }\r
+ }\r
+ assertEquals(2, count);\r
+ int numberOfFlows = fm.getTableForNode(nodeId, (short) 1).getFlow().size();\r
+ fm = dosync(flowMap);\r
+ assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 1).getFlow().size());\r
+ }\r
+\r
+}\r