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.
38 public class PolicyRouteFlowProgrammer {
39 private static final Logger LOG = LoggerFactory.getLogger(PolicyRouteFlowProgrammer.class);
41 private final DataBroker dataBroker;
42 private final PolicyIdManager policyIdManager;
43 private final PolicyServiceUtil policyServiceUtil;
44 private final PolicyServiceFlowUtil policyFlowUtil;
45 private final JobCoordinator coordinator;
48 public PolicyRouteFlowProgrammer(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
49 final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyFlowUtil,
50 final JobCoordinator coordinator) {
51 this.dataBroker = dataBroker;
52 this.policyIdManager = policyIdManager;
53 this.policyServiceUtil = policyServiceUtil;
54 this.policyFlowUtil = policyFlowUtil;
55 this.coordinator = coordinator;
58 public void programPolicyClassifierFlows(String policyClassifierName, List<BigInteger> localDpIds,
59 List<BigInteger> remoteDpIds, int addOrRemove) {
60 long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
61 if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
62 LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
66 coordinator.enqueueJob(policyClassifierName, () -> {
67 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
68 remoteDpIds.forEach(remoteDpId -> {
69 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
70 if (groupId != PolicyServiceConstants.INVALID_ID) {
71 List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
72 localDpIds.forEach(localDpId -> {
73 if (!remoteDpId.equals(localDpId)) {
74 programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions,
75 localDpId, remoteDpId, tx, addOrRemove);
79 LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName,
83 return Collections.singletonList(tx.submit());
88 public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
90 programPolicyClassifierFlow(policyClassifierName, localDpId, remoteDpId, addOrRemove, false);
93 public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
94 int addOrRemove, boolean createIfMissing) {
95 long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
96 if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
97 LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
101 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
102 if (groupId == PolicyServiceConstants.INVALID_ID) {
103 LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName, remoteDpId);
107 if (addOrRemove == NwConstants.ADD_FLOW && createIfMissing) {
108 addPolicyClassifierGroup(policyClassifierName, localDpId, remoteDpId, addOrRemove, groupId);
111 List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
112 coordinator.enqueueJob(policyClassifierName, () -> {
113 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
114 programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions, localDpId, remoteDpId,
116 return Collections.singletonList(tx.submit());
121 private void programPolicyClassifierFlow(String policyClassifierName, long policyClassifierId,
122 List<InstructionInfo> instructions, BigInteger localDpId, BigInteger remoteDpId, WriteTransaction tx,
124 Optional<Integer> lportTagOpt = policyServiceUtil.getLogicalTunnelLportTag(localDpId, remoteDpId);
125 if (!lportTagOpt.isPresent()) {
126 LOG.debug("Missing lport-tag for policy classifier {} logical tunnel for source DPN {} dst DPN {}",
127 policyClassifierName, localDpId, remoteDpId);
131 List<MatchInfoBase> matches = policyFlowUtil.getPolicyRouteMatches(policyClassifierId, lportTagOpt.get());
132 LOG.debug("{} policy classifier {} route on source DPN {} dest DPN {}",
133 addOrRemove == NwConstants.ADD_FLOW ? "Installing" : "Removing", policyClassifierName, localDpId,
135 policyFlowUtil.updateFlowToTx(localDpId, NwConstants.EGRESS_POLICY_ROUTING_TABLE,
136 PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId),
137 PolicyServiceConstants.POLICY_FLOW_PRIOPITY, NwConstants.EGRESS_POLICY_ROUTING_COOKIE, matches,
138 instructions, addOrRemove, tx);
141 private void addPolicyClassifierGroup(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
142 int addOrRemove, long groupId) {
143 coordinator.enqueueJob(policyClassifierName, () -> {
144 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
145 policyFlowUtil.updateGroupToTx(localDpId, groupId,
146 PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId), GroupTypes.GroupFf,
148 return Collections.singletonList(tx.submit());