Mass-convert all compontents to use -no-zone addresses
[bgpcep.git] / bgp / openconfig-rp-spi / src / main / java / org / opendaylight / protocol / bgp / openconfig / routing / policy / spi / registry / ActionsRegistryImpl.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 static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.Preconditions;
13 import java.util.HashMap;
14 import java.util.Map;
15 import org.checkerframework.checker.lock.qual.GuardedBy;
16 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
17 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.RouteEntryBaseAttributes;
18 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.policy.action.ActionsAugPolicy;
19 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.policy.action.BgpActionAugPolicy;
20 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.policy.action.BgpActionPolicy;
21 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryExportParameters;
22 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
23 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.Actions1;
24 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.BgpNextHopType;
25 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.BgpSetMedType;
26 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.routing.policy.policy.definitions.policy.definition.statements.statement.actions.BgpActions;
27 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.routing.policy.policy.definitions.policy.definition.statements.statement.actions.bgp.actions.SetAsPathPrepend;
28 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.routing.policy.policy.definitions.policy.definition.statements.statement.actions.bgp.actions.SetCommunity;
29 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.policy.rev151009.routing.policy.policy.definitions.policy.definition.statements.statement.actions.bgp.actions.SetExtCommunity;
30 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.BgpOriginAttrType;
31 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.generic.actions.route.disposition.RejectRoute;
32 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.routing.policy.rev151009.routing.policy.top.routing.policy.policy.definitions.policy.definition.statements.statement.Actions;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.LocalPrefBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.MultiExitDiscBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.OriginBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.BgpOrigin;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.CNextHop;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.Ipv6NextHopCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHopBuilder;
46 import org.opendaylight.yangtools.concepts.AbstractRegistration;
47 import org.opendaylight.yangtools.yang.binding.Augmentation;
48 import org.opendaylight.yangtools.yang.binding.ChildOf;
49 import org.opendaylight.yangtools.yang.common.Uint32;
50
51 final class ActionsRegistryImpl {
52     @GuardedBy("this")
53     private final Map<Class<? extends Augmentation<Actions>>, ActionsAugPolicy> actionsRegistry = new HashMap<>();
54     @GuardedBy("this")
55     private final Map<Class<? extends ChildOf<BgpActions>>, BgpActionPolicy> bgpActions = new HashMap<>();
56     @GuardedBy("this")
57     private final Map<Class<? extends Augmentation<BgpActions>>, BgpActionAugPolicy> bgpAugActionsRegistry
58             = new HashMap<>();
59
60     AbstractRegistration registerActionPolicy(
61             final Class<? extends Augmentation<Actions>> actionPolicyClass,
62             final ActionsAugPolicy actionPolicy) {
63         synchronized (this.actionsRegistry) {
64             final ActionsAugPolicy prev = this.actionsRegistry.putIfAbsent(actionPolicyClass, actionPolicy);
65             Preconditions.checkState(prev == null, "Action Policy %s already registered %s",
66                     actionPolicyClass, prev);
67             return new AbstractRegistration() {
68                 @Override
69                 protected void removeRegistration() {
70                     synchronized (ActionsRegistryImpl.this.actionsRegistry) {
71                         ActionsRegistryImpl.this.actionsRegistry.remove(actionPolicyClass);
72                     }
73                 }
74             };
75         }
76     }
77
78     public AbstractRegistration registerBgpActionPolicy(
79             final Class<? extends ChildOf<BgpActions>> bgpActionPolicyClass,
80             final BgpActionPolicy bgpActionPolicy) {
81         synchronized (this.bgpActions) {
82             final BgpActionPolicy prev = this.bgpActions.putIfAbsent(bgpActionPolicyClass, bgpActionPolicy);
83             Preconditions.checkState(prev == null, "Action Policy %s already registered %s",
84                     bgpActionPolicyClass, prev);
85             return new AbstractRegistration() {
86                 @Override
87                 protected void removeRegistration() {
88                     synchronized (ActionsRegistryImpl.this.bgpActions) {
89                         ActionsRegistryImpl.this.bgpActions.remove(bgpActionPolicyClass);
90                     }
91                 }
92             };
93         }
94     }
95
96     public AbstractRegistration registerBgpActionAugmentationPolicy(
97             final Class<? extends Augmentation<BgpActions>> bgpActionPolicyClass,
98             final BgpActionAugPolicy bgpActionPolicy) {
99         synchronized (this.bgpAugActionsRegistry) {
100             final BgpActionAugPolicy prev = this.bgpAugActionsRegistry
101                     .putIfAbsent(bgpActionPolicyClass, bgpActionPolicy);
102             Preconditions.checkState(prev == null, "Action Policy %s already registered %s",
103                     bgpActionPolicyClass, prev);
104             return new AbstractRegistration() {
105                 @Override
106                 protected void removeRegistration() {
107                     synchronized (ActionsRegistryImpl.this.bgpAugActionsRegistry) {
108                         ActionsRegistryImpl.this.bgpAugActionsRegistry.remove(bgpActionPolicyClass);
109                     }
110                 }
111             };
112         }
113     }
114
115     @SuppressWarnings("unchecked")
116     Attributes applyExportAction(
117             final RouteEntryBaseAttributes routeEntryInfo,
118             final BGPRouteEntryExportParameters routeEntryExportParameters,
119             final Attributes attributes,
120             final Actions actions) {
121         requireNonNull(attributes);
122         if (actions.getRouteDisposition() instanceof RejectRoute) {
123             return null;
124         }
125         Attributes attributesUpdated = attributes;
126         final Actions1 augmentation = actions.augmentation(Actions1.class);
127         if (augmentation != null && augmentation.getBgpActions() != null) {
128             final BgpActions bgpAction = augmentation.getBgpActions();
129
130             final SetAsPathPrepend asPrependAction = bgpAction.getSetAsPathPrepend();
131             final Uint32 localPrefPrependAction = bgpAction.getSetLocalPref();
132             final BgpOriginAttrType localOriginAction = bgpAction.getSetRouteOrigin();
133             final BgpSetMedType medAction = bgpAction.getSetMed();
134             final BgpNextHopType nhAction = bgpAction.getSetNextHop();
135             final SetCommunity setCommunityAction = bgpAction.getSetCommunity();
136             final SetExtCommunity setExtCommunityAction = bgpAction.getSetExtCommunity();
137
138             if (asPrependAction != null) {
139                 attributesUpdated = this.bgpActions.get(SetAsPathPrepend.class)
140                         .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
141                                 asPrependAction);
142             }
143
144             if (attributesUpdated == null) {
145                 return null;
146             }
147
148             if (setCommunityAction != null) {
149                 attributesUpdated = this.bgpActions.get(SetCommunity.class)
150                         .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
151                                 setCommunityAction);
152             }
153
154             if (attributesUpdated == null) {
155                 return null;
156             }
157
158             if (setExtCommunityAction != null) {
159                 attributesUpdated = this.bgpActions.get(SetExtCommunity.class)
160                         .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
161                                 setExtCommunityAction);
162             }
163
164             boolean updated = false;
165             if (localPrefPrependAction != null || localOriginAction != null
166                     || medAction != null || nhAction != null) {
167                 updated = true;
168             }
169
170             if (updated) {
171                 final AttributesBuilder attributesUpdatedBuilder = new AttributesBuilder(attributes);
172                 if (localPrefPrependAction != null) {
173                     attributesUpdatedBuilder.setLocalPref(new LocalPrefBuilder()
174                             .setPref(localPrefPrependAction).build());
175                 }
176
177                 if (localOriginAction != null) {
178                     attributesUpdatedBuilder.setOrigin(new OriginBuilder()
179                             .setValue(BgpOrigin.forValue(localOriginAction.getIntValue())).build());
180                 }
181
182                 if (medAction != null) {
183                     attributesUpdatedBuilder.setMultiExitDisc(new MultiExitDiscBuilder()
184                             .setMed(medAction.getUint32()).build());
185                 }
186
187                 if (nhAction != null) {
188                     final IpAddress address = nhAction.getIpAddress();
189                     CNextHop nhNew;
190                     if (address != null) {
191                         if (address.getIpv4Address() != null) {
192                             nhNew = new Ipv4NextHopCaseBuilder()
193                                     .setIpv4NextHop(new Ipv4NextHopBuilder()
194                                         .setGlobal(IetfInetUtil.INSTANCE.ipv4AddressNoZoneFor(address.getIpv4Address()))
195                                         .build())
196                                     .build();
197                         } else {
198                             nhNew = new Ipv6NextHopCaseBuilder()
199                                     .setIpv6NextHop(new Ipv6NextHopBuilder()
200                                         .setGlobal(IetfInetUtil.INSTANCE.ipv6AddressNoZoneFor(address.getIpv6Address()))
201                                         .build())
202                                     .build();
203                         }
204
205                         attributesUpdatedBuilder.setCNextHop(nhNew);
206                     } else if (nhAction.getEnumeration() != null
207                             && BgpNextHopType.Enumeration.SELF == nhAction.getEnumeration()) {
208                         nhNew = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
209                                 .setGlobal(routeEntryInfo.getOriginatorId()).build()).build();
210                         attributesUpdatedBuilder.setCNextHop(nhNew);
211                     }
212                 }
213                 attributesUpdated = attributesUpdatedBuilder.build();
214             }
215
216             final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpConditionsAug = BindingReflections
217                     .getAugmentations(bgpAction);
218
219             if (bgpConditionsAug != null) {
220                 for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry
221                         : bgpConditionsAug.entrySet()) {
222                     final BgpActionAugPolicy handler = this.bgpAugActionsRegistry.get(entry.getKey());
223                     if (handler == null) {
224                         continue;
225                     } else if (attributesUpdated == null) {
226                         return null;
227                     }
228                     attributesUpdated = handler.applyExportAction(routeEntryInfo, routeEntryExportParameters,
229                             attributesUpdated, entry.getValue());
230                 }
231             }
232         }
233
234         if (attributesUpdated == null) {
235             return null;
236         }
237
238         // Export Actions Aug
239         final Map<Class<? extends Augmentation<?>>, Augmentation<?>> conditionsAug = BindingReflections
240                 .getAugmentations(actions);
241
242         if (conditionsAug == null) {
243             return attributes;
244         }
245
246         for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry : conditionsAug.entrySet()) {
247             final ActionsAugPolicy handler = this.actionsRegistry.get(entry.getKey());
248             if (attributesUpdated == null) {
249                 return null;
250             } else if (handler == null) {
251                 continue;
252             }
253             attributesUpdated = handler.applyExportAction(routeEntryInfo, routeEntryExportParameters,
254                     attributesUpdated, (Augmentation<Actions>) entry.getValue());
255         }
256
257         return attributesUpdated;
258     }
259
260     @SuppressWarnings("unchecked")
261     Attributes applyImportAction(
262             final RouteEntryBaseAttributes routeEntryInfo,
263             final BGPRouteEntryImportParameters routeParameters,
264             final Attributes attributes,
265             final Actions actions) {
266         if (actions.getRouteDisposition() instanceof RejectRoute) {
267             return null;
268         }
269         Attributes attributesUpdated = attributes;
270         final Actions1 augmentation = actions.augmentation(Actions1.class);
271
272         if (augmentation != null && augmentation.getBgpActions() != null) {
273             final BgpActions bgpAction = augmentation.getBgpActions();
274             final SetCommunity setCommunityAction = bgpAction.getSetCommunity();
275             final SetExtCommunity setExtCommunityAction = bgpAction.getSetExtCommunity();
276             final SetAsPathPrepend asPrependAction = bgpAction.getSetAsPathPrepend();
277
278             if (asPrependAction != null) {
279                 attributesUpdated = this.bgpActions.get(asPrependAction.getClass())
280                         .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated, asPrependAction);
281             }
282
283             if (attributesUpdated == null) {
284                 return null;
285             }
286
287             if (setCommunityAction != null) {
288                 attributesUpdated = this.bgpActions.get(SetCommunity.class)
289                         .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
290                                 setCommunityAction);
291             }
292
293             if (attributesUpdated == null) {
294                 return null;
295             }
296
297             if (setExtCommunityAction != null) {
298                 attributesUpdated = this.bgpActions.get(SetExtCommunity.class)
299                         .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated, setExtCommunityAction);
300             }
301
302             if (attributesUpdated == null) {
303                 return null;
304             }
305
306             final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpConditionsAug = BindingReflections
307                     .getAugmentations(bgpAction);
308
309             if (bgpConditionsAug == null) {
310                 return attributes;
311             }
312
313             for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry
314                     : bgpConditionsAug.entrySet()) {
315                 final BgpActionAugPolicy handler = this.bgpAugActionsRegistry.get(entry.getKey());
316                 if (handler == null) {
317                     continue;
318                 } else if (attributesUpdated == null) {
319                     return null;
320                 }
321                 attributesUpdated = handler.applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
322                         entry.getValue());
323             }
324             if (attributesUpdated == null) {
325                 return null;
326             }
327         }
328         // Augmented Actions
329         final Map<Class<? extends Augmentation<?>>, Augmentation<?>> conditionsAug = BindingReflections
330                 .getAugmentations(actions);
331
332         if (conditionsAug == null) {
333             return attributesUpdated;
334         }
335         for (final Map.Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry : conditionsAug.entrySet()) {
336             final ActionsAugPolicy handler = this.actionsRegistry.get(entry.getKey());
337             if (handler == null) {
338                 continue;
339             } else if (attributesUpdated == null) {
340                 return null;
341             }
342             attributesUpdated = handler.applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
343                     (Augmentation<Actions>) entry.getValue());
344         }
345         return attributesUpdated;
346     }
347 }