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 java.math.BigInteger;
12 import java.util.Collections;
13 import java.util.List;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
19 import org.opendaylight.netvirt.policyservice.util.PolicyServiceFlowUtil;
20 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterface;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Program policy classifier fast-failover groups per remote DPN.<br>
29 * Group id is allocated for combination of policy classifier and DPN id.<br>
30 * The group buckets are built based on the underlay networks defined for the
31 * policy classifier.<br>
32 * Each bucket in the group contains the tunnel egress actions for the actual
33 * tunnel interface associated with the underlay network.
37 public class PolicyRouteGroupProgrammer {
38 private static final Logger LOG = LoggerFactory.getLogger(PolicyRouteGroupProgrammer.class);
40 private final DataBroker dataBroker;
41 private final PolicyIdManager policyIdManager;
42 private final PolicyServiceUtil policyServiceUtil;
43 private final PolicyServiceFlowUtil policyServiceFlowUtil;
44 private final JobCoordinator coordinator;
47 public PolicyRouteGroupProgrammer(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
48 final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyServiceFlowUtil,
49 final JobCoordinator coordinator) {
50 this.dataBroker = dataBroker;
51 this.policyIdManager = policyIdManager;
52 this.policyServiceUtil = policyServiceUtil;
53 this.policyServiceFlowUtil = policyServiceFlowUtil;
54 this.coordinator = coordinator;
57 public void programPolicyClassifierGroups(String policyClassifier, List<BigInteger> localDpIds,
58 List<BigInteger> remoteDpIds, int addOrRemove) {
59 if (remoteDpIds == null || remoteDpIds.isEmpty()) {
60 LOG.debug("No remote DPNs found for policy classifier {}", policyClassifier);
64 coordinator.enqueueJob(policyClassifier, () -> {
65 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
67 remoteDpId -> programPolicyClassifierGroups(policyClassifier, localDpIds, remoteDpId, tx,
69 return Collections.singletonList(tx.submit());
73 public void programPolicyClassifierGroups(String policyClassifier, BigInteger dpId,
74 List<TunnelInterface> tunnelInterfaces, int addOrRemove) {
75 if (tunnelInterfaces == null) {
76 LOG.debug("No tunnel interfaces found for policy classifier {} DPN {}", policyClassifier, dpId);
80 coordinator.enqueueJob(policyClassifier, () -> {
81 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
82 tunnelInterfaces.forEach(tunnelInterface -> {
83 BigInteger remoteDpId = tunnelInterface.getRemoteDpId();
84 programPolicyClassifierGroups(policyClassifier, Collections.singletonList(dpId), remoteDpId, tx,
87 return Collections.singletonList(tx.submit());
91 private void programPolicyClassifierGroups(String policyClassifier, List<BigInteger> localDpIds,
92 BigInteger remoteDpId, WriteTransaction tx, int addOrRemove) {
93 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifier, remoteDpId);
94 if (groupId == PolicyServiceConstants.INVALID_ID) {
95 LOG.error("Failed to get group id for policy classifier {}", policyClassifier);
99 if (localDpIds == null || localDpIds.isEmpty()) {
100 LOG.debug("No DPNs found for policy classifier {}", policyClassifier);
104 String groupName = PolicyIdManager.getPolicyClassifierGroupKey(policyClassifier, remoteDpId);
105 localDpIds.forEach(srcDpId -> {
106 if (!remoteDpId.equals(srcDpId)) {
107 policyServiceFlowUtil.updateGroupToTx(srcDpId, groupId, groupName, GroupTypes.GroupFf, addOrRemove, tx);
112 public void programPolicyClassifierGroupBuckets(String policyClassifier, List<String> underlayNetworks,
114 if (underlayNetworks == null) {
118 coordinator.enqueueJob(policyClassifier, () -> {
119 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
121 for (int idx = 0; idx < underlayNetworks.size(); idx++) {
122 final int bucketId = idx;
123 String underlayNetwork = underlayNetworks.get(idx);
124 List<DpnToInterface> dpnToInterfaceList =
125 policyServiceUtil.getUnderlayNetworkDpnToInterfaces(underlayNetwork);
126 dpnToInterfaceList.forEach(dpnToInterface -> {
127 BigInteger dpId = dpnToInterface.getDpId();
128 List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
129 programPolicyClassifierGroupBuckets(policyClassifier, tunnelInterfaces, dpId, bucketId,
133 return Collections.singletonList(tx.submit());
137 public void programPolicyClassifierGroupBuckets(String policyClassifier, List<TunnelInterface> tunnelInterfaces,
138 BigInteger dpId, int bucketId, int addOrRemove) {
139 coordinator.enqueueJob(policyClassifier, () -> {
140 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
141 programPolicyClassifierGroupBuckets(policyClassifier, tunnelInterfaces, dpId, bucketId, addOrRemove, tx);
142 return Collections.singletonList(tx.submit());
146 private void programPolicyClassifierGroupBuckets(String policyClassifier, List<TunnelInterface> tunnelInterfaces,
147 BigInteger dpId, int bucketId, int addOrRemove, WriteTransaction tx) {
148 if (tunnelInterfaces == null) {
149 LOG.debug("No tunnel interfaces found for policy classifier {} DPN {}", policyClassifier, dpId);
153 tunnelInterfaces.forEach(tunnelInterface -> {
154 String interfaceName = tunnelInterface.getInterfaceName();
155 BigInteger remoteDpId = tunnelInterface.getRemoteDpId();
156 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifier, remoteDpId);
157 policyServiceFlowUtil.updateInterfaceBucketToTx(dpId, groupId, bucketId, interfaceName, addOrRemove, tx);