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.listeners;
11 import com.google.common.base.Optional;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
16 import javax.annotation.PostConstruct;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
23 import org.opendaylight.genius.mdsalutil.NwConstants;
24 import org.opendaylight.netvirt.policyservice.PolicyAceFlowProgrammer;
25 import org.opendaylight.netvirt.policyservice.PolicyIdManager;
26 import org.opendaylight.netvirt.policyservice.PolicyRouteFlowProgrammer;
27 import org.opendaylight.netvirt.policyservice.PolicyRouteGroupProgrammer;
28 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyProfiles;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.PolicyProfile;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.PolicyAclRule;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.acl.rule.AceRule;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Listen on {@link PolicyProfile} config changes and update the policy pipeline
40 * whenever the association between policy classifier and underlay networks
42 * This listener will update the following flows/groups:<br>
43 * * POLICY_CLASSIFER_TABLE policy ACL flows when policy classifier
45 * * POLICY_ROUTING_TABLE flows when policy classifier added/removed<br>
46 * * Policy classifier groups for each remote DPN is updated when policy
47 * classifier added/removed or when the list of associated underlay networks is
50 @SuppressWarnings("deprecation")
52 public class PolicyProfileChangeListener
53 extends AsyncDataTreeChangeListenerBase<PolicyProfile, PolicyProfileChangeListener> {
54 private static final Logger LOG = LoggerFactory.getLogger(PolicyProfileChangeListener.class);
56 private final DataBroker dataBroker;
57 private final PolicyIdManager policyIdManager;
58 private final PolicyServiceUtil policyServiceUtil;
59 private final PolicyAceFlowProgrammer aceFlowProgrammer;
60 private final PolicyRouteFlowProgrammer routeFlowProgrammer;
61 private final PolicyRouteGroupProgrammer routeGroupProgramer;
64 public PolicyProfileChangeListener(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
65 final PolicyServiceUtil policyServiceUtil, final PolicyAceFlowProgrammer aceFlowProgrammer,
66 final PolicyRouteFlowProgrammer routeFlowProgrammer, final PolicyRouteGroupProgrammer routeGroupProgramer) {
67 this.dataBroker = dataBroker;
68 this.policyIdManager = policyIdManager;
69 this.policyServiceUtil = policyServiceUtil;
70 this.aceFlowProgrammer = aceFlowProgrammer;
71 this.routeFlowProgrammer = routeFlowProgrammer;
72 this.routeGroupProgramer = routeGroupProgramer;
79 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
83 protected InstanceIdentifier<PolicyProfile> getWildCardPath() {
84 return InstanceIdentifier.create(PolicyProfiles.class).child(PolicyProfile.class);
88 protected PolicyProfileChangeListener getDataTreeChangeListener() {
93 protected void remove(InstanceIdentifier<PolicyProfile> key, PolicyProfile policyProfile) {
94 String policyClassifier = policyProfile.getPolicyClassifier();
95 LOG.info("Policy profile {} removed", policyClassifier);
96 List<String> underlayNetworks = PolicyServiceUtil
97 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
98 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, false);
99 List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
100 List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
101 routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.DEL_FLOW);
102 updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.DEL_FLOW);
103 routeFlowProgrammer.programPolicyClassifierFlows(policyClassifier, dpnIds, remoteDpIds, NwConstants.DEL_FLOW);
104 policyIdManager.releasePolicyClassifierId(policyClassifier);
105 releasePolicyClassifierGroupIds(policyClassifier, dpnIds);
109 protected void update(InstanceIdentifier<PolicyProfile> key, PolicyProfile origPolicyProfile,
110 PolicyProfile updatedPolicyProfile) {
111 List<String> origUnderlayNetworks = PolicyServiceUtil
112 .getUnderlayNetworksFromPolicyRoutes(origPolicyProfile.getPolicyRoute());
113 List<String> updatedUnderlayNetworks = PolicyServiceUtil
114 .getUnderlayNetworksFromPolicyRoutes(updatedPolicyProfile.getPolicyRoute());
115 List<String> removedUnderlayNetworks = new ArrayList<>(origUnderlayNetworks);
116 removedUnderlayNetworks.removeAll(updatedUnderlayNetworks);
117 List<String> addedUnderlayNetworks = new ArrayList<>(updatedUnderlayNetworks);
118 addedUnderlayNetworks.removeAll(origUnderlayNetworks);
120 String policyClassifier = updatedPolicyProfile.getPolicyClassifier();
121 LOG.info("Policy profile {} updated", policyClassifier);
122 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(removedUnderlayNetworks, policyClassifier, false);
123 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(addedUnderlayNetworks, policyClassifier, true);
125 // rewrite all group buckets
126 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, origUnderlayNetworks,
127 NwConstants.DEL_FLOW);
128 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, updatedUnderlayNetworks,
129 NwConstants.ADD_FLOW);
131 updatedUnderlayNetworks.removeAll(origUnderlayNetworks);
132 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(updatedUnderlayNetworks,
133 updatedPolicyProfile.getPolicyClassifier(), true);
134 updatePolicyAclRules(policyClassifier, updatedUnderlayNetworks, NwConstants.ADD_FLOW);
138 protected void add(InstanceIdentifier<PolicyProfile> key, PolicyProfile policyProfile) {
139 String policyClassifier = policyProfile.getPolicyClassifier();
140 LOG.info("Policy profile {} added", policyClassifier);
141 List<String> underlayNetworks = PolicyServiceUtil
142 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
143 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, true);
144 List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
145 List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
146 routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.ADD_FLOW);
147 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, underlayNetworks,
148 NwConstants.ADD_FLOW);
149 updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.ADD_FLOW);
150 routeFlowProgrammer.programPolicyClassifierFlows(policyClassifier, dpnIds, remoteDpIds, NwConstants.ADD_FLOW);
153 private void updatePolicyAclRules(String policyClassifier, List<String> underlayNetworks, int addOrRemove) {
154 List<PolicyAclRule> aclRules = policyServiceUtil.getPolicyClassifierAclRules(policyClassifier);
155 if (aclRules == null || aclRules.isEmpty()) {
156 LOG.debug("No policy ACE rules found for policy classifier {}", policyClassifier);
160 List<BigInteger> dpIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
161 if (dpIds == null || dpIds.isEmpty()) {
162 LOG.debug("No DPNs found for installation of underlay networks {}", underlayNetworks);
166 aclRules.forEach(aclRule -> {
167 List<AceRule> aceRules = aclRule.getAceRule();
168 if (aceRules != null) {
169 aceRules.forEach(aceRule -> {
170 Optional<Ace> policyAceOpt =
171 policyServiceUtil.getPolicyAce(aclRule.getAclName(), aceRule.getRuleName());
172 if (policyAceOpt.isPresent()) {
173 aceFlowProgrammer.programAceFlows(policyAceOpt.get(), policyClassifier, dpIds,
178 LOG.debug("No ACE rules found for ACL {}", aclRule.getAclName());
183 private void releasePolicyClassifierGroupIds(String policyClassifier, List<BigInteger> dpnIds) {
184 dpnIds.forEach(dpnId -> {
185 policyIdManager.releasePolicyClassifierGroupId(policyClassifier, dpnId);