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;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IetfModelCodec;
import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServiceChainAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
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.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
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.common.rev140421.ParameterName;
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);
RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0);
RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop());
- SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(rspFirstHop.getIp().getIpv4Address())
- .setNshTunUdpPort(rspFirstHop.getPort())
+ SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address()))
+ .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort()))
.setNshNsiToChain(firstRspHop.getServiceIndex())
.setNshNspToChain(renderedServicePath.getPathId())
.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 path;
+ if (paths != null) {
+ for (ServiceFunctionPath path : paths.getServiceFunctionPath()) {
+ if (path.getServiceChainName().equals(chainName)) {
+ return path;
+ }
}
}
return null;
return ImmutableList.<SupportedParameterValues>of(new SupportedParameterValuesBuilder()
.setParameterName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME)).build());
}
-
}