/* * Copyright (c) 2017 Hewlett Packard Enterprise, Co. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.netvirt.policyservice; import com.google.common.base.Optional; import java.math.BigInteger; import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator; import org.opendaylight.genius.mdsalutil.InstructionInfo; import org.opendaylight.genius.mdsalutil.MatchInfoBase; import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.netvirt.aclservice.api.utils.IAclServiceUtil; import org.opendaylight.netvirt.policyservice.util.PolicyServiceFlowUtil; import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Program POLICY_CLASSIFER_TABLE flows. Each flow is composed from
* * OF matches - translated from set of {@link Ace} matches
* * OF actions - set policy classifier bits in the metadata and goto * POLICY_ROUTING_TABLE * */ @Singleton public class PolicyAceFlowProgrammer { private static final Logger LOG = LoggerFactory.getLogger(PolicyAceFlowProgrammer.class); private final DataBroker dataBroker; private final IAclServiceUtil aclServiceUtil; private final PolicyIdManager policyIdManager; private final PolicyServiceUtil policyServiceUtil; private final PolicyServiceFlowUtil policyFlowUtil; private final DataStoreJobCoordinator coordinator; @Inject public PolicyAceFlowProgrammer(final DataBroker dataBroker, final IAclServiceUtil aclServiceUtil, final PolicyIdManager policyIdManager, final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyFlowUtil) { this.dataBroker = dataBroker; this.aclServiceUtil = aclServiceUtil; this.policyIdManager = policyIdManager; this.policyServiceUtil = policyServiceUtil; this.policyFlowUtil = policyFlowUtil; this.coordinator = DataStoreJobCoordinator.getInstance(); } public void programAceFlows(Ace ace, BigInteger dpId, int addOrRemove) { Optional policyClassifierOpt = policyServiceUtil.getAcePolicyClassifier(ace); if (!policyClassifierOpt.isPresent()) { LOG.debug("No egress policy classifier found for ACE rule {}", ace.getRuleName()); return; } List instructions = (addOrRemove == NwConstants.ADD_FLOW) ? getPolicyClassifierInstructions(policyClassifierOpt.get()) : null; programAceFlows(ace, instructions, dpId, addOrRemove); } public void programAceFlows(Ace ace, String policyClassifierName, List dpIds, int addOrRemove) { List instructions = (addOrRemove == NwConstants.ADD_FLOW) ? getPolicyClassifierInstructions(policyClassifierName) : null; dpIds.forEach(dpId -> { programAceFlows(ace, instructions, dpId, addOrRemove); }); } private void programAceFlows(Ace ace, List instructions, BigInteger dpId, int addOrRemove) { Map> flowMap = aclServiceUtil.programIpFlow(ace.getMatches()); if (flowMap == null) { LOG.error("Failed to create flows for ACE rule {}", ace.getRuleName()); return; } coordinator.enqueueJob(ace.getRuleName(), () -> { WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); flowMap.forEach((flowName, matches) -> { String policyFlowName = "Policy_" + flowName; LOG.debug("{} ACE rule {} on DPN {} flow {}", addOrRemove == NwConstants.ADD_FLOW ? "Installing" : "Removing", ace.getRuleName(), dpId, policyFlowName); policyFlowUtil.updateFlowToTx(dpId, NwConstants.EGRESS_POLICY_CLASSIFIER_TABLE, policyFlowName, PolicyServiceConstants.POLICY_FLOW_PRIOPITY, NwConstants.EGRESS_POLICY_CLASSIFIER_COOKIE, matches, instructions, addOrRemove, tx); }); return Collections.singletonList(tx.submit()); }); } private List getPolicyClassifierInstructions(String policyClassifierName) { long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName); if (policyClassifierId == PolicyServiceConstants.INVALID_ID) { LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName); return Collections.emptyList(); } return policyFlowUtil.getPolicyClassifierInstructions(policyClassifierId); } // TODO table miss flow }