2 * Copyright (c) 2018 AT&T Intellectual Property. 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
8 package org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.base.Preconditions;
13 import java.util.HashMap;
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;
51 final class ActionsRegistryImpl {
53 private final Map<Class<? extends Augmentation<Actions>>, ActionsAugPolicy> actionsRegistry = new HashMap<>();
55 private final Map<Class<? extends ChildOf<BgpActions>>, BgpActionPolicy> bgpActions = new HashMap<>();
57 private final Map<Class<? extends Augmentation<BgpActions>>, BgpActionAugPolicy> bgpAugActionsRegistry
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() {
69 protected void removeRegistration() {
70 synchronized (ActionsRegistryImpl.this.actionsRegistry) {
71 ActionsRegistryImpl.this.actionsRegistry.remove(actionPolicyClass);
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() {
87 protected void removeRegistration() {
88 synchronized (ActionsRegistryImpl.this.bgpActions) {
89 ActionsRegistryImpl.this.bgpActions.remove(bgpActionPolicyClass);
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() {
106 protected void removeRegistration() {
107 synchronized (ActionsRegistryImpl.this.bgpAugActionsRegistry) {
108 ActionsRegistryImpl.this.bgpAugActionsRegistry.remove(bgpActionPolicyClass);
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) {
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();
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();
138 if (asPrependAction != null) {
139 attributesUpdated = this.bgpActions.get(SetAsPathPrepend.class)
140 .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
144 if (attributesUpdated == null) {
148 if (setCommunityAction != null) {
149 attributesUpdated = this.bgpActions.get(SetCommunity.class)
150 .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
154 if (attributesUpdated == null) {
158 if (setExtCommunityAction != null) {
159 attributesUpdated = this.bgpActions.get(SetExtCommunity.class)
160 .applyExportAction(routeEntryInfo, routeEntryExportParameters, attributesUpdated,
161 setExtCommunityAction);
164 boolean updated = false;
165 if (localPrefPrependAction != null || localOriginAction != null
166 || medAction != null || nhAction != null) {
171 final AttributesBuilder attributesUpdatedBuilder = new AttributesBuilder(attributes);
172 if (localPrefPrependAction != null) {
173 attributesUpdatedBuilder.setLocalPref(new LocalPrefBuilder()
174 .setPref(localPrefPrependAction).build());
177 if (localOriginAction != null) {
178 attributesUpdatedBuilder.setOrigin(new OriginBuilder()
179 .setValue(BgpOrigin.forValue(localOriginAction.getIntValue())).build());
182 if (medAction != null) {
183 attributesUpdatedBuilder.setMultiExitDisc(new MultiExitDiscBuilder()
184 .setMed(medAction.getUint32()).build());
187 if (nhAction != null) {
188 final IpAddress address = nhAction.getIpAddress();
190 if (address != null) {
191 if (address.getIpv4Address() != null) {
192 nhNew = new Ipv4NextHopCaseBuilder()
193 .setIpv4NextHop(new Ipv4NextHopBuilder()
194 .setGlobal(IetfInetUtil.INSTANCE.ipv4AddressNoZoneFor(address.getIpv4Address()))
198 nhNew = new Ipv6NextHopCaseBuilder()
199 .setIpv6NextHop(new Ipv6NextHopBuilder()
200 .setGlobal(IetfInetUtil.INSTANCE.ipv6AddressNoZoneFor(address.getIpv6Address()))
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);
213 attributesUpdated = attributesUpdatedBuilder.build();
216 final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpConditionsAug = BindingReflections
217 .getAugmentations(bgpAction);
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) {
225 } else if (attributesUpdated == null) {
228 attributesUpdated = handler.applyExportAction(routeEntryInfo, routeEntryExportParameters,
229 attributesUpdated, entry.getValue());
234 if (attributesUpdated == null) {
238 // Export Actions Aug
239 final Map<Class<? extends Augmentation<?>>, Augmentation<?>> conditionsAug = BindingReflections
240 .getAugmentations(actions);
242 if (conditionsAug == null) {
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) {
250 } else if (handler == null) {
253 attributesUpdated = handler.applyExportAction(routeEntryInfo, routeEntryExportParameters,
254 attributesUpdated, (Augmentation<Actions>) entry.getValue());
257 return attributesUpdated;
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) {
269 Attributes attributesUpdated = attributes;
270 final Actions1 augmentation = actions.augmentation(Actions1.class);
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();
278 if (asPrependAction != null) {
279 attributesUpdated = this.bgpActions.get(asPrependAction.getClass())
280 .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated, asPrependAction);
283 if (attributesUpdated == null) {
287 if (setCommunityAction != null) {
288 attributesUpdated = this.bgpActions.get(SetCommunity.class)
289 .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
293 if (attributesUpdated == null) {
297 if (setExtCommunityAction != null) {
298 attributesUpdated = this.bgpActions.get(SetExtCommunity.class)
299 .applyImportAction(routeEntryInfo, routeParameters, attributesUpdated, setExtCommunityAction);
302 if (attributesUpdated == null) {
306 final Map<Class<? extends Augmentation<?>>, Augmentation<?>> bgpConditionsAug = BindingReflections
307 .getAugmentations(bgpAction);
309 if (bgpConditionsAug == null) {
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) {
318 } else if (attributesUpdated == null) {
321 attributesUpdated = handler.applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
324 if (attributesUpdated == null) {
329 final Map<Class<? extends Augmentation<?>>, Augmentation<?>> conditionsAug = BindingReflections
330 .getAugmentations(actions);
332 if (conditionsAug == null) {
333 return attributesUpdated;
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) {
339 } else if (attributesUpdated == null) {
342 attributesUpdated = handler.applyImportAction(routeEntryInfo, routeParameters, attributesUpdated,
343 (Augmentation<Actions>) entry.getValue());
345 return attributesUpdated;