@Override
public int compare(Rule o1, Rule o2) {
return ComparisonChain.start()
- .compare(o1.getOrder(), o2.getOrder(),
+ .compare(o1.getOrder(), o2.getOrder(),
Ordering.natural().nullsLast())
+ .compare(o1.getName().getValue(), o2.getName().getValue(),
+ Ordering.natural().nullsLast())
.result();
}
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.groupbasedpolicy.dto.RuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
public class RuleGroupTest {
subjectValue = "value";
when(subject.getValue()).thenReturn(subjectValue);
+ ContractId contractId = new ContractId("contract");
+ when(contract.getKey()).thenReturn(new ContractKey(contractId));
ruleGroup = new RuleGroup(rules, order, contractTenant, contract, subject);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayL3Context;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;
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.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.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.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
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.Layer3Match;
+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.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;
}
public static void createChainTunnelFlows(SfcNshHeader sfcNshHeader, NetworkElements netElements, OfWriter ofWriter,
- OfContext ctx) {
+ OfContext ctx, Direction direction) {
NodeId localNodeId = netElements.getLocalNodeId();
- NodeId destNodeId = netElements.getDstEp().getAugmentation(OfOverlayContext.class).getNodeId();
EndpointFwdCtxOrdinals epOrdinals = netElements.getSrcEpOrdinals();
NodeConnectorId localNodeTunPort = ctx.getSwitchManager().getTunnelPort(localNodeId, TunnelTypeVxlanGpe.class);
- NodeConnectorId destNodeTunPort = ctx.getSwitchManager().getTunnelPort(destNodeId, TunnelTypeVxlanGpe.class);
Ipv4Address tunDestAddress = ctx.getSwitchManager()
.getTunnelIP(netElements.getDstNodeId(), TunnelTypeVxlanGpe.class)
.getIpv4Address();
- if (localNodeTunPort == null || destNodeTunPort == null) {
- LOG.error("createChainTunnelFlows: No valid VXLAN GPE tunnel for Node {} or Node {}", localNodeId,
- destNodeId);
+ if (localNodeTunPort == null) {
+ LOG.error("createChainTunnelFlows: No valid VXLAN GPE tunnel for Node {} ", localNodeId);
return;
}
- ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), allowFromChainPort(
- sfcNshHeader, localNodeTunPort, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), ctx));
-
- ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(),
- allowFromChainTunnel(localNodeTunPort, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()));
+ if (direction.equals(Direction.In)) {
+ ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), allowFromChainPort(
+ sfcNshHeader, localNodeTunPort, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), ctx));
- ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER(),
- createExternalFlow(sfcNshHeader, localNodeTunPort, netElements,
- ctx.getPolicyManager(), ctx.getSwitchManager(), tunDestAddress));
+ for (Flow flow : createChainTunnelFlow(sfcNshHeader, localNodeTunPort, netElements,
+ ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), ctx)) {
+ ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), flow);
+ }
- ofWriter.writeFlow(destNodeId, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), createChainTunnelFlow(
- sfcNshHeader, destNodeTunPort, epOrdinals, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), ctx));
+ ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(),
+ allowFromChainTunnel(localNodeTunPort, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()));
- ofWriter.writeFlow(destNodeId, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), createChainBroadcastFlow(
- sfcNshHeader, destNodeTunPort, epOrdinals, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), ctx));
+ ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(),
+ createChainBroadcastFlow(sfcNshHeader, localNodeTunPort, epOrdinals,
+ ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), ctx));
+ } else {
+ ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER(),
+ createExternalFlow(sfcNshHeader, localNodeTunPort, netElements, ctx.getPolicyManager(),
+ ctx.getSwitchManager(), tunDestAddress));
+ }
}
private static Flow createChainBroadcastFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action outputAction;
Integer priority = 1000;
- int matchTunnelId = sfcNshHeader.getNshMetaC2().intValue();
+ int matchTunnelId = netElements.getSrcEpOrdinals().getTunnelId();
+ long setTunnelId = netElements.getDstEpOrdinals().getTunnelId();
Long l3c = (long) netElements.getSrcEpOrdinals().getL3Id();
loadC1 = nxLoadNshc1RegAction(sfcNshHeader.getNshMetaC1());
}
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadC2 =
- nxLoadNshc2RegAction(sfcNshHeader.getNshMetaC2());
+ nxLoadNshc2RegAction(setTunnelId);
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
- nxLoadTunIdAction(BigInteger.valueOf(sfcNshHeader.getNshMetaC2()), false);
+ nxLoadTunIdAction(BigInteger.valueOf(setTunnelId), false);
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
nxLoadTunIPv4Action(sfcNshHeader.getNshTunIpDst().getValue(), false);
return flowb.build();
}
- private static Flow createChainTunnelFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
- EndpointFwdCtxOrdinals epFwdCtxOrds, short tableId, OfContext ctx) {
-
- int egId = epFwdCtxOrds.getEpgId();
- int bdId = epFwdCtxOrds.getBdId();
- int fdId = epFwdCtxOrds.getFdId();
- int l3Id = epFwdCtxOrds.getL3Id();
- int tunnelId = epFwdCtxOrds.getTunnelId();
+ private static List<Flow> createChainTunnelFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
+ NetworkElements netElements, short tableId, OfContext ctx) {
- MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
- addNxTunIdMatch(mb, tunnelId);
- addNxNspMatch(mb, sfcNshHeader.getNshNspFromChain());
- addNxNsiMatch(mb, sfcNshHeader.getNshNsiFromChain());
+ int egId = netElements.getDstEpOrdinals().getEpgId();
+ int bdId = netElements.getDstEpOrdinals().getBdId();
+ int fdId = netElements.getDstEpOrdinals().getFdId();
+ int l3Id = netElements.getDstEpOrdinals().getL3Id();
+ int tunnelId = netElements.getSrcEpOrdinals().getTunnelId();
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action segReg =
nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action vrfReg =
nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
- Match match = mb.build();
- FlowId flowId = FlowIdUtils.newFlowId(tableId, "chaintunnel", match);
- FlowBuilder flowb =
- base(tableId).setId(flowId).setPriority(150).setMatch(match).setInstructions(
- instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
- gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
- return flowb.build();
+ List<Flow> flows = new ArrayList<>();
+ for (L3Address address : netElements.getDstEp().getL3Address()) {
+ Layer3Match l3Match = null;
+ MatchBuilder mb = null;
+ if (address.getIpAddress() != null) {
+ if (address.getIpAddress().getIpv4Address() != null) {
+ l3Match = new Ipv4MatchBuilder()
+ .setIpv4Source(new Ipv4Prefix(address.getIpAddress().getIpv4Address().getValue() + "/32"))
+ .build();
+ mb = new MatchBuilder().setInPort(tunPort)
+ .setLayer3Match(l3Match)
+ .setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));
+ } else if (address.getIpAddress().getIpv6Address() != null) {
+ l3Match = new Ipv6MatchBuilder()
+ .setIpv6Source(new Ipv6Prefix(address.getIpAddress().getIpv6Address().getValue() + "/128"))
+ .build();
+ mb = new MatchBuilder().setInPort(tunPort)
+ .setLayer3Match(l3Match)
+ .setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6));
+ }
+ }
+
+ addNxTunIdMatch(mb, tunnelId);
+ addNxNspMatch(mb, sfcNshHeader.getNshNspFromChain());
+ addNxNsiMatch(mb, sfcNshHeader.getNshNsiFromChain());
+
+ Match match = mb.build();
+ FlowId flowId = FlowIdUtils.newFlowId(tableId, "chaintunnel", match);
+ FlowBuilder flowb = base(tableId).setId(flowId).setPriority(150).setMatch(match).setInstructions(
+ instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
+ gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
+ flows.add(flowb.build());
+ }
+ return flows;
}
private static Flow allowFromChainPort(SfcNshHeader sfcNshHeader, NodeConnectorId port, short tableId,
--- /dev/null
+/*\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
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer;\r
+\r
+import org.opendaylight.groupbasedpolicy.dto.EgKey;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;\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.NodeId;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NetworkElements {\r
+\r
+ private static final Logger LOG = LoggerFactory.getLogger(NetworkElements.class);\r
+ private final Endpoint srcEp;\r
+ private final Endpoint dstEp;\r
+ private final EgKey srcEpg;\r
+ private final EgKey dstEpg;\r
+ private NodeId srcNodeId;\r
+ private NodeId dstNodeId;\r
+ private final NodeId localNodeId;\r
+ private EndpointFwdCtxOrdinals srcEpOrdinals;\r
+ private EndpointFwdCtxOrdinals dstEpOrdinals;\r
+\r
+ public NetworkElements(Endpoint srcEp, Endpoint dstEp, EgKey srcEpg, EgKey dstEpg, NodeId nodeId, OfContext ctx) throws Exception {\r
+ this.srcEp = srcEp;\r
+ this.dstEp = dstEp;\r
+ this.srcEpg = srcEpg;\r
+ this.dstEpg = dstEpg;\r
+ this.localNodeId = nodeId;\r
+ this.srcEpOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, srcEp);\r
+ if (this.srcEpOrdinals == null) {\r
+ LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", srcEp);\r
+ return;\r
+ }\r
+ this.dstEpOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, dstEp);\r
+ if (this.dstEpOrdinals == null) {\r
+ LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", dstEp);\r
+ return;\r
+ }\r
+ if (dstEp.getAugmentation(OfOverlayContext.class) != null) {\r
+ this.dstNodeId = dstEp.getAugmentation(OfOverlayContext.class).getNodeId();\r
+ }\r
+ if (srcEp.getAugmentation(OfOverlayContext.class) != null) {\r
+ this.srcNodeId = srcEp.getAugmentation(OfOverlayContext.class).getNodeId();\r
+ }\r
+ }\r
+\r
+\r
+ public Endpoint getSrcEp() {\r
+ return srcEp;\r
+ }\r
+\r
+\r
+ public Endpoint getDstEp() {\r
+ return dstEp;\r
+ }\r
+\r
+ public EgKey getSrcEpg() {\r
+ return srcEpg;\r
+ }\r
+\r
+ public EgKey getDstEpg() {\r
+ return dstEpg;\r
+ }\r
+\r
+ public NodeId getSrcNodeId() {\r
+ return srcNodeId;\r
+ }\r
+\r
+\r
+ public NodeId getDstNodeId() {\r
+ return dstNodeId;\r
+ }\r
+\r
+\r
+ public NodeId getLocalNodeId() {\r
+ return localNodeId;\r
+ }\r
+\r
+\r
+ public EndpointFwdCtxOrdinals getSrcEpOrdinals() {\r
+ return srcEpOrdinals;\r
+ }\r
+\r
+\r
+ public EndpointFwdCtxOrdinals getDstEpOrdinals() {\r
+ return dstEpOrdinals;\r
+ }\r
+\r
+}
\ No newline at end of file
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import javax.annotation.concurrent.Immutable;
-
import org.opendaylight.groupbasedpolicy.api.sf.AllowActionDefinition;
-import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
-import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
-import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
import org.opendaylight.groupbasedpolicy.dto.EgKey;
import org.opendaylight.groupbasedpolicy.dto.EndpointConstraint;
import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
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.ChainAction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ParamDerivator;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
import org.opendaylight.groupbasedpolicy.util.TenantUtils;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
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.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
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.ActionRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ArrayListMultimap;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ComparisonChain;
-import com.google.common.collect.ListMultimap;
import com.google.common.collect.Ordering;
import com.google.common.collect.Table.Cell;
/**
* <h1>Manage the table that enforces policy on the traffic. Traffic is denied
* unless specifically allowed by policy (table=4)</h1>
- *
- * In policy enforcer, according to current {@link Policy} specific traffic is sent to SFC (nsp and nsi is set), or from SFC
+ * In policy enforcer, according to current {@link Policy} specific traffic is sent to SFC (nsp and
+ * nsi is set), or from SFC
* to some {@link Endpoint} or to another classifier.
* <p>
* <i>Tunnel/overlay flows</i><br>
* Priority = 65000 (if more flows, decrements)<br>
* Matches:<br>
- * - ethertype (tcp, tcp6, ipv6, icmp or missing)<br>
- * - Reg0 {@link NxmNxReg0}<br>
- * - Reg1 {@link NxmNxReg1}<br>
- * - Reg2 {@link NxmNxReg2}<br>
- * - Reg3 {@link NxmNxReg3}<br>
- * - L3 for src_ip_prefix (if exists)<br>
- * - L3 for dst_ip_prefix (if exists)<br>
+ * - ethertype (tcp, tcp6, ipv6, icmp or missing)<br>
+ * - Reg0 {@link NxmNxReg0}<br>
+ * - Reg1 {@link NxmNxReg1}<br>
+ * - Reg2 {@link NxmNxReg2}<br>
+ * - Reg3 {@link NxmNxReg3}<br>
+ * - L3 for src_ip_prefix (if exists)<br>
+ * - L3 for dst_ip_prefix (if exists)<br>
* Actions:<br>
- * - set nsi (only chain action)<br>
- * - set nsp (only chain action)<br>
- * - {@link GoToTable} EXTERNAL MAPPER table<br>
- *<p>
+ * - set nsi (only chain action)<br>
+ * - set nsp (only chain action)<br>
+ * - {@link GoToTable} EXTERNAL MAPPER table<br>
+ * <p>
* <i>Allow from tunnel flow</i><br>
* Priority = 65000<br>
* Matches:<br>
- * - Reg1 (set to 0xffffff) {@link NxmNxReg1}<br>
- * - in_port (should be tunnel port) {@link NodeConnectorId}<br>
+ * - Reg1 (set to 0xffffff) {@link NxmNxReg1}<br>
+ * - in_port (should be tunnel port) {@link NodeConnectorId}<br>
* Actions:<br>
- * - output:port (Reg7) {@link NxmNxReg7}<br>
+ * - output:port (Reg7) {@link NxmNxReg7}<br>
* <p>
* Traffic is sent from one {@link EndpointGroup} to the same EPG
* <p>
* <i>Allow from same EPG flow</i><br>
* Priority = 65000<br>
* Matches:<br>
- * - Reg0 {@link NxmNxReg0}<br>
- * - Reg2 {@link NxmNxReg2}<br>
+ * - Reg0 {@link NxmNxReg0}<br>
+ * - Reg2 {@link NxmNxReg2}<br>
* Actions:<br>
- * - output:port (Reg7) {@link NxmNxReg7}
+ * - output:port (Reg7) {@link NxmNxReg7}
* <p>
* <i>Arp flow</i><br>
* Priority = 20000<br>
* Matches:<br>
- * - ethernet match (arp)<br>
- * - Reg5 {@link NxmNxReg5}<br>
+ * - ethernet match (arp)<br>
+ * - Reg5 {@link NxmNxReg5}<br>
* Actions:<br>
- * - output:port (Reg7) {@link NxmNxReg7}
- *
+ * - output:port (Reg7) {@link NxmNxReg7}
*/
public class PolicyEnforcer extends FlowTable {
private static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
public static short TABLE_ID;
- private static boolean isReversedPolicy;
private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoEgressNatInstruction;
private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoExternalInstruction;
- private HashSet<PolicyPair> visitedPairs = new HashSet<>();
- private HashSet<PolicyPair> visitedReversePairs = new HashSet<>();
- private List<Rule> reversedActiveRules = new ArrayList<>();
- private ListMultimap<EgKey, EgKey> resolvedEpgPairs = ArrayListMultimap.create();
- private boolean directPathFlowsCreated = false;
- private boolean reversePathFlowsCreated = false;
public PolicyEnforcer(OfContext ctx, short tableId) {
super(ctx);
TABLE_ID = tableId;
- isReversedPolicy = false;
gotoEgressNatInstruction = gotoTableIns(ctx.getPolicyManager().getTABLEID_EGRESS_NAT());
gotoExternalInstruction = gotoTableIns(ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER());
}
- private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction getGotoEgressNatInstruction() {
- return gotoEgressNatInstruction;
- }
-
- private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction getGotoExternalInstruction() {
- return gotoExternalInstruction;
- }
-
@Override
public short getTableId() {
return TABLE_ID;
@Override
public void sync(Endpoint endpoint, OfWriter ofWriter) throws Exception {
+ Preconditions.checkNotNull(endpoint);
+ Preconditions.checkNotNull(ofWriter);
- // TODO: only temporary workaround, use src & dst endpoint in implementation
NodeId nodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(1, null, TABLE_ID));
if (tunPort != null) {
ofWriter.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
}
+ EndpointFwdCtxOrdinals srcEpFwdCxtOrdinals =
+ OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
+ if (srcEpFwdCxtOrdinals == null) {
+ LOG.debug("Method getEndpointFwdCtxOrdinals returned null for EP {}", endpoint);
+ return;
+ }
+ for (EgKey sourceEpg : ctx.getEndpointManager().getEgKeysForEndpoint(endpoint)) {
+ for (EgKey destEpg : ctx.getCurrentPolicy().getPeers(sourceEpg)) {
+ Collection<Endpoint> destinationEndpoints = getEndpointsForGroup(destEpg);
+ for (Endpoint destinationEndpoint : destinationEndpoints) {
+ EndpointFwdCtxOrdinals dstEpFwdCxtOrdinals =
+ OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, destinationEndpoint);
+ if (dstEpFwdCxtOrdinals == null) {
+ LOG.debug("Method getEndpointFwdCtxOrdinals returned null for EP {}", destinationEndpoint);
+ continue;
+ }
- visitedPairs = new HashSet<>();
- reversedActiveRules = new ArrayList<>();
- visitedReversePairs = new HashSet<>();
- resolvedEpgPairs = ArrayListMultimap.create();
-
- // Used for ARP flows
- Set<Integer> fdIds = new HashSet<>();
-
- for (Endpoint sourceEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
- for (EgKey sourceEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(sourceEp)) {
- Set<EgKey> peers = ctx.getCurrentPolicy().getPeers(sourceEpgKey);
- for (EgKey destinationEpgKey : peers) {
-
- Set<Endpoint> destinationEndpoints = new HashSet<>();
- destinationEndpoints.addAll(ctx.getEndpointManager().getEndpointsForGroup(destinationEpgKey));
- destinationEndpoints.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(destinationEpgKey));
- for (Endpoint destinationEp : destinationEndpoints) {
-
- EndpointFwdCtxOrdinals srcEpFwdCxtOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, sourceEp);
- if (srcEpFwdCxtOrdinals == null) {
- LOG.debug("Method getEndpointFwdCtxOrdinals returned null for EP {}", sourceEp);
- continue;
- }
-
- EndpointFwdCtxOrdinals dstEpFwdCxtOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, destinationEp);
- if (dstEpFwdCxtOrdinals == null) {
- LOG.debug("Method getEndpointFwdCtxOrdinals returned null for EP {}", destinationEp);
- continue;
- }
-
- fdIds.add(srcEpFwdCxtOrdinals.getFdId());
- NetworkElements netElements = new NetworkElements(sourceEp, destinationEp, sourceEpgKey,
- destinationEpgKey, nodeId, ctx);
+ NetworkElements netElements =
+ new NetworkElements(endpoint, destinationEndpoint, sourceEpg, destEpg, nodeId, ctx);
- // Get policy in both directions
- Policy sourceEpgPolicy = ctx.getCurrentPolicy().getPolicy(destinationEpgKey, sourceEpgKey);
- Policy destinationEpgPolicy = ctx.getCurrentPolicy().getPolicy(sourceEpgKey, destinationEpgKey);
- reversedActiveRules = getRules(getActiveRulesBetweenEps(destinationEpgPolicy, sourceEp, destinationEp));
+ // Get policy in both directions
+ Policy sourceEpgPolicy = ctx.getCurrentPolicy().getPolicy(destEpg, sourceEpg);
+ Policy destinationEpgPolicy = ctx.getCurrentPolicy().getPolicy(sourceEpg, destEpg);
- // Resolve flows in both directions if possible according to policy. Get back status of resolution
- PathStatus status = resolveSourceEpgPolicy(ofWriter, netElements, sourceEpgPolicy);
+ // Resolve flows in both directions if possible according to policy. Get back
+ // status
+ // of resolution
+ resolveSourceEpgPolicy(ofWriter, netElements, sourceEpgPolicy, destinationEpgPolicy);
- // When source Epg policy creates no flows, destination Epg policy has to be resolved
- if (status.equals(PathStatus.none)) {
- resolveDestinationEpgPolicy(ofWriter, netElements, destinationEpgPolicy, false);
- }
- // When source Epg policy creates flows only in one direction, the other direction has to be
- // created here. Is essential to revert directions to prevent flow overriding and incorrect nsp
- // evaluation
- else if (status.equals(PathStatus.partial)) {
- resolveDestinationEpgPolicy(ofWriter, netElements, destinationEpgPolicy, true);
- }
- }
+ ofWriter.writeFlow(nodeId, TABLE_ID, createArpFlow(srcEpFwdCxtOrdinals.getFdId()));
}
}
- }
-
- // Allow same EPG
- allowSameEpg(nodeId, ofWriter);
-
- // Write ARP flows per flood domain
- for (Integer fdId : fdIds) {
- ofWriter.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
+ // Allow same EPG
+ allowSameEpg(sourceEpg, endpoint, nodeId, ofWriter);
}
}
- private PathStatus resolveSourceEpgPolicy(OfWriter ofWriter, NetworkElements netElements, Policy directPolicy) {
- isReversedPolicy = false;
- directPathFlowsCreated = false;
- reversePathFlowsCreated = false;
+ private Set<Endpoint> getEndpointsForGroup(EgKey epg) {
+ Set<Endpoint> destinationEndpoints = new HashSet<>();
+ destinationEndpoints.addAll(ctx.getEndpointManager().getEndpointsForGroup(epg));
+ destinationEndpoints.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(epg));
+ return destinationEndpoints;
+ }
- for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : getActiveRulesBetweenEps(
- directPolicy, netElements.getDstEp(), netElements.getSrcEp())) {
- Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
- .getL3EpPrefixes());
- Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
- .getL3EpPrefixes());
+ private void resolveSourceEpgPolicy(OfWriter ofWriter, NetworkElements netElements, Policy directPolicy,
+ Policy reversedPolicy) {
- int priority = 65000;
- for (RuleGroup rg : activeRulesByConstraints.getValue()) {
+ List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> providedRules =
+ getActiveRulesBetweenEps(directPolicy, netElements.getDstEp(), netElements.getSrcEp());
+ List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> consumedRules =
+ getActiveRulesBetweenEps(reversedPolicy, netElements.getSrcEp(), netElements.getDstEp());
+ List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> activeRules;
+ if (!providedRules.isEmpty()) {
+ activeRules = providedRules;
+ } else {
+ activeRules = consumedRules;
+ }
+ int priority = 65000;
+ for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : activeRules) {
+ Set<IpPrefix> sIpPrefixes;
+ Set<IpPrefix> dIpPrefixes;
+ if (providedRules.contains(activeRulesByConstraints)) {
+ sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey().getL3EpPrefixes());
+ dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey().getL3EpPrefixes());
+ } else {
+ sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey().getL3EpPrefixes());
+ dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey().getL3EpPrefixes());
+ }
+ for (RuleGroup rg : Ordering.from(new RuleGroupComparator())
+ .immutableSortedCopy(activeRulesByConstraints.getValue())) {
TenantId tenantId = rg.getContractTenant().getId();
IndexedTenant tenant = ctx.getTenant(tenantId);
- for (Rule rule : rg.getRules()) {
-
- // Find all rules in the same traffic direction
- List<Rule> sameDirectionRules = findRulesInSameDirection(rule, reversedActiveRules);
- if (sameDirectionRules.isEmpty()) {
- sameDirectionRules.add(rule);
+ for (Direction direction : new Direction[] {Direction.In, Direction.Out}) {
+ List<Rule> sameDirectionRules;
+ if (providedRules.contains(activeRulesByConstraints)) {
+ sameDirectionRules = uniteRulesByDirection(direction, rg.getRules(), getRules(consumedRules));
+ } else {
+ sameDirectionRules = uniteRulesByDirection(direction, null, rg.getRules());
}
- sameDirectionRules = Ordering.from(TenantUtils.RULE_COMPARATOR)
- .immutableSortedCopy(sameDirectionRules);
-
- // Create flows for every pair of rules
- for (Rule oppositeRule : sameDirectionRules) {
-
- // Evaluate which rule has more specific matches
- Rule ruleWithMatches = findRuleWithSpecificMatches(rule, oppositeRule, tenant);
- Rule ruleWithActions = mergeRuleActions(rule, oppositeRule, tenant);
- if (ruleWithMatches == null) {
- LOG.trace("No matches found for pair of rules {}, {}", rule, oppositeRule);
- continue;
- }
- if (ruleWithActions == null) {
- LOG.trace("No actions found for pair of rules {}, {}", rule, oppositeRule);
- continue;
- }
- PolicyPair policyPair = null;
- if (rule.equals(ruleWithMatches)) {
- policyPair = new PolicyPair(netElements.getDstEpOrdinals().getEpgId(),
- netElements.getSrcEpOrdinals().getEpgId(), netElements.getDstEpOrdinals().getCgId(),
- netElements.getSrcEpOrdinals().getCgId(), dIpPrefixes, sIpPrefixes,
- netElements.getDstNodeId(), netElements.getSrcNodeId());
- } else {
- policyPair = new PolicyPair(netElements.getSrcEpOrdinals().getEpgId(),
- netElements.getDstEpOrdinals().getEpgId(), netElements.getSrcEpOrdinals().getCgId(),
- netElements.getDstEpOrdinals().getCgId(), sIpPrefixes, dIpPrefixes,
- netElements.getSrcNodeId(), netElements.getDstNodeId());
- }
- LOG.trace("PolicyEnforcer: Visiting PolicyPair {} endpoints {} {}", policyPair,
- netElements.getSrcEp().getKey(), netElements.getDstEp().getKey());
-
- // Preserve original rule direction
- Set<Direction> directions = getRuleDirections(rule);
-
- for(Direction direction : directions) {
-
- // Create list of matches/actions. Also creates chain flows when specific action requires it
- List<MatchBuilder> inMatches = createMatches(Direction.In, policyPair, tenant,
- ruleWithMatches);
- List<MatchBuilder> outMatches = createMatches(Direction.Out, policyPair, tenant,
- ruleWithMatches);
-
- List<ActionBuilder> actions = createActions(ofWriter, netElements, direction,
- policyPair, tenant, ruleWithActions, false);
-
- // Compose flows
- createFlows(inMatches, actions, netElements, ofWriter, priority);
- createFlows(outMatches, actions, netElements, ofWriter, priority);
-
- priority -= 1;
-
- // Keep info about what direction has flows already created
- if (direction.equals(Direction.In)) {
- directPathFlowsCreated = true;
- }
- if (direction.equals(Direction.Out)) {
- reversePathFlowsCreated = true;
- }
-
- // Fully resolved Ep groups are saved to prevent duplicates
- if (directPathFlowsCreated && reversePathFlowsCreated) {
- LOG.trace("Epg pair added: {}, {} ", netElements.getSrcEpg(), netElements.getDstEpg());
- resolvedEpgPairs.put(netElements.getSrcEpg(), netElements.getDstEpg());
- }
- }
+ for (Rule rule : Ordering.from(TenantUtils.RULE_COMPARATOR)
+ .immutableSortedCopy(sameDirectionRules)) {
+ createFlowsForRule(rule, getRules(providedRules), getRules(consumedRules), direction,
+ netElements, ofWriter, tenant, sIpPrefixes, dIpPrefixes, priority);
+ priority--;
}
}
}
-
- }
- // Returns appropriate result of resolving
- if (directPathFlowsCreated && reversePathFlowsCreated) {
- return PathStatus.both;
- } else if ((!directPathFlowsCreated && reversePathFlowsCreated) || (directPathFlowsCreated && !reversePathFlowsCreated)) {
- return PathStatus.partial;
- } else {
- return PathStatus.none;
- }
- }
-
- private Set<Direction> getRuleDirections(Rule ruleWithMatches) {
- Set<Direction> directions = new HashSet<>();
- for (ClassifierRef classifierRef : ruleWithMatches.getClassifierRef()) {
- if (!directions.contains(classifierRef.getDirection()) && classifierRef.getDirection() == Direction.In) {
- directions.add(classifierRef.getDirection());
- }
- if (!directions.contains(classifierRef.getDirection()) && classifierRef.getDirection() == Direction.Out) {
- directions.add(classifierRef.getDirection());
- }
- }
- if (directions.isEmpty()) {
- directions.add(Direction.Bidirectional);
}
- return directions;
}
- private Rule mergeRuleActions(Rule rule, Rule oppositeRule, IndexedTenant tenant) {
- if (oppositeRule.equals(rule)) {
- return rule;
- }
-
- Action ruleAction = null;
- Action oppositeRuleAction = null;
- // For now, only allow action and chain action is supported
- for (ActionRef actionRef : rule.getActionRef()) {
- ActionInstance actionInstance = tenant.getAction(actionRef.getName());
- if (actionRef.getOrder() == 0 && (actionInstance.getActionDefinitionId().equals(new AllowAction().getId()))) {
- ruleAction = new AllowAction();
- }
- if (actionRef.getOrder() == 0 && (actionInstance.getActionDefinitionId().equals(new ChainAction().getId()))) {
- ruleAction = new ChainAction();
- }
- }
- for (ActionRef actionRef : oppositeRule.getActionRef()) {
- ActionInstance actionInstance = tenant.getAction(actionRef.getName());
- if (actionRef.getOrder() == 0 && (actionInstance.getActionDefinitionId().equals(new AllowAction().getId()))) {
- oppositeRuleAction = new AllowAction();
- }
- if (actionRef.getOrder() == 0 && (actionInstance.getActionDefinitionId().equals(new ChainAction().getId()))) {
- oppositeRuleAction = new ChainAction();
- }
- }
-
- if (ruleAction == null && oppositeRuleAction == null) {
- return null;
- } else if (ruleAction != null && ruleAction.getClass().equals(AllowAction.class)) {
- return oppositeRule;
- } else if (oppositeRuleAction != null && oppositeRuleAction.getClass().equals(AllowAction.class)) {
- return rule;
- } else {
- // TODO both rules have chain action - add support for more different chain actions. This works for now
- return rule;
- }
+ private List<Rule> uniteRulesByDirection (Direction direction, List<Rule> directRules, List<Rule> reversedRules) {
+ List<Rule> sameDirectionRules = findRulesInDirection(direction, directRules);
+ sameDirectionRules
+ .addAll(findRulesInDirection(reverse(direction), reversedRules));
+ return sameDirectionRules;
}
- private Rule findRuleWithSpecificMatches(Rule rule, Rule oppositeRule, IndexedTenant tenant) {
- if (oppositeRule.equals(rule)) {
- return rule;
- }
-
- // TODO check all classifierRefs
- ClassifierRef ruleClassifierRef = rule.getClassifierRef().get(0);
- ClassifierRef oppositeRuleClassifierRef = oppositeRule.getClassifierRef().get(0);
-
- ClassifierInstance ruleClassifierInstance = tenant.getClassifier(ruleClassifierRef.getInstanceName());
- ClassifierInstance oppositeRuleClassifierInstance = tenant.getClassifier(oppositeRuleClassifierRef.getInstanceName());
-
- if (ruleClassifierInstance == null) {
- LOG.trace("Classifier instance not found, ClassifierRef name: {} ", ruleClassifierRef.getInstanceName());
- return null;
- }
- if (oppositeRuleClassifierInstance == null) {
- LOG.trace("Opposite classifier instance not found, ClassifierRef name: {} ", oppositeRuleClassifierRef.getInstanceName());
- return null;
- }
-
- // Check ethertype. Values must be equal
- for (ParameterValue ruleParameter : ruleClassifierInstance.getParameterValue()) {
- for (ParameterValue oppositeRuleParameter : oppositeRuleClassifierInstance.getParameterValue()) {
- if ((ruleParameter.getName().getValue().equals(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
- && oppositeRuleParameter.getName().getValue().equals(EtherTypeClassifierDefinition.ETHERTYPE_PARAM)) {
- if (!ruleParameter.getIntValue().equals(oppositeRuleParameter.getIntValue())) {
- LOG.trace("Ethertype values are not equal, rule: {}, opposite rule: {} ", rule, oppositeRule);
- return null;
- }
- }
- }
- }
- // Check proto if exists. Values must be equal or missing
- ParameterValue ruleProtoParameter = null;
- ParameterValue oppositeRuleProtoParameter = null;
- for (ParameterValue ruleParameter : ruleClassifierInstance.getParameterValue()) {
- if (ruleParameter.getName().getValue().equals(IpProtoClassifierDefinition.PROTO_PARAM)) {
- ruleProtoParameter = ruleParameter;
- }
- }
- for (ParameterValue oppositeRuleParameter : oppositeRuleClassifierInstance.getParameterValue()) {
- if (oppositeRuleParameter.getName().getValue().equals(IpProtoClassifierDefinition.PROTO_PARAM)) {
- oppositeRuleProtoParameter = oppositeRuleParameter;
- }
- }
-
- if (ruleProtoParameter == null || ruleProtoParameter.getIntValue() == null) {
- return oppositeRule;
- } else if (oppositeRuleProtoParameter == null || oppositeRuleProtoParameter.getIntValue() == null) {
- return rule;
- } else if (!ruleProtoParameter.getIntValue().equals(oppositeRuleProtoParameter.getIntValue())) {
- LOG.trace("Proto parameters are not equal, rule parameters: {}, opposite rule parameters {} ",
- ruleProtoParameter, oppositeRuleProtoParameter);
- return null;
- }
-
- // Check ports
- // TODO add support for port ranges
- ParameterValue ruleL4Src = null;
- ParameterValue oppositeRuleL4Src = null;
- ParameterValue ruleL4Dst = null;
- ParameterValue oppositeRuleL4Dst = null;
-
- for (ParameterValue ruleParameter : ruleClassifierInstance.getParameterValue()) {
- if (ruleParameter.getName().getValue().equals(L4ClassifierDefinition.SRC_PORT_PARAM)) {
- ruleL4Src = ruleParameter;
- }
- if (ruleParameter.getName().getValue().equals(L4ClassifierDefinition.DST_PORT_PARAM)) {
- ruleL4Dst = ruleParameter;
- }
- }
- for (ParameterValue oppositeRuleParameter : oppositeRuleClassifierInstance.getParameterValue()) {
- if (oppositeRuleParameter.getName().getValue().equals(L4ClassifierDefinition.SRC_PORT_PARAM)) {
- oppositeRuleL4Src = oppositeRuleParameter;
- }
- if (oppositeRuleParameter.getName().getValue().equals(L4ClassifierDefinition.DST_PORT_PARAM)) {
- oppositeRuleL4Dst = oppositeRuleParameter;
- }
- }
-
- if (ruleL4Src == null && ruleL4Dst == null && oppositeRuleL4Src == null && oppositeRuleL4Dst == null) {
- return rule;
- }
-
- // Source rules
- if (ruleL4Src == null && oppositeRuleL4Src != null) {
- return oppositeRule;
- }
- if (ruleL4Src != null && oppositeRuleL4Src == null) {
- return rule;
- }
- if (ruleL4Src != null && ruleL4Src.getIntValue() != null && oppositeRuleL4Src.getIntValue() != null
- && ruleL4Src.equals(oppositeRuleL4Src)) {
- return rule;
- }
- if (ruleL4Src != null && ruleL4Src.getIntValue() != null && oppositeRuleL4Src.getIntValue() != null
- && !ruleL4Src.equals(oppositeRuleL4Src)) {
- return null;
- }
-
- // Destination rules
- if (ruleL4Dst == null && oppositeRuleL4Dst != null) {
- return oppositeRule;
- }
- if (ruleL4Dst != null && oppositeRuleL4Dst == null) {
- return rule;
+ private void createFlowsForRule(Rule rule, List<Rule> providedRules, List<Rule> consumedRules,
+ Direction direction, NetworkElements netElements,OfWriter ofWriter, IndexedTenant tenant, Set<IpPrefix> sIpPrefixes,
+ Set<IpPrefix> dIpPrefixes, int priority) {
+ List<Rule> reverseProvidedRules = findRulesInDirection(reverse(direction), providedRules);
+ List<String> resolvedSymmetricChains =
+ resolveSymetricChainActions(direction, rule, tenant, reverseProvidedRules, consumedRules);
+ if (resolvedSymmetricChains == null) {
+ LOG.debug("Rule {} skipped. Reason: asymmetric use of symmetric chain", rule);
+ return;
}
- if (ruleL4Dst != null && ruleL4Dst.getIntValue() != null && oppositeRuleL4Dst.getIntValue() != null
- && ruleL4Dst.equals(oppositeRuleL4Dst)) {
- return rule;
+ // Create list of matches/actions. Also creates chain flows when
+ // specific action requires it
+ List<MatchBuilder> matches = null;
+ if (consumedRules.contains(rule)) {
+ matches = createMatches(direction, reverse(direction), netElements, tenant, rule,
+ sIpPrefixes, dIpPrefixes);
+ } else {
+ matches = createMatches(direction, direction, netElements, tenant, rule, sIpPrefixes,
+ dIpPrefixes);
}
- if (ruleL4Dst != null && ruleL4Dst.getIntValue() != null && oppositeRuleL4Dst.getIntValue() != null
- && !ruleL4Dst.equals(oppositeRuleL4Dst)) {
- return null;
+ List<ActionBuilder> actions = createActions(ofWriter, netElements, direction, tenant, rule,
+ resolvedSymmetricChains);
+ if (actions == null) {
+ return;
}
- return null;
+ // Compose flows
+ createFlows(matches, actions, netElements, ofWriter, priority);
}
- private void resolveDestinationEpgPolicy(OfWriter ofWriter, NetworkElements netElements, Policy reversedPolicy,
- boolean isReverted) {
- isReversedPolicy = true;
- for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : getActiveRulesBetweenEps(
- reversedPolicy, netElements.getSrcEp(), netElements.getDstEp())) {
- Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
- .getL3EpPrefixes());
- Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
- .getL3EpPrefixes());
- PolicyPair policyPair = new PolicyPair(netElements.getSrcEpOrdinals().getEpgId(), netElements.getDstEpOrdinals().getEpgId(),
- netElements.getSrcEpOrdinals().getCgId(), netElements.getDstEpOrdinals().getCgId(), sIpPrefixes, dIpPrefixes,
- netElements.getSrcNodeId(), netElements.getDstNodeId());
- if (visitedReversePairs.contains(policyPair)) {
- LOG.trace(
- "PolicyEnforcer: Reverse: Already visited PolicyPair {}, endpoints {} {} skipped",
- policyPair, netElements.getSrcEp().getKey(), netElements.getDstEp().getKey());
- continue;
- } else {
- LOG.trace("PolicyEnforcer: Reverse: Visiting: PolicyPair {} via endpoints {} {}",
- policyPair, netElements.getSrcEp().getKey(), netElements.getDstEp().getKey());
- visitedReversePairs.add(policyPair);
-
- }
- int priority = 65000;
- for (RuleGroup rg : activeRulesByConstraints.getValue()) {
- TenantId tenantId = rg.getContractTenant().getId();
- IndexedTenant tenant = ctx.getTenant(tenantId);
- for (Rule rule : rg.getRules()) {
+ private List<String> resolveSymetricChainActions(Direction direction, Rule rule, IndexedTenant tenant,
+ List<Rule> reversedProvidedRules, List<Rule> consumedRules) {
+ List<String> chainNames = new ArrayList<>();
+ if (rule.getActionRef() != null) {
- Set<Direction> directions = getRuleDirections(rule);
- if (directions.isEmpty()) {
+ for (ActionRef actionRef : rule.getActionRef()) {
+ ActionInstance actionInstance = tenant.getAction(actionRef.getName());
+ if (actionInstance == null) {
+ continue;
+ }
+ Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
+ if (action == null) {
+ continue;
+ }
+ if (action instanceof ChainAction) {
+ chainNames = getSymetricChainNames(actionInstance);
+ if (chainNames.isEmpty()) {
continue;
}
+ List<Rule> reversedRules = findRulesInDirection(reverse(direction), reversedProvidedRules);
+ reversedRules.addAll(findRulesInDirection(direction, consumedRules));
- for(Direction direction : directions) {
-
- // When specific direction flows exists, do not create them again
- if (direction.equals(Direction.In) && reversePathFlowsCreated) {
+ List<String> oppositeChainNames = new ArrayList<>();
+ for (Rule oppositeRule : reversedRules) {
+ if (oppositeRule.getActionRef() == null) {
continue;
}
- if (direction.equals(Direction.Out) && directPathFlowsCreated) {
- continue;
- }
-
- List<MatchBuilder> inMatches = createMatches(Direction.In, policyPair, tenant, rule);
- List<MatchBuilder> outMatches = createMatches(Direction.Out, policyPair, tenant, rule);
-
- // In case chain action is called here, it has to know that this is reversed policy to set tunnel
- // ordinal correctly
- List<ActionBuilder> inActions = createActions(ofWriter, netElements, Direction.In, policyPair, tenant,
- rule, isReverted);
- List<ActionBuilder> outActions = createActions(ofWriter, netElements, Direction.Out, policyPair, tenant,
- rule, isReverted);
-
- createFlows(inMatches, inActions, netElements, ofWriter, priority);
- createFlows(outMatches, outActions, netElements, ofWriter, priority);
-
- if (direction.equals(Direction.In)) {
- reversePathFlowsCreated = true;
- }
- if (direction.equals(Direction.Out)) {
- directPathFlowsCreated = true;
- }
-
- priority -= 1;
+ for (ActionRef oppositeActionRef : oppositeRule.getActionRef()) {
+ ActionInstance oppositeActionInstance = tenant.getAction(oppositeActionRef.getName());
+ if (oppositeActionInstance == null) {
+ continue;
+ }
+ Action oppositeAction = SubjectFeatures.getAction(oppositeActionInstance.getActionDefinitionId());
+ if (oppositeAction == null) {
+ continue;
+ }
+ if (oppositeAction instanceof ChainAction) {
+ oppositeChainNames.addAll(getSymetricChainNames(oppositeActionInstance));
- if (directPathFlowsCreated && reversePathFlowsCreated) {
- resolvedEpgPairs.put(netElements.getSrcEpg(), netElements.getDstEpg());
+ }
}
}
+ if (!oppositeChainNames.containsAll(chainNames)) {
+ return null;
+ }
+ if ((consumedRules.contains(rule) && (direction.equals(Direction.In)))
+ || ((!consumedRules.contains(rule)) && direction.equals(Direction.Out))) {
+ return new ArrayList<>();
+ }
}
}
}
+ return chainNames;
}
- private void allowSameEpg(NodeId nodeId, OfWriter ofWriter) throws Exception {
- for (Endpoint sourceEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
- for (EgKey sourceEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(sourceEp)) {
+ private List<String> getSymetricChainNames(ActionInstance action) {
+ List<String> chainNames = new ArrayList<>();
+ for (ParameterValue param : action.getParameterValue()) {
+ if (param.getStringValue() != null
+ && param.getName().getValue().equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
+ String chainName = param.getStringValue();
+ ServiceFunctionPath sfcPath = ChainAction.getSfcPath(new SfcName(chainName));
+ if (sfcPath == null || sfcPath.getName() == null) {
+ continue;
+ }
+ if (sfcPath.isSymmetric()) {
+ chainNames.add(param.getStringValue());
+ }
+ }
+ }
+ return chainNames;
+ }
- IndexedTenant tenant = ctx.getTenant(sourceEpgKey.getTenantId());
- if (tenant != null) {
- EndpointGroup group = tenant.getEndpointGroup(sourceEpgKey.getEgId());
- if (group == null) {
- LOG.debug("EPG {} does not exit and is used in EP {}", sourceEpgKey, sourceEp.getKey());
- continue;
- }
- IntraGroupPolicy igp = group.getIntraGroupPolicy();
-
- if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
- for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(sourceEpgKey)) {
- EndpointFwdCtxOrdinals srcEpFwdCxtOrdinals =
- OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, sourceEp);
- if (srcEpFwdCxtOrdinals == null) {
- LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", sourceEp);
- continue;
- }
+ private void allowSameEpg(EgKey epgKey, Endpoint sourceEp, NodeId nodeId, OfWriter ofWriter) throws Exception {
- EndpointFwdCtxOrdinals dstEpFwdCxtOrdinals =
- OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, dstEp);
- if (dstEpFwdCxtOrdinals == null) {
- LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", dstEp);
- continue;
- }
+ IndexedTenant tenant = ctx.getTenant(epgKey.getTenantId());
+ if (tenant != null) {
+ EndpointGroup group = tenant.getEndpointGroup(epgKey.getEgId());
+ if (group == null) {
+ LOG.debug("EPG {} does not exit and is used ", epgKey);
+ return;
+ }
+ IntraGroupPolicy igp = group.getIntraGroupPolicy();
- int destinationEpgId = dstEpFwdCxtOrdinals.getEpgId();
- int sourceEpgId = srcEpFwdCxtOrdinals.getEpgId();
- ofWriter.writeFlow(nodeId, TABLE_ID, allowSameEpg(sourceEpgId, destinationEpgId));
- ofWriter.writeFlow(nodeId, TABLE_ID, allowSameEpg(destinationEpgId, sourceEpgId));
- }
- }
+ if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
+ EndpointFwdCtxOrdinals srcEpFwdCxtOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, sourceEp);
+ if (srcEpFwdCxtOrdinals == null) {
+ LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", sourceEp);
}
+ int epgId = srcEpFwdCxtOrdinals.getEpgId();
+ ofWriter.writeFlow(nodeId, TABLE_ID, allowSameEpg(epgId));
}
}
}
// Return list of all rules with opposite direction
- private List<Rule> findRulesInSameDirection(Rule ruleToResolve, List<Rule> reversedRules) {
+ private List<Rule> findRulesInDirection(Direction direction, List<Rule> rules) {
List<Rule> sameDirectionRules = new ArrayList<>();
- for (Rule ruleToCompare : reversedRules) {
- for (ClassifierRef classifierRefToCompare : ruleToCompare.getClassifierRef()) {
- for (ClassifierRef classifierRefToResolve : ruleToResolve.getClassifierRef()) {
- if (isDirectionOpposite(classifierRefToCompare.getDirection(), classifierRefToResolve.getDirection())) {
- sameDirectionRules.add(ruleToCompare);
- }
+ if (rules != null) {
+ for (Rule ruleToCompare : rules) {
+ if (isSameDirection(direction, ruleToCompare)) {
+ sameDirectionRules.add(ruleToCompare);
}
}
}
return sameDirectionRules;
}
- private boolean isDirectionOpposite(Direction one, Direction two) {
- return ((one.equals(Direction.In) && two.equals(Direction.Out))
- || (one.equals(Direction.Out) && two.equals(Direction.In)));
+ private boolean isSameDirection(Direction direction, Rule rule) {
+ for (ClassifierRef classifier : rule.getClassifierRef()) {
+ if (direction.equals(classifier.getDirection()) || direction.equals(Direction.Bidirectional)
+ || Direction.Bidirectional.equals(classifier.getDirection())) {
+ return true;
+ }
+ }
+ return false;
}
private List<Rule> getRules(List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> activeRules) {
Match match = mb.build();
FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "arp", match);
return base().setPriority(priority)
- .setId(flowid)
- .setMatch(match)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
- .build();
+ .setId(flowid)
+ .setMatch(match)
+ .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
+ .build();
}
- private Flow allowSameEpg(int sourceEpgId, int destinationEpgId) {
+ private Flow allowSameEpg(int epgId) {
MatchBuilder mb = new MatchBuilder();
- addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, (long) sourceEpgId),
- RegMatch.of(NxmNxReg2.class, (long) destinationEpgId));
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, (long) epgId), RegMatch.of(NxmNxReg2.class, (long) epgId));
Match match = mb.build();
FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "intraallow", match);
- FlowBuilder flow = base().setId(flowId)
- .setMatch(match)
- .setPriority(65000)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+ FlowBuilder flow = base().setId(flowId).setMatch(match).setPriority(65000).setInstructions(
+ instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
return flow.build();
}
addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, 0xffffffL));
Match match = mb.build();
FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "tunnelallow", match);
- FlowBuilder flow = base().setId(flowId)
- .setMatch(match)
- .setPriority(65000)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+ FlowBuilder flow = base().setId(flowId).setMatch(match).setPriority(65000).setInstructions(
+ instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
return flow.build();
}
- private List<MatchBuilder> createMatches(Direction direction, PolicyPair policyPair, IndexedTenant contractTenant,
- Rule rule) {
+ private List<MatchBuilder> createMatches(Direction flowDirection, Direction classifierDirection,
+ NetworkElements netElements, IndexedTenant contractTenant, Rule rule, Set<IpPrefix> sIpPrefixes,
+ Set<IpPrefix> dIpPrefixes) {
Map<String, ParameterValue> paramsFromClassifier = new HashMap<>();
Set<ClassifierDefinitionId> classifiers = new HashSet<>();
for (ClassifierRef cr : rule.getClassifierRef()) {
if (cr.getDirection() != null && !cr.getDirection().equals(Direction.Bidirectional)
- && !cr.getDirection().equals(direction)) {
+ && !cr.getDirection().equals(classifierDirection)) {
continue;
}
if (classifiers.isEmpty()) {
return null;
}
- List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
+ List<Map<String, ParameterValue>> derivedParamsByName =
+ ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
List<MatchBuilder> flowMatchBuilders = new ArrayList<>();
for (Map<String, ParameterValue> params : derivedParamsByName) {
List<MatchBuilder> matchBuildersToResolve = new ArrayList<>();
- if (policyPair.consumerEicIpPrefixes.isEmpty() && policyPair.providerEicIpPrefixes.isEmpty()) {
- matchBuildersToResolve.add(createBaseMatch(direction, policyPair, null, null));
- } else if (!policyPair.consumerEicIpPrefixes.isEmpty() && policyPair.providerEicIpPrefixes.isEmpty()) {
- for (IpPrefix sIpPrefix : policyPair.consumerEicIpPrefixes) {
- matchBuildersToResolve.add(createBaseMatch(direction, policyPair, sIpPrefix, null));
+ if (sIpPrefixes.isEmpty() && dIpPrefixes.isEmpty()) {
+ matchBuildersToResolve.add(createBaseMatch(flowDirection, netElements, null, null));
+ } else if (!sIpPrefixes.isEmpty() && dIpPrefixes.isEmpty()) {
+ for (IpPrefix sIpPrefix : sIpPrefixes) {
+ matchBuildersToResolve.add(createBaseMatch(flowDirection, netElements, sIpPrefix, null));
}
- } else if (policyPair.consumerEicIpPrefixes.isEmpty() && !policyPair.providerEicIpPrefixes.isEmpty()) {
- for (IpPrefix dIpPrefix : policyPair.consumerEicIpPrefixes) {
- matchBuildersToResolve.add(createBaseMatch(direction, policyPair, null, dIpPrefix));
+ } else if (sIpPrefixes.isEmpty() && !dIpPrefixes.isEmpty()) {
+ for (IpPrefix dIpPrefix : dIpPrefixes) {
+ matchBuildersToResolve.add(createBaseMatch(flowDirection, netElements, null, dIpPrefix));
}
} else {
- for (IpPrefix sIpPrefix : policyPair.consumerEicIpPrefixes) {
- for (IpPrefix dIpPrefix : policyPair.consumerEicIpPrefixes) {
- matchBuildersToResolve.add(createBaseMatch(direction, policyPair, sIpPrefix, dIpPrefix));
+ for (IpPrefix sIpPrefix : sIpPrefixes) {
+ for (IpPrefix dIpPrefix : dIpPrefixes) {
+ matchBuildersToResolve.add(createBaseMatch(flowDirection, netElements, sIpPrefix, dIpPrefix));
}
}
}
return flowMatchBuilders;
}
- private List<ActionBuilder> createActions(OfWriter ofWriter, NetworkElements netElements, Direction direction, PolicyPair policyPair,
- IndexedTenant contractTenant, Rule rule, boolean isReversedDirection) {
+ private List<ActionBuilder> createActions(OfWriter ofWriter, NetworkElements netElements, Direction direction,
+ IndexedTenant contractTenant, Rule rule, List<String> resolvedSymmetricChains) {
List<ActionBuilder> actionBuilderList = new ArrayList<>();
if (rule.getActionRef() != null) {
List<ActionRef> actionRefList = new ArrayList<>(rule.getActionRef());
Collections.sort(actionRefList, ActionRefComparator.INSTANCE);
- for (ActionRef actionRule : actionRefList) {
- ActionInstance actionInstance = contractTenant.getAction(actionRule.getName());
+ for (ActionRef actionRef : actionRefList) {
+ ActionInstance actionInstance = contractTenant.getAction(actionRef.getName());
if (actionInstance == null) {
// XXX TODO fail the match and raise an exception
- LOG.warn("Action instance {} not found", actionRule.getName().getValue());
+ LOG.warn("Action instance {} not found", actionRef.getName().getValue());
return null;
}
Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
}
}
}
- if (isReversedDirection) {
- direction = reverse(direction);
+ if (action instanceof ChainAction) {
+ ((ChainAction) action).setResolvedSymmetricChains(resolvedSymmetricChains);
}
// Convert the GBP Action to one or more OpenFlow Actions
- if (!(actionRefList.indexOf(actionRule) == (actionRefList.size() - 1)
- && action.equals(SubjectFeatures.getAction(AllowActionDefinition.DEFINITION.getId())))) {
- actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(), netElements,
- policyPair, ofWriter, ctx, direction);
+ if ((!(actionRefList.indexOf(actionRef) == (actionRefList.size() - 1)
+ && action.equals(SubjectFeatures.getAction(AllowActionDefinition.DEFINITION.getId()))))
+ && actionBuilderList != null) {
+ actionBuilderList = action.updateAction(actionBuilderList, params, actionRef.getOrder(),
+ netElements, ofWriter, ctx, direction);
}
}
}
return actionBuilderList;
}
- private Direction reverse(Direction direction) {
+ public static Direction reverse(Direction direction) {
if (direction.equals(Direction.In)) {
return Direction.Out;
- }
- else if(direction.equals(Direction.Out)) {
+ } else if (direction.equals(Direction.Out)) {
return Direction.In;
- }
- else {
+ } else {
return Direction.Bidirectional;
}
}
- private void createFlows(List<MatchBuilder> flowMatchBuilders, List<ActionBuilder> actionBuilderList, NetworkElements netElements,
- OfWriter ofWriter, int priority) {
+ private void createFlows(List<MatchBuilder> flowMatchBuilders, List<ActionBuilder> actionBuilderList,
+ NetworkElements netElements, OfWriter ofWriter, int priority) {
FlowBuilder flow = base().setPriority(priority);
- if(flowMatchBuilders == null) {
+ if (flowMatchBuilders == null) {
return;
}
for (MatchBuilder mb : flowMatchBuilders) {
.getExternalImplicitGroup();
boolean performNat = false;
for (EndpointL3 natEp : ctx.getEndpointManager().getL3EndpointsWithNat()) {
- if (natEp.getMacAddress() != null &&
- natEp.getL2Context() != null &&
- netElements.getSrcEp().getKey().equals(new EndpointKey(natEp.getL2Context(),
- natEp.getMacAddress())) &&
- EndpointManager.isExternal(netElements.getDstEp(), eigs)) {
+ if (natEp.getMacAddress() != null && natEp.getL2Context() != null
+ && netElements.getSrcEp()
+ .getKey()
+ .equals(new EndpointKey(natEp.getL2Context(), natEp.getMacAddress()))
+ && EndpointManager.isExternal(netElements.getDstEp(), eigs)) {
performNat = true;
break;
}
}
if (actionBuilderList == null) {
- //TODO - analyse, what happen for unknown action, SFC, etc.
- LOG.warn("Action builder list not found, partially flow which is not created: {}", flow.build());
+ // flow with this match should not appear on switch (e.g. chain action IN)
+ // //TODO - analyse, what happen for unknown action, SFC, etc.
continue;
}
if (actionBuilderList.isEmpty()) {
- flow.setInstructions((performNat == true) ? instructions(gotoEgressNatInstruction) : instructions(gotoExternalInstruction));
+ flow.setInstructions((performNat == true) ? instructions(gotoEgressNatInstruction) : instructions(
+ gotoExternalInstruction));
} else {
flow.setInstructions(instructions(applyActionIns(actionBuilderList),
(performNat == true) ? gotoEgressNatInstruction : gotoExternalInstruction));
}
}
- private MatchBuilder createBaseMatch(Direction direction, PolicyPair policyPair, IpPrefix sIpPrefix,
- IpPrefix dIpPrefix) {
+ private MatchBuilder createBaseMatch(Direction direction, NetworkElements netElements, IpPrefix sIpPrefix,
+ IpPrefix dIpPrefix) {
MatchBuilder baseMatch = new MatchBuilder();
if (direction.equals(Direction.In)) {
- addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, (long) policyPair.consumerEpgId),
- RegMatch.of(NxmNxReg1.class, (long) policyPair.consumerCondGrpId),
- RegMatch.of(NxmNxReg2.class, (long) policyPair.providerEpgId),
- RegMatch.of(NxmNxReg3.class, (long) policyPair.providerCondGrpId));
+ addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, (long) netElements.getDstEpOrdinals().getEpgId()),
+ RegMatch.of(NxmNxReg1.class, (long) netElements.getDstEpOrdinals().getCgId()),
+ RegMatch.of(NxmNxReg2.class, (long) netElements.getSrcEpOrdinals().getEpgId()),
+ RegMatch.of(NxmNxReg3.class, (long) netElements.getSrcEpOrdinals().getCgId()));
if (sIpPrefix != null) {
baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, true));
}
if (dIpPrefix != null) {
- baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, true));
+ baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, false));
}
} else {
- addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, (long) policyPair.providerEpgId),
- RegMatch.of(NxmNxReg1.class, (long) policyPair.providerCondGrpId),
- RegMatch.of(NxmNxReg2.class, (long) policyPair.consumerEpgId),
- RegMatch.of(NxmNxReg3.class, (long) policyPair.consumerCondGrpId));
+ addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, (long) netElements.getSrcEpOrdinals().getEpgId()),
+ RegMatch.of(NxmNxReg1.class, (long) netElements.getSrcEpOrdinals().getCgId()),
+ RegMatch.of(NxmNxReg2.class, (long) netElements.getDstEpOrdinals().getEpgId()),
+ RegMatch.of(NxmNxReg3.class, (long) netElements.getDstEpOrdinals().getCgId()));
if (sIpPrefix != null) {
baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, false));
}
if (dIpPrefix != null) {
- baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, false));
+ baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, true));
}
}
return baseMatch;
// TODO: move to a common utils for all renderers
private List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> getActiveRulesBetweenEps(Policy policy,
- Endpoint consEp, Endpoint provEp) {
+ Endpoint consEp, Endpoint provEp) {
List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> rulesWithEpConstraints = new ArrayList<>();
for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> cell : policy.getRuleMap().cellSet()) {
EndpointConstraint consEpConstraint = cell.getRowKey();
return constraint.getConditionSet().matches(epConditions);
}
- private enum PathStatus { both, partial, none }
-
- public static boolean checkPolicyOrientation() {
- return isReversedPolicy;
- }
-
/**
* Private internal class for ordering Actions in Rules. The order is
* determined first by the value of the order parameter, with the lower
@Override
public int compare(ActionRef arg0, ActionRef arg1) {
return ComparisonChain.start()
- .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
- .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
- .result();
+ .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
+ .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
+ .result();
}
}
- @Immutable
- public static class PolicyPair {
-
- private final int consumerEpgId;
- private final int providerEpgId;
- private final int consumerCondGrpId;
- private final int providerCondGrpId;
- private final Set<IpPrefix> consumerEicIpPrefixes;
- private final Set<IpPrefix> providerEicIpPrefixes;
- private final NodeId consumerEpNodeId;
- private final NodeId providerEpNodeId;
-
- public PolicyPair(int consumerEpgId, int providerEpgId, int consumerCondGrpId, int providerCondGrpId,
- Set<IpPrefix> consumerEicIpPrefixes, Set<IpPrefix> providerEicIpPrefixes, NodeId consumerEpNodeId, NodeId providerEpNodeId) {
- super();
- this.consumerEpgId = consumerEpgId;
- this.providerEpgId = providerEpgId;
- this.consumerCondGrpId = consumerCondGrpId;
- this.providerCondGrpId = providerCondGrpId;
- this.consumerEicIpPrefixes = consumerEicIpPrefixes;
- this.providerEicIpPrefixes = providerEicIpPrefixes;
- this.consumerEpNodeId = consumerEpNodeId;
- this.providerEpNodeId = providerEpNodeId;
- }
-
- public int getConsumerEpgId() {
- return consumerEpgId;
- }
-
- public int getProviderEpgId() {
- return providerEpgId;
- }
-
- public NodeId getConsumerEpNodeId() {
- return consumerEpNodeId;
- }
-
- public NodeId getProviderEpNodeId() {
- return providerEpNodeId;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((providerEicIpPrefixes == null) ? 0 : providerEicIpPrefixes.hashCode());
- result = prime * result + providerCondGrpId;
- result = prime * result + providerEpgId;
- result = prime * result + ((consumerEicIpPrefixes == null) ? 0 : consumerEicIpPrefixes.hashCode());
- result = prime * result + consumerCondGrpId;
- result = prime * result + consumerEpgId;
- result = prime * result + ((consumerEpNodeId == null) ? 0 : consumerEpNodeId.hashCode());
- result = prime * result + ((providerEpNodeId == null) ? 0 : providerEpNodeId.hashCode());
-
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- PolicyPair other = (PolicyPair) obj;
- if (providerEicIpPrefixes == null) {
- if (other.providerEicIpPrefixes != null) {
- return false;
- }
- } else if (!providerEicIpPrefixes.equals(other.providerEicIpPrefixes)) {
- return false;
- }
- if (consumerEicIpPrefixes == null) {
- if (other.consumerEicIpPrefixes != null) {
- return false;
- }
- } else if (!consumerEicIpPrefixes.equals(other.consumerEicIpPrefixes)) {
- return false;
- }
- if (consumerEpNodeId == null) {
- if (other.consumerEpNodeId != null) {
- return false;
- }
- } else if (!consumerEpNodeId.getValue().equals(other.consumerEpNodeId.getValue())) {
- return false;
- }
- if (providerEpNodeId == null) {
- if (other.providerEpNodeId != null) {
- return false;
- }
- } else if (!providerEpNodeId.getValue().equals(other.providerEpNodeId.getValue())) {
- return false;
- }
- return (providerCondGrpId == other.providerCondGrpId)
- && (providerEpgId == other.providerEpgId)
- && (consumerCondGrpId == other.consumerCondGrpId)
- && (consumerEpgId == other.consumerEpgId);
-
- }
+ private static class RuleGroupComparator implements Comparator<RuleGroup> {
@Override
- public String toString() {
- return "consumerEPG: " + consumerEpgId +
- "consumerCG: " + consumerCondGrpId +
- "providerEPG: " + providerEpgId +
- "providerCG: " + providerCondGrpId +
- "consumerEpNodeId: " + consumerEpNodeId +
- "providerEpNodeId: " + providerEpNodeId +
- "consumerEicIpPrefixes: " + consumerEicIpPrefixes +
- "providerEicIpPrefixes: " + providerEicIpPrefixes;
- }
- }
-
- public class NetworkElements {
-
- private final Endpoint srcEp;
- private final Endpoint dstEp;
- private final EgKey srcEpg;
- private final EgKey dstEpg;
- private NodeId srcNodeId;
- private NodeId dstNodeId;
- private final NodeId localNodeId;
- private EndpointFwdCtxOrdinals srcEpOrdinals;
- private EndpointFwdCtxOrdinals dstEpOrdinals;
-
- public NetworkElements(Endpoint srcEp, Endpoint dstEp, EgKey srcEpg, EgKey dstEpg, NodeId nodeId, OfContext ctx) throws Exception {
- this.srcEp = srcEp;
- this.dstEp = dstEp;
- this.srcEpg = srcEpg;
- this.dstEpg = dstEpg;
- this.localNodeId = nodeId;
- this.srcEpOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, srcEp);
- if (this.srcEpOrdinals == null) {
- LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", srcEp);
- return;
- }
- this.dstEpOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, dstEp);
- if (this.dstEpOrdinals == null) {
- LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", dstEp);
- return;
- }
- if (dstEp.getAugmentation(OfOverlayContext.class) != null) {
- this.dstNodeId = dstEp.getAugmentation(OfOverlayContext.class).getNodeId();
- }
- if (srcEp.getAugmentation(OfOverlayContext.class) != null) {
- this.srcNodeId = srcEp.getAugmentation(OfOverlayContext.class).getNodeId();
- }
- }
-
-
- public Endpoint getSrcEp() {
- return srcEp;
- }
-
-
- public Endpoint getDstEp() {
- return dstEp;
- }
-
- public EgKey getSrcEpg() {
- return srcEpg;
- }
-
- public EgKey getDstEpg() {
- return dstEpg;
- }
-
- public NodeId getSrcNodeId() {
- return srcNodeId;
- }
-
-
- public NodeId getDstNodeId() {
- return dstNodeId;
- }
-
-
- public NodeId getLocalNodeId() {
- return localNodeId;
- }
-
-
- public EndpointFwdCtxOrdinals getSrcEpOrdinals() {
- return srcEpOrdinals;
- }
-
-
- public EndpointFwdCtxOrdinals getDstEpOrdinals() {
- return dstEpOrdinals;
+ public int compare(RuleGroup arg0, RuleGroup arg1) {
+ return ComparisonChain.start()
+ .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
+ .compare(arg0.getRelatedSubject().getValue(), arg1.getRelatedSubject().getValue()
+ ,Ordering.natural().nullsLast())
+ .result();
}
-
}
}
import org.opendaylight.groupbasedpolicy.api.Validator;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.PolicyPair;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
/**
* The result represents supported parameters for the action by renderer
- *
+ *
* @return list of supported parameters by the action
*/
public abstract List<SupportedParameterValues> getSupportedParameterValues();
* @param params the parameters for the action instance
* @param order the order of the list of actions
* @param netElements the network elements
- * @param policyPair the {@link PolicyPair}
* @param ofWriter the {@link OfWriter}
* @param ctx the OfContext
* @param direction the direction of traffic
Map<String, Object> params,
Integer order,
NetworkElements netElements,
- PolicyPair policyPair,
OfWriter ofWriter,
OfContext ctx,
Direction direction);
import org.opendaylight.groupbasedpolicy.dto.ValidationResultBuilder;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.PolicyPair;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
Map<String, Object> params,
Integer order,
NetworkElements netElements,
- PolicyPair policyPair,
OfWriter ofWriter,
OfContext ctx,
Direction direction) {
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxSetNsiAction;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxSetNspAction;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.opendaylight.groupbasedpolicy.dto.ValidationResultBuilder;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.PolicyPair;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcIidFactory;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader.SfcNshHeaderBuilder;
public class ChainAction extends Action {
private static final Logger LOG = LoggerFactory.getLogger(ChainAction.class);
+ private List<String> resolvedSymmetricChains = new ArrayList<>();;
+
+ public void setResolvedSymmetricChains(List<String> resolvedSymmetricChains) {
+ this.resolvedSymmetricChains = resolvedSymmetricChains;
+ }
@Override
public ActionDefinitionId getId() {
@Override
public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order,
- NetworkElements netElements, PolicyPair policyPair, OfWriter ofWriter,
+ NetworkElements netElements, OfWriter ofWriter,
OfContext ctx, Direction direction) {
/*
* Get the named chain
return null;
}
- Long returnVnId;
+ Long tunnelId;
/*
* If path is symmetrical then there are two RSPs.
ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction();
RenderedServicePath renderedServicePath;
RenderedServicePath rsp = getRspByName(rspName, rTx);
- returnVnId = (long) resolveTunnelId(netElements, false);
+ tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId();
if (rsp == null) {
renderedServicePath = createRsp(sfcPath, rspName);
if (renderedServicePath != null) {
}
try {
- if (sfcPath.isSymmetric() && direction.equals(Direction.Out)) {
+ if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) {
rspName = new RspName(rspName.getValue() + "-Reverse");
rsp = getRspByName(rspName, rTx);
- returnVnId = (long) resolveTunnelId(netElements, true);
+ tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId();
if (rsp == null) {
LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName);
renderedServicePath = createSymmetricRsp(renderedServicePath);
.setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1))
.setNshNspFromChain(renderedServicePath.getPathId())
.setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address()))
- .setNshMetaC2(returnVnId)
+ .setNshMetaC2(tunnelId)
.build();
- // Cannot set all actions here. Some actions are destination specific, and we don't know
- // a destination is to be
- // chained until we reach this point. Need to write match/action in External Table for
- // chained packets.
- actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order);
- actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order);
- createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx);
- return actions;
- }
+ createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction);
- // Return tunnelId according to policy direction
- private int resolveTunnelId(NetworkElements netElements, boolean isReversedPath) {
- if ((isReversedPath && PolicyEnforcer.checkPolicyOrientation())
- || (!isReversedPath && !PolicyEnforcer.checkPolicyOrientation())) {
- return netElements.getDstEpOrdinals().getTunnelId();
+ if (direction.equals(Direction.Out) ) {
+ actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order);
+ actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order);
} else {
- return netElements.getSrcEpOrdinals().getTunnelId();
+ return null;
}
+ return actions;
}
private RenderedServicePath createRsp(ServiceFunctionPath sfcPath, RspName rspName) {
}
}
- public ServiceFunctionPath getSfcPath(SfcName chainName) {
+ public static ServiceFunctionPath getSfcPath(SfcName chainName) {
ServiceFunctionPaths paths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
for (ServiceFunctionPath path : paths.getServiceFunctionPath()) {
if (path.getServiceChainName().equals(chainName)) {
return ImmutableList.<SupportedParameterValues>of(new SupportedParameterValuesBuilder()
.setParameterName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME)).build());
}
-
}
import org.junit.Test;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;\r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader.SfcNshHeaderBuilder;\r
import org.junit.Ignore;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\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
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
\r
public class FlowTableTest extends OfTableTest {\r
- FlowTable table;\r
+ protected FlowTable table;\r
InstanceIdentifier<Table> tiid;\r
\r
protected void setup() throws Exception {\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.ContextId;\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.policy.rev140421.tenants.tenant.ForwardingContextBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;\r
import com.google.common.collect.ImmutableList;\r
\r
public class OfTableTest {\r
- MockOfContext ctx;\r
+ protected MockOfContext ctx;\r
\r
- MockEndpointManager endpointManager;\r
- MockPolicyManager policyManager;\r
- MockSwitchManager switchManager;\r
- NodeId nodeId = new NodeId("openflow:1");\r
- NodeId remoteNodeId = new NodeId("openflow:2");\r
- NodeConnectorId nodeConnectorId =\r
+ protected MockEndpointManager endpointManager;\r
+ protected MockPolicyManager policyManager;\r
+ protected MockSwitchManager switchManager;\r
+ protected NodeId nodeId = new NodeId("openflow:1");\r
+ protected NodeId remoteNodeId = new NodeId("openflow:2");\r
+ protected NodeConnectorId nodeConnectorId =\r
new NodeConnectorId(nodeId.getValue() + ":4");\r
\r
- NodeConnectorId tunnelId =\r
+ protected 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
- L2FloodDomainId ext_fd = new L2FloodDomainId("d8024f7a-b83e-11e5-9912-ba0be0483c18");\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
- SubnetId ext_sub = new SubnetId("8da17ad9-3261-4dc9-bcff-928a2f73cce7");\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
+ protected L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d");\r
+ protected L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639");\r
+ protected L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");\r
+ protected L2FloodDomainId ext_fd = new L2FloodDomainId("d8024f7a-b83e-11e5-9912-ba0be0483c18");\r
+ protected SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");\r
+ protected SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");\r
+ protected SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec");\r
+ protected SubnetId ext_sub = new SubnetId("8da17ad9-3261-4dc9-bcff-928a2f73cce7");\r
+ protected TenantId tid = new TenantId("1118c691-8520-47ad-80b8-4cf5e3fe3302");\r
+ protected EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");\r
+ protected EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");\r
+ protected ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f");\r
\r
protected void initCtx() {\r
endpointManager = new MockEndpointManager();\r
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;
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.inet.types.rev100924.Ipv6Address;
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.FlowId;
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.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+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.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.NetworkDomainId;
+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.SubnetId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
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.ofoverlay.rev140528.OfOverlayContextBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.Segmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.SegmentationBuilder;
+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.ForwardingContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstancesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.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 java.util.ArrayList;
-import java.util.List;
+import com.google.common.collect.ImmutableList;
public abstract class MapperUtilsTest {
protected static final String DHCP_IP = "255.255.255.255";
protected static final String TENANT_ID = "dummy tenant";
protected static final String NODE_ID = "dummy node";
+ protected static final String CONTRACT_ID = "dummy contract";
protected static final String L2 = "L2";
- private static final String DOMAIN_ID = "dummy id";
+ protected static final String DOMAIN_ID = "dummy id";
protected final NodeId nodeId = new NodeId(NODE_ID);
+ protected NodeConnectorId nodeConnectorId =
+ new NodeConnectorId(nodeId.getValue() + CONNECTOR_0);
+ protected L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d");
+ protected L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639");
+ protected L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");
+ protected L2FloodDomainId ext_fd = new L2FloodDomainId("d8024f7a-b83e-11e5-9912-ba0be0483c18");
+ protected SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");
+ protected SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");
+ protected SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec");
+ protected SubnetId ext_sub = new SubnetId("8da17ad9-3261-4dc9-bcff-928a2f73cce7");
+ protected TenantId tid = new TenantId(TENANT_ID);
+ protected EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");
+ protected EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");
+ protected ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f");
protected Short tableId;
protected OfContext ctx;
protected OfWriter ofWriter;
protected PolicyManager policyManager;
protected EndpointManager endpointManager;
protected PolicyInfo policyInfo;
+ protected FlowTable table;
protected Flow flowCreator(FlowId flowId, short tableId, Integer priority, Match match, Instructions instructions) {
FlowBuilder flowBuilder = FlowUtils.base(tableId);
// Augment node connector
OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(nodeConnectorId));
+ ofOverlayContextBuilder.setNodeId(nodeId);
endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
// Set network containment
l2FloodDomains.add(l2FloodDomainBuilder.build());
return l2FloodDomains;
}
+
+ protected EndpointBuilder endpointBuilder(IpAddress ip, MacAddress mac, NodeConnectorId nodeConnectorId,
+ EndpointGroupId epg, L2BridgeDomainId l2) {
+ EndpointBuilder endpointBuilder = new EndpointBuilder();
+
+ // Set tenant
+ endpointBuilder.setTenant(new TenantId(TENANT_ID));
+
+ // Set L3 address
+ if (ip != null) {
+ List<L3Address> l3Addresses = new ArrayList<>();
+ L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
+ l3AddressBuilder.setIpAddress(ip);
+ l3Addresses.add(l3AddressBuilder.build());
+ endpointBuilder.setL3Address(l3Addresses);
+ }
+
+ // Set Mac address
+ endpointBuilder.setMacAddress(new MacAddress(mac));
+ endpointBuilder.setL2Context(l2);
+ endpointBuilder.setEndpointGroup(epg);
+
+ // Augment node connector
+ OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
+ ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(nodeConnectorId));
+ ofOverlayContextBuilder.setNodeId(nodeId);
+ endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
+
+ // Set network containment
+ endpointBuilder.setNetworkContainment(new NetworkDomainId(DOMAIN_ID));
+
+ return endpointBuilder;
+ }
+
+ protected TenantBuilder baseTenant() {
+ return new TenantBuilder().setId(tid)
+ .setPolicy(new PolicyBuilder()
+ .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()))
+ .setSubjectFeatureInstances(
+ new SubjectFeatureInstancesBuilder()
+ .setClassifierInstance(
+ ImmutableList
+ .of(new ClassifierInstanceBuilder().setName(new ClassifierName("tcp_dst_80"))
+ .setClassifierDefinitionId(L4ClassifierDefinition.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(), new ClassifierInstanceBuilder()
+ .setName(new ClassifierName("tcp_src_80"))
+ .setClassifierDefinitionId(Classifier.L4_CL.getId())
+ .setParameterValue(ImmutableList.of(
+ new ParameterValueBuilder()
+ .setName(new ParameterName("sourceport"))
+ .setIntValue(Long.valueOf(80))
+ .build(),
+ new ParameterValueBuilder().setName(new ParameterName("proto"))
+ .setIntValue(Long.valueOf(6))
+ .build()))
+ .build(),
+ new ClassifierInstanceBuilder()
+ .setName(new ClassifierName("ether_type"))
+ .setClassifierDefinitionId(Classifier.ETHER_TYPE_CL.getId())
+ .setParameterValue(ImmutableList.of(new ParameterValueBuilder()
+ .setName(new ParameterName("ethertype"))
+ .setIntValue(Long.valueOf(FlowUtils.IPv4))
+ .build()))
+ .build()))
+ .setActionInstance(
+ ImmutableList.of(new ActionInstanceBuilder().setName(new ActionName("allow"))
+ .setActionDefinitionId(new AllowAction().getId())
+ .build()))
+ .build())
+ .build())
+ .setForwardingContext(
+ new ForwardingContextBuilder()
+ .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)
+ .addAugmentation(Segmentation.class,
+ new SegmentationBuilder()
+ .setSegmentationId(Integer.valueOf(216))
+ .build())
+ .build(),
+ new L2FloodDomainBuilder()
+ .setId(ext_fd)
+ .addAugmentation(Segmentation.class,
+ new SegmentationBuilder()
+ .setSegmentationId(Integer.valueOf(2016))
+ .build())
+ .build()))
+ .setSubnet(ImmutableList.of(
+ new SubnetBuilder().setId(sub2)
+ .setParent(fd)
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.0/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.0/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.0/24")))
+ .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))
+ .build(),
+ new SubnetBuilder()
+ .setId(ext_sub)
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("192.168.111.0/24")))
+ .setParent(ext_fd)
+ .build()))
+ .build());
+ }
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertTrue;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
-import java.util.Set;
-import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.groupbasedpolicy.dto.ConditionGroup;
import org.opendaylight.groupbasedpolicy.dto.EgKey;
import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockOfContext;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.MockEndpointManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.PolicyPair;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager;
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.PortNumber;
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.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.ConditionMatcherName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
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.action.refs.ActionRefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
+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.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.tenant.policy.ContractBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
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._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;
@RunWith(PowerMockRunner.class)
@PrepareForTest({PolicyManager.class})
-public class PolicyEnforcerTest extends FlowTableTest {
-
- @Override
+public class PolicyEnforcerTest extends MapperUtilsTest {
+
+ //TODO (att: kblagov) XXX needs redesign
+ private final int sameEpgFlows = 1;
+ private final int allowTunnelFlows = 1;
+ private final int layer4flowsIPv4 = 1;
+ private final int layer4flowsIPv6 = 1;
+ private final int dropAllFlow = 1;
+ private final int arpFlows = 1;
+ private MockEndpointManager endpointManagerMock;
+ private MockPolicyManager policyManagerMock;
+ private MockSwitchManager switchManagerMock;
+ private MockOfContext ctxMock;
+
+ private NodeConnectorId tunnelId =
+ new NodeConnectorId(nodeId.getValue() + ":42");
@Before
public void setup() throws Exception {
PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true);
- initCtx();
- table = new PolicyEnforcer(ctx, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER());
- super.setup();
+ endpointManagerMock = new MockEndpointManager();
+ policyManagerMock = new MockPolicyManager(endpointManagerMock);
+ switchManagerMock = new MockSwitchManager();
+ ctxMock = new MockOfContext(null, policyManagerMock, switchManagerMock, endpointManagerMock, null);
+ table = new PolicyEnforcer(ctxMock, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER());
- switchManager.addSwitch(
+ switchManagerMock.addSwitch(
nodeId,
tunnelId,
Collections.<NodeConnectorId>emptySet(),
.build())).build());
}
- @Ignore
- @Test
- public void testNoEps() throws Exception {
- OfWriter fm = dosync(null);
- assertEquals(2, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
- .getFlow()
- .size());
- }
-
- @Ignore
@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);
- ctx.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy())
+ Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd)
+ .build();
+ endpointManagerMock.addEndpoint(ep1);
+ Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg, bd)
+ .build();
+ endpointManagerMock.addEndpoint(ep2);
+ ctxMock.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy())
.setContract(ImmutableList.of(baseContract(null).build())).build()).build());
- OfWriter fm = dosync(null);
- assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+ ofWriter = new OfWriter();
+ table.sync(ep1, ofWriter);
+ assertTrue(!ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
- .size());
+ .isEmpty());
int count = 0;
HashMap<String, Flow> flowMap = new HashMap<>();
- for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
+ for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
flowMap.put(f.getId().getValue(), f);
if (isAllowSameEpg(f)) {
count += 1;
}
}
- assertEquals(1, count);
- assertEquals(3, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
- .getFlow()
- .size());
- fm = dosync(flowMap);
- assertEquals(3, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+ assertEquals(sameEpgFlows, count);
+ int totalFlows = sameEpgFlows + allowTunnelFlows + dropAllFlow;
+ assertEquals(totalFlows, ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
.size());
}
- @Ignore
@Test
public void testDifferentEg() throws Exception {
- assertEquals(7, doTestDifferentEg(ImmutableList.of(baseSubject(null).build())));
- assertEquals(7, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build())));
- assertEquals(5, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build())));
- assertEquals(5, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build())));
+ int totalFlows = sameEpgFlows + allowTunnelFlows;
+ assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(null).build())));
+ // one layer4 flow for each direction
+ totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
+ assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build())));
+ totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
+ assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build())));
+ assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build())));
}
- @Ignore
@Test
public void doTestRule() throws Exception {
Rule rule1 = new RuleBuilder().setActionRef(
Direction.In)))
.build();
- assertEquals(5,
+ int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
+ assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1)))));
- assertEquals(11,
+ // one layer4 flow for each direction
+ totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
+ assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2)))));
- assertEquals(9,
+ // only one ether_type for out direction
+ totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + layer4flowsIPv6;
+ assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3)))));
- assertEquals(3,
+ totalFlows = sameEpgFlows + allowTunnelFlows;
+ assertEquals(totalFlows,
doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4)))));
}
private int doTestDifferentEg(List<Subject> subjects) 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);
- ctx.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy())
+ Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd)
+ .build();
+ endpointManagerMock.addEndpoint(ep1);
+ Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg2, bd)
+ .build();
+ endpointManagerMock.addEndpoint(ep2);
+ ctxMock.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy())
.setContract(ImmutableList.of(baseContract(subjects).build())).build()).build());
- OfWriter fm = dosync(null);
- assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+ ofWriter = new OfWriter();
+ table.sync(ep1, ofWriter);
+ assertTrue(!ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
- .size());
+ .isEmpty());
int count = 0;
- for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
+ for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
if (isAllowSameEpg(f)) {
count += 1;
} else if (f.getMatch() != null && Objects.equals(tunnelId, f.getMatch().getInPort())) {
return count;
}
- @Ignore
@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"))
+ Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd)
+ .setCondition(ImmutableList.of(cond1.getName())).build();
+ endpointManagerMock.addEndpoint(ep1);
+ Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg2, bd)
.setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))
- .setEndpointGroup(eg2)
.build();
- endpointManager.addEndpoint(ep2);
+ endpointManagerMock.addEndpoint(ep2);
TenantBuilder tb = baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy()).setContract(
ImmutableList.of(new ContractBuilder().setId(cid)
.build())).build())
.build()))
.build())).build());
- ctx.addTenant(tb.build());
+ ctxMock.addTenant(tb.build());
- PolicyInfo policy = ctx.getCurrentPolicy();
- List<ConditionName> ep1c = endpointManager.getConditionsForEndpoint(ep1);
+ PolicyInfo policy = ctxMock.getCurrentPolicy();
+ List<ConditionName> ep1c = endpointManagerMock.getConditionsForEndpoint(ep1);
ConditionGroup cg1 = policy.getEgCondGroup(new EgKey(tb.getId(), ep1.getEndpointGroup()), ep1c);
- List<ConditionName> ep2c = endpointManager.getConditionsForEndpoint(ep2);
+ List<ConditionName> ep2c = endpointManagerMock.getConditionsForEndpoint(ep2);
ConditionGroup cg2 = policy.getEgCondGroup(new EgKey(tb.getId(), ep2.getEndpointGroup()), ep2c);
int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);
int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);
RegMatch.of(NxmNxReg1.class, (long) cg1Id), RegMatch.of(NxmNxReg2.class, (long) eg2Id),
RegMatch.of(NxmNxReg3.class, (long) cg2Id));
int count = 0;
- OfWriter fm = dosync(null);
- assertEquals(7, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+ ofWriter = new OfWriter();
+ table.sync(ep1, ofWriter);
+ // one layer4 flow for each direction
+ int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow;;
+ assertEquals(totalFlows, ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
.getFlow()
.size());
HashMap<String, Flow> flowMap = new HashMap<>();
- for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
+ for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
flowMap.put(f.getId().getValue(), f);
if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null) {
count++;
}
}
- assertEquals(3, count);
- fm = dosync(flowMap);
- int numberOfFlows = fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
- .getFlow()
- .size();
- fm = dosync(flowMap);
- assertEquals(numberOfFlows, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
- .getFlow()
- .size());
+ //flows with ether_type match
+ totalFlows = layer4flowsIPv4 + layer4flowsIPv6 + arpFlows;
+ assertEquals(totalFlows, count);
}
private boolean isAllowSameEpg(Flow flow) {
return res;
}
- PolicyPair policyPair;
- int consumerEpgId;
- int providerEpgId;
- int consumerCondGrpId;
- int providerCondGrpId;
- Set<IpPrefix> consumerEicIpPrefixes;
- Set<IpPrefix> providerEicIpPrefixes;
- IpPrefix consumerEicIp;
- IpPrefix providerEicIp;
- NodeId consumerEpNodeId;
- NodeId providerEpNodeId;
-
- @Before
- public void PolicyPairInitialisation() {
- consumerEpgId = 5;
- providerEpgId = 8;
- consumerCondGrpId = 5;
- providerCondGrpId = 8;
- consumerEicIp = mock(IpPrefix.class);
- providerEicIp = mock(IpPrefix.class);
- consumerEicIpPrefixes = new HashSet<>(Collections.singletonList(consumerEicIp));
- providerEicIpPrefixes = new HashSet<>(Collections.singletonList(providerEicIp));
- consumerEpNodeId = mock(NodeId.class);
- when(consumerEpNodeId.getValue()).thenReturn("consumerValue");
- providerEpNodeId = mock(NodeId.class);
- when(providerEpNodeId.getValue()).thenReturn("providerValue");
+ protected ContractBuilder baseContract(List<Subject> subjects) {
+ ContractBuilder contractBuilder = new ContractBuilder().setId(cid).setSubject(subjects);
+ // TODO refactor
+ if (subjects == null) {
+ return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
+ .setSubjectRefs(ImmutableList.<SubjectName>of(new SubjectName("s1")))
+ .build()));
+ }
+ List<SubjectName> subjectNames = new ArrayList<>();
+ for (Subject subject : subjects) {
+ subjectNames.add(subject.getName());
+ }
+ return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
+ .setSubjectRefs(subjectNames)
+ .build()));
}
- @Test
- public void PolicyPairConstructorTest() {
- policyPair = new PolicyPair(consumerEpgId, providerEpgId, consumerCondGrpId, providerCondGrpId,
- consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId, providerEpNodeId);
- Assert.assertEquals(consumerEpgId, policyPair.getConsumerEpgId());
- Assert.assertEquals(providerEpgId, policyPair.getProviderEpgId());
- Assert.assertEquals(consumerEpNodeId, policyPair.getConsumerEpNodeId());
- Assert.assertEquals(providerEpNodeId, policyPair.getProviderEpNodeId());
- Assert.assertNotNull(policyPair.toString());
+ 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_dst_80"))
+ .setDirection(direction)
+ .setInstanceName(new ClassifierName("tcp_dst_80"))
+ .build()))
+ .build()));
}
- @Test
- public void PolicyPairEqualsTest() {
- policyPair = new PolicyPair(0, 0, 0, 0, null, null, null, null);
- PolicyPair other;
- other = new PolicyPair(0, 0, 0, 0, null, null, null, null);
- Assert.assertTrue(policyPair.equals(other));
-
- policyPair = new PolicyPair(consumerEpgId, providerEpgId, consumerCondGrpId, providerCondGrpId,
- consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId, providerEpNodeId);
-
- Assert.assertNotNull(policyPair);
- Assert.assertFalse(policyPair.equals(new Object()));
-
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 0, 0, 0, null, providerEicIpPrefixes, null, null);
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 0, 0, 0, consumerEicIpPrefixes, providerEicIpPrefixes, null, null);
- Assert.assertFalse(other.equals(policyPair));
-
- other = new PolicyPair(0, 0, 0, 0, consumerEicIpPrefixes, providerEicIpPrefixes, providerEpNodeId, null);
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 0, 0, 0, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId, null);
- Assert.assertFalse(other.equals(policyPair));
-
- other = new PolicyPair(0, 0, 0, 0, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- consumerEpNodeId);
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 0, 0, 0, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- providerEpNodeId);
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 0, 0, 8, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- providerEpNodeId);
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 8, 0, 8, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- providerEpNodeId);
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
-
- other = new PolicyPair(0, 8, 5, 8, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- providerEpNodeId);
- Assert.assertFalse(other.equals(policyPair));
- Assert.assertFalse(policyPair.equals(other));
+ protected Subject createSubject(String name, List<Rule> rules){
+ return new SubjectBuilder().setName(new SubjectName(name)).setRule(rules).build();
+ }
- other = new PolicyPair(5, 8, 5, 8, consumerEicIpPrefixes, providerEicIpPrefixes, consumerEpNodeId,
- providerEpNodeId);
- Assert.assertTrue(policyPair.equals(other));
+ protected List<ClassifierRef> createClassifierRefs(Map<String, Direction> refNamesAndDirections) {
+ List<ClassifierRef> refs = new ArrayList<>();
+ for (String refName : refNamesAndDirections.keySet()) {
+ refs.add(new ClassifierRefBuilder().setName(new ClassifierName(refName))
+ .setDirection(refNamesAndDirections.get(refName))
+ .setInstanceName(new ClassifierName(refName))
+ .build());
+ }
+ return refs;
}
}
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.NetworkElements;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.PolicyEnforcer.PolicyPair;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ChainAction.class)
public class ChainActionTest {
private ChainAction chainAction;
private NodeId nodeId;
private EndpointFwdCtxOrdinals endpointFwdCtxOrdinals;
private Endpoint endpoint;
- private PolicyPair policyPair;
private EndpointManager endpointManager;
private EgKey egKey;
private TenantId tenant = new TenantId("e09a2308-6ffa-40af-92a2-69f54b2cf3e4");
@SuppressWarnings("unchecked")
@Before
public void initialise() throws Exception {
- chainAction = spy(new ChainAction());
+ chainAction = new ChainAction();
sfcPath = mock(ServiceFunctionPath.class);
when(sfcPath.getName()).thenReturn(new SfpName("sfcPathName"));
endpoint = mock(Endpoint.class);
when(netElements.getSrcEp()).thenReturn(endpoint);
when(netElements.getSrcEp().getTenant()).thenReturn(tenant);
- policyPair = mock(PolicyPair.class);
- when(policyPair.getConsumerEpgId()).thenReturn(Integer.valueOf(5));
endpointManager = mock(EndpointManager.class);
when(ctx.getEndpointManager()).thenReturn(endpointManager);
Integer order = Integer.valueOf(0);
OfWriter ofWriter = mock(OfWriter.class);
- doReturn(sfcPath).when(chainAction).getSfcPath(new SfcName(chainName));
+ PowerMockito.mockStatic(ChainAction.class);
+ when(ChainAction.getSfcPath(new SfcName(chainName))).thenReturn(sfcPath);
+ chainAction.setResolvedSymmetricChains(Collections.singletonList(chainName));
List<ActionBuilder> result =
- chainAction.updateAction(actions, params, order, netElements, policyPair, ofWriter, ctx, Direction.Out);
+ chainAction.updateAction(actions, params, order, netElements, ofWriter, ctx, Direction.Out);
Assert.assertNull(result);
}
OfWriter ofWriter = mock(OfWriter.class);
List<ActionBuilder> result =
- chainAction.updateAction(actions, null, order, netElements, policyPair, ofWriter, ctx, Direction.In);
+ chainAction.updateAction(actions, null, order, netElements, ofWriter, ctx, Direction.In);
Assert.assertNull(result);
}
params.put(ChainActionDefinition.SFC_CHAIN_NAME, null);
Integer order = Integer.valueOf(0);
NetworkElements netElements = mock(NetworkElements.class);
- PolicyPair policyPair = mock(PolicyPair.class);
OfWriter ofWriter = mock(OfWriter.class);
- chainAction.updateAction(actions, params, order, netElements, policyPair, ofWriter, ctx, Direction.In);
+ List<ActionBuilder> result =
+ chainAction.updateAction(actions, params, order, netElements, ofWriter, ctx, Direction.In);
+
+ Assert.assertNull(result);
}
@Test
Integer order = Integer.valueOf(0);
OfWriter ofWriter = mock(OfWriter.class);
- doReturn(sfcPath).when(chainAction).getSfcPath(new SfcName(chainName));
+ PowerMockito.mockStatic(ChainAction.class);
+ when(ChainAction.getSfcPath(new SfcName(chainName))).thenReturn(sfcPath);
when(sfcPath.getName()).thenReturn(null);
List<ActionBuilder> result =
- chainAction.updateAction(actions, params, order, netElements, policyPair, ofWriter, ctx, Direction.Out);
+ chainAction.updateAction(actions, params, order, netElements, ofWriter, ctx, Direction.Out);
Assert.assertNull(result);
}