Route Constrain policies
[bgpcep.git] / bgp / openconfig-rp-spi / src / main / java / org / opendaylight / protocol / bgp / openconfig / routing / policy / spi / registry / BgpConditionsRegistry.java
1 /*
2  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry;
9
10 import com.google.common.base.Preconditions;
11 import java.util.HashMap;
12 import java.util.Map;
13 import javax.annotation.concurrent.GuardedBy;
14 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.RouteEntryBaseAttributes;
15 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.policy.condition.BgpConditionsAugmentationPolicy;
16 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.policy.condition.BgpConditionsPolicy;
17 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryExportParameters;
18 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
19 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.BgpMatchConditions;
20 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.Conditions1;
21 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.bgp.match.conditions.MatchAsPathSet;
22 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.bgp.match.conditions.MatchCommunitySet;
23 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.bgp.match.conditions.MatchExtCommunitySet;
24 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.routing.policy.policy.definitions.policy.definition.statements.statement.conditions.BgpConditions;
25 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
26 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Conditions;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
28 import org.opendaylight.yangtools.concepts.AbstractRegistration;
29 import org.opendaylight.yangtools.yang.binding.Augmentation;
30 import org.opendaylight.yangtools.yang.binding.ChildOf;
31 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
32
33 final class BgpConditionsRegistry {
34     @GuardedBy("this")
35     private final Map<Class<? extends Augmentation<BgpConditions>>,
36             BgpConditionsAugmentationPolicy> bgpConditionsAugRegistry = new HashMap<>();
37     @GuardedBy("this")
38     private final Map<Class<? extends ChildOf<BgpMatchConditions>>,
39             BgpConditionsPolicy> bgpConditionsRegistry = new HashMap<>();
40
41     AbstractRegistration registerBgpConditionsAugmentationPolicy(
42             final Class<? extends Augmentation<BgpConditions>> conditionPolicyClass,
43             final BgpConditionsAugmentationPolicy conditionPolicy) {
44         synchronized (this.bgpConditionsAugRegistry) {
45             final BgpConditionsAugmentationPolicy prev
46                     = this.bgpConditionsAugRegistry.putIfAbsent(conditionPolicyClass, conditionPolicy);
47             Preconditions.checkState(prev == null, "Condition Policy %s already registered %s",
48                     conditionPolicyClass, prev);
49             return new AbstractRegistration() {
50                 @Override
51                 protected void removeRegistration() {
52                     synchronized (BgpConditionsRegistry.this.bgpConditionsAugRegistry) {
53                         BgpConditionsRegistry.this.bgpConditionsAugRegistry.remove(conditionPolicyClass);
54                     }
55                 }
56             };
57         }
58     }
59
60     <T extends ChildOf<BgpMatchConditions>, N> AbstractRegistration registerBgpConditionsPolicy(
61             final Class<T> conditionPolicyClass,
62             final BgpConditionsPolicy<T, N> conditionPolicy) {
63         synchronized (this.bgpConditionsRegistry) {
64             final BgpConditionsPolicy prev
65                     = this.bgpConditionsRegistry.putIfAbsent(conditionPolicyClass, conditionPolicy);
66             Preconditions.checkState(prev == null, "Condition Policy %s already registered %s",
67                     conditionPolicyClass, prev);
68             return new AbstractRegistration() {
69                 @Override
70                 protected void removeRegistration() {
71                     synchronized (BgpConditionsRegistry.this.bgpConditionsRegistry) {
72                         BgpConditionsRegistry.this.bgpConditionsRegistry.remove(conditionPolicyClass);
73                     }
74                 }
75             };
76         }
77     }
78
79     @SuppressWarnings("unchecked")
80     boolean matchExportConditions(
81             final Class<? extends AfiSafiType> afiSafi,
82             final RouteEntryBaseAttributes entryInfo,
83             final BGPRouteEntryExportParameters routeEntryExportParameters,
84             final Attributes attributes,
85             final Conditions conditions) {
86         final Conditions1 bgpConditionsAug = conditions.augmentation(Conditions1.class);
87         if (bgpConditionsAug != null) {
88
89             final BgpConditions bgpConditions = bgpConditionsAug.getBgpConditions();
90             if (!matchExportCondition(afiSafi, entryInfo, routeEntryExportParameters, attributes,
91                     bgpConditions)) {
92                 return false;
93             }
94             final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpAug = BindingReflections
95                     .getAugmentations(bgpConditions);
96             for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry : bgpAug.entrySet()) {
97                 final BgpConditionsAugmentationPolicy handler = this.bgpConditionsAugRegistry.get(entry.getKey());
98                 if (handler == null) {
99                     continue;
100                 }
101                 if (!handler.matchExportCondition(afiSafi, entryInfo, routeEntryExportParameters,
102                         handler.getConditionParameter(attributes), entry.getValue())) {
103                     return false;
104                 }
105             }
106         }
107         return true;
108     }
109
110
111     boolean matchImportConditions(
112             final Class<? extends AfiSafiType> afiSafi,
113             final RouteEntryBaseAttributes entryInfo,
114             final BGPRouteEntryImportParameters routeEntryImportParameters,
115             final Attributes attributes,
116             final Conditions conditions) {
117
118         final Conditions1 bgpConditionsAug = conditions.augmentation(Conditions1.class);
119         if (bgpConditionsAug != null) {
120             final BgpConditions bgpConditions = bgpConditionsAug.getBgpConditions();
121             synchronized (this) {
122                 if (!matchImportCondition(afiSafi, entryInfo, routeEntryImportParameters, attributes,
123                         bgpConditions)) {
124                     return false;
125                 }
126             }
127             final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpAug = BindingReflections
128                     .getAugmentations(bgpConditions);
129             for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry : bgpAug.entrySet()) {
130                 final BgpConditionsAugmentationPolicy handler = this.bgpConditionsAugRegistry.get(entry.getKey());
131                 if (handler == null) {
132                     continue;
133                 }
134                 if (!handler.matchImportCondition(afiSafi, entryInfo, routeEntryImportParameters,
135                         handler.getConditionParameter(attributes), entry.getValue())) {
136                     return false;
137                 }
138             }
139         }
140         return true;
141     }
142
143     @SuppressWarnings("unchecked")
144     private boolean matchImportCondition(
145             final Class<? extends AfiSafiType> afiSafi,
146             final RouteEntryBaseAttributes routeEntryInfo,
147             final BGPRouteEntryImportParameters routeEntryImportParameters,
148             final Attributes attributes,
149             final BgpConditions conditions) {
150
151         if (!BgpAttributeConditionsUtil.matchConditions(afiSafi, attributes, conditions)) {
152             return false;
153         }
154
155         final MatchCommunitySet matchCond = conditions.getMatchCommunitySet();
156         if (matchCond != null) {
157             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchCommunitySet.class);
158             if (!handler.matchImportCondition(afiSafi, routeEntryInfo, routeEntryImportParameters,
159                     handler.getConditionParameter(attributes), matchCond)) {
160                 return false;
161             }
162         }
163
164         final MatchAsPathSet matchAsPathSet = conditions.getMatchAsPathSet();
165         if (matchCond != null) {
166             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchAsPathSet.class);
167             if (!handler.matchImportCondition(afiSafi, routeEntryInfo, routeEntryImportParameters,
168                     handler.getConditionParameter(attributes), matchAsPathSet)) {
169                 return false;
170             }
171         }
172
173         final MatchExtCommunitySet matchExtCommSet = conditions.getMatchExtCommunitySet();
174         if (matchExtCommSet != null) {
175             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchAsPathSet.class);
176             if (!handler.matchImportCondition(afiSafi, routeEntryInfo, routeEntryImportParameters,
177                     handler.getConditionParameter(attributes), matchExtCommSet)) {
178                 return false;
179             }
180         }
181
182         return true;
183     }
184
185     @SuppressWarnings("unchecked")
186     private boolean matchExportCondition(
187             final Class<? extends AfiSafiType> afiSafi,
188             final RouteEntryBaseAttributes routeEntryInfo,
189             final BGPRouteEntryExportParameters routeEntryExportParameters,
190             final Attributes attributes,
191             final BgpConditions conditions) {
192         if (!BgpAttributeConditionsUtil.matchConditions(afiSafi, attributes, conditions)) {
193             return false;
194         }
195
196         final MatchCommunitySet matchCond = conditions.getMatchCommunitySet();
197         if (matchCond != null) {
198             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchCommunitySet.class);
199             if (!handler.matchExportCondition(afiSafi, routeEntryInfo, routeEntryExportParameters,
200                     handler.getConditionParameter(attributes), matchCond)) {
201                 return false;
202             }
203         }
204
205         final MatchAsPathSet matchAsPathSet = conditions.getMatchAsPathSet();
206         if (matchAsPathSet != null) {
207             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchAsPathSet.class);
208             if (!handler.matchExportCondition(afiSafi, routeEntryInfo, routeEntryExportParameters,
209                     handler.getConditionParameter(attributes), matchAsPathSet)) {
210                 return false;
211             }
212         }
213
214         final MatchExtCommunitySet matchExtCommSet = conditions.getMatchExtCommunitySet();
215         if (matchExtCommSet != null) {
216             final BgpConditionsPolicy handler = this.bgpConditionsRegistry.get(MatchExtCommunitySet.class);
217             if (!handler.matchExportCondition(afiSafi, routeEntryInfo, routeEntryExportParameters,
218                     handler.getConditionParameter(attributes), matchExtCommSet)) {
219                 return false;
220             }
221         }
222
223         return true;
224     }
225 }