2 * Copyright (c) 2017 Hewlett Packard Enterprise, Co. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.policyservice;
11 import com.google.common.base.Optional;
12 import java.math.BigInteger;
13 import java.util.Collections;
14 import java.util.List;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.genius.mdsalutil.InstructionInfo;
20 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
21 import org.opendaylight.genius.mdsalutil.NwConstants;
22 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
23 import org.opendaylight.netvirt.policyservice.util.PolicyServiceFlowUtil;
24 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Program POLICY_ROUTING_TABLE flows. Each flow is composed from<br>
31 * * OF matches - logical tunnel lport tag and policy classifier metadata
33 * * OF actions - set policy classifier group id based on the remote DPN
34 * associated with the logical tunnel.
37 @SuppressWarnings("deprecation")
39 public class PolicyRouteFlowProgrammer {
40 private static final Logger LOG = LoggerFactory.getLogger(PolicyRouteFlowProgrammer.class);
42 private final DataBroker dataBroker;
43 private final PolicyIdManager policyIdManager;
44 private final PolicyServiceUtil policyServiceUtil;
45 private final PolicyServiceFlowUtil policyFlowUtil;
46 private final JobCoordinator coordinator;
49 public PolicyRouteFlowProgrammer(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
50 final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyFlowUtil,
51 final JobCoordinator coordinator) {
52 this.dataBroker = dataBroker;
53 this.policyIdManager = policyIdManager;
54 this.policyServiceUtil = policyServiceUtil;
55 this.policyFlowUtil = policyFlowUtil;
56 this.coordinator = coordinator;
59 public void programPolicyClassifierFlows(String policyClassifierName, List<BigInteger> localDpIds,
60 List<BigInteger> remoteDpIds, int addOrRemove) {
61 long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
62 if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
63 LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
67 coordinator.enqueueJob(policyClassifierName, () -> {
68 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
69 remoteDpIds.forEach(remoteDpId -> {
70 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
71 if (groupId != PolicyServiceConstants.INVALID_ID) {
72 List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
73 localDpIds.forEach(localDpId -> {
74 if (!remoteDpId.equals(localDpId)) {
75 programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions,
76 localDpId, remoteDpId, tx, addOrRemove);
80 LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName,
84 return Collections.singletonList(tx.submit());
89 public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
91 programPolicyClassifierFlow(policyClassifierName, localDpId, remoteDpId, addOrRemove, false);
94 public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
95 int addOrRemove, boolean createIfMissing) {
96 long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
97 if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
98 LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
102 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
103 if (groupId == PolicyServiceConstants.INVALID_ID) {
104 LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName, remoteDpId);
108 if (addOrRemove == NwConstants.ADD_FLOW && createIfMissing) {
109 addPolicyClassifierGroup(policyClassifierName, localDpId, remoteDpId, addOrRemove, groupId);
112 List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
113 coordinator.enqueueJob(policyClassifierName, () -> {
114 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
115 programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions, localDpId, remoteDpId,
117 return Collections.singletonList(tx.submit());
122 private void programPolicyClassifierFlow(String policyClassifierName, long policyClassifierId,
123 List<InstructionInfo> instructions, BigInteger localDpId, BigInteger remoteDpId, WriteTransaction tx,
125 Optional<Integer> lportTagOpt = policyServiceUtil.getLogicalTunnelLportTag(localDpId, remoteDpId);
126 if (!lportTagOpt.isPresent()) {
127 LOG.debug("Missing lport-tag for policy classifier {} logical tunnel for source DPN {} dst DPN {}",
128 policyClassifierName, localDpId, remoteDpId);
132 List<MatchInfoBase> matches = policyFlowUtil.getPolicyRouteMatches(policyClassifierId, lportTagOpt.get());
133 LOG.debug("{} policy classifier {} route on source DPN {} dest DPN {}",
134 addOrRemove == NwConstants.ADD_FLOW ? "Installing" : "Removing", policyClassifierName, localDpId,
136 policyFlowUtil.updateFlowToTx(localDpId, NwConstants.EGRESS_POLICY_ROUTING_TABLE,
137 PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId),
138 PolicyServiceConstants.POLICY_FLOW_PRIOPITY, NwConstants.EGRESS_POLICY_ROUTING_COOKIE, matches,
139 instructions, addOrRemove, tx);
142 private void addPolicyClassifierGroup(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
143 int addOrRemove, long groupId) {
144 coordinator.enqueueJob(policyClassifierName, () -> {
145 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
146 policyFlowUtil.updateGroupToTx(localDpId, groupId,
147 PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId), GroupTypes.GroupFf,
149 return Collections.singletonList(tx.submit());