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;
15 import javax.annotation.PostConstruct;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.mdsalutil.NwConstants;
22 import org.opendaylight.netvirt.policyservice.PolicyAceFlowProgrammer;
23 import org.opendaylight.netvirt.policyservice.PolicyIdManager;
24 import org.opendaylight.netvirt.policyservice.PolicyRouteFlowProgrammer;
25 import org.opendaylight.netvirt.policyservice.PolicyRouteGroupProgrammer;
26 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyProfiles;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.PolicyProfile;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.PolicyAclRule;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.acl.rule.AceRule;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * Listen on {@link PolicyProfile} config changes and update the policy pipeline
38 * whenever the association between policy classifier and underlay networks
40 * This listener will update the following flows/groups:<br>
41 * * POLICY_CLASSIFER_TABLE policy ACL flows when policy classifier
43 * * POLICY_ROUTING_TABLE flows when policy classifier added/removed<br>
44 * * Policy classifier groups for each remote DPN is updated when policy
45 * classifier added/removed or when the list of associated underlay networks is
49 public class PolicyProfileChangeListener
50 extends AsyncDataTreeChangeListenerBase<PolicyProfile, PolicyProfileChangeListener> {
51 private static final Logger LOG = LoggerFactory.getLogger(PolicyProfileChangeListener.class);
53 private final DataBroker dataBroker;
54 private final PolicyIdManager policyIdManager;
55 private final PolicyServiceUtil policyServiceUtil;
56 private final PolicyAceFlowProgrammer aceFlowProgrammer;
57 private final PolicyRouteFlowProgrammer routeFlowProgrammer;
58 private final PolicyRouteGroupProgrammer routeGroupProgramer;
61 public PolicyProfileChangeListener(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
62 final PolicyServiceUtil policyServiceUtil, final PolicyAceFlowProgrammer aceFlowProgrammer,
63 final PolicyRouteFlowProgrammer routeFlowProgrammer, final PolicyRouteGroupProgrammer routeGroupProgramer) {
64 this.dataBroker = dataBroker;
65 this.policyIdManager = policyIdManager;
66 this.policyServiceUtil = policyServiceUtil;
67 this.aceFlowProgrammer = aceFlowProgrammer;
68 this.routeFlowProgrammer = routeFlowProgrammer;
69 this.routeGroupProgramer = routeGroupProgramer;
76 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
80 protected InstanceIdentifier<PolicyProfile> getWildCardPath() {
81 return InstanceIdentifier.create(PolicyProfiles.class).child(PolicyProfile.class);
85 protected PolicyProfileChangeListener getDataTreeChangeListener() {
90 protected void remove(InstanceIdentifier<PolicyProfile> key, PolicyProfile policyProfile) {
91 String policyClassifier = policyProfile.getPolicyClassifier();
92 LOG.info("Policy profile {} removed", policyClassifier);
93 List<String> underlayNetworks = PolicyServiceUtil
94 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
95 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, false);
96 List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
97 List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
98 routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.DEL_FLOW);
99 updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.DEL_FLOW);
100 routeFlowProgrammer.programPolicyClassifierFlows(policyClassifier, dpnIds, remoteDpIds, NwConstants.DEL_FLOW);
101 policyIdManager.releasePolicyClassifierId(policyClassifier);
102 releasePolicyClassifierGroupIds(policyClassifier, dpnIds);
106 protected void update(InstanceIdentifier<PolicyProfile> key, PolicyProfile origPolicyProfile,
107 PolicyProfile updatedPolicyProfile) {
108 List<String> origUnderlayNetworks = PolicyServiceUtil
109 .getUnderlayNetworksFromPolicyRoutes(origPolicyProfile.getPolicyRoute());
110 List<String> updatedUnderlayNetworks = PolicyServiceUtil
111 .getUnderlayNetworksFromPolicyRoutes(updatedPolicyProfile.getPolicyRoute());
112 List<String> removedUnderlayNetworks = new ArrayList<>(origUnderlayNetworks);
113 removedUnderlayNetworks.removeAll(updatedUnderlayNetworks);
114 List<String> addedUnderlayNetworks = new ArrayList<>(updatedUnderlayNetworks);
115 addedUnderlayNetworks.removeAll(origUnderlayNetworks);
117 String policyClassifier = updatedPolicyProfile.getPolicyClassifier();
118 LOG.info("Policy profile {} updated", policyClassifier);
119 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(removedUnderlayNetworks, policyClassifier, false);
120 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(addedUnderlayNetworks, policyClassifier, true);
122 // rewrite all group buckets
123 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, origUnderlayNetworks,
124 NwConstants.DEL_FLOW);
125 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, updatedUnderlayNetworks,
126 NwConstants.ADD_FLOW);
128 updatedUnderlayNetworks.removeAll(origUnderlayNetworks);
129 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(updatedUnderlayNetworks,
130 updatedPolicyProfile.getPolicyClassifier(), true);
131 updatePolicyAclRules(policyClassifier, updatedUnderlayNetworks, NwConstants.ADD_FLOW);
135 protected void add(InstanceIdentifier<PolicyProfile> key, PolicyProfile policyProfile) {
136 String policyClassifier = policyProfile.getPolicyClassifier();
137 LOG.info("Policy profile {} added", policyClassifier);
138 List<String> underlayNetworks = PolicyServiceUtil
139 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
140 policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, true);
141 List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
142 List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
143 routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.ADD_FLOW);
144 routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, underlayNetworks,
145 NwConstants.ADD_FLOW);
146 updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.ADD_FLOW);
147 routeFlowProgrammer.programPolicyClassifierFlows(policyClassifier, dpnIds, remoteDpIds, NwConstants.ADD_FLOW);
150 private void updatePolicyAclRules(String policyClassifier, List<String> underlayNetworks, int addOrRemove) {
151 List<PolicyAclRule> aclRules = policyServiceUtil.getPolicyClassifierAclRules(policyClassifier);
152 if (aclRules == null || aclRules.isEmpty()) {
153 LOG.debug("No policy ACE rules found for policy classifier {}", policyClassifier);
157 List<BigInteger> dpIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
158 if (dpIds == null || dpIds.isEmpty()) {
159 LOG.debug("No DPNs found for installation of underlay networks {}", underlayNetworks);
163 aclRules.forEach(aclRule -> {
164 List<AceRule> aceRules = aclRule.getAceRule();
165 if (aceRules != null) {
166 aceRules.forEach(aceRule -> {
167 Optional<Ace> policyAceOpt =
168 policyServiceUtil.getPolicyAce(aclRule.getAclName(), aceRule.getRuleName());
169 if (policyAceOpt.isPresent()) {
170 aceFlowProgrammer.programAceFlows(policyAceOpt.get(), policyClassifier, dpIds,
175 LOG.debug("No ACE rules found for ACL {}", aclRule.getAclName());
180 private void releasePolicyClassifierGroupIds(String policyClassifier, List<BigInteger> dpnIds) {
181 dpnIds.forEach(dpnId -> policyIdManager.releasePolicyClassifierGroupId(policyClassifier, dpnId));