Merge "Support proper route redistribution"
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / AbstractExportPolicy.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  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.rib.impl;
9
10 import com.google.common.collect.Maps;
11 import java.util.EnumMap;
12 import java.util.Map;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
14 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
15
16 /**
17  * Defines the internal hooks invoked when a new route appears.
18  */
19 abstract class AbstractExportPolicy {
20     // Invoked on routes which we send outside of our home AS
21     private static final class ToExternalExportPolicy extends AbstractExportPolicy {
22         @Override
23         ContainerNode effectiveAttributes(final PeerRole sourceRole, final ContainerNode attributes) {
24             // FIXME: filter all non-transitive attributes
25             // FIXME: but that may end up hurting our informedness
26             // FIXME: prepend local AS to add our AS into AS_PATH
27
28             switch (sourceRole) {
29             case Ebgp:
30                 // eBGP -> eBGP, propagate
31                 return attributes;
32             case Ibgp:
33                 // Non-Client iBGP -> eBGP, propagate
34                 return attributes;
35             case RrClient:
36                 // Client iBGP -> eBGP, propagate
37                 return attributes;
38             }
39             return attributes;
40         }
41     }
42
43     // Invoked on routes which we send to our normal home AS peers.
44     private static class ToInternalExportPolicy extends AbstractExportPolicy {
45         protected static ContainerNode prependClusterId(final ContainerNode attributes) {
46             // FIXME: prepend local CLUSTER_ID to CLUSTER_LIST
47             return attributes;
48         }
49
50         // Attributes when reflecting a route
51         protected static ContainerNode toClientAttributes(final ContainerNode attributes) {
52             // TODO: (defensiveness) verify ORIGINATOR_ID (should have been set)
53
54             return prependClusterId(attributes);
55         }
56
57         @Override
58         ContainerNode effectiveAttributes(final PeerRole sourceRole, final ContainerNode attributes) {
59             // Implement filtering according to <a ref="http://tools.ietf.org/html/rfc4456#section-8"/>.
60
61             switch (sourceRole) {
62             case Ebgp:
63                 // eBGP -> Non-Client iBGP, propagate
64                 return attributes;
65
66             case Ibgp:
67                 // Non-Client iBGP -> Non-Client iBGP, block
68                 return null;
69
70             case RrClient:
71                 // Client iBGP -> Non-Client iBGP, reflect
72                 return toClientAttributes(attributes);
73             }
74             return attributes;
75         }
76     }
77
78     /**
79      * Invoked on routes which we send to our reflector peers. This is a special-case of
80      * FromInternalImportPolicy.
81      */
82     private static final class ToReflectorClientExportPolicy extends AbstractExportPolicy {
83         @Override
84         ContainerNode effectiveAttributes(final PeerRole sourceRole, final ContainerNode attributes) {
85             switch (sourceRole) {
86             case Ebgp:
87                 // eBGP -> Client iBGP, propagate
88                 return attributes;
89             case Ibgp:
90                 // Non-Client iBGP -> Client iBGP, reflect
91                 // FIXME: add ORIGINATOR_ID
92
93                 return ToInternalExportPolicy.prependClusterId(attributes);
94             case RrClient:
95                 // Client iBGP -> Client iBGP, reflect
96                 return ToInternalExportPolicy.toClientAttributes(attributes);
97             }
98
99             throw new IllegalStateException("Unhandled source role " + sourceRole);
100         }
101     }
102
103     static final Map<PeerRole, AbstractExportPolicy> POLICIES;
104
105     static {
106         final Map<PeerRole, AbstractExportPolicy> p = new EnumMap<PeerRole, AbstractExportPolicy>(PeerRole.class);
107         p.put(PeerRole.Ebgp, new ToExternalExportPolicy());
108         p.put(PeerRole.Ibgp, new ToInternalExportPolicy());
109         p.put(PeerRole.RrClient, new ToReflectorClientExportPolicy());
110         POLICIES = Maps.immutableEnumMap(p);
111     }
112
113     static AbstractExportPolicy forRole(final PeerRole peerRole) {
114         return POLICIES.get(peerRole);
115     }
116
117     /**
118      * Transform outgoing attributes according to policy.
119      *
120      * @param sourceRole role of the peer which originated the routes
121      * @param attributes outgoing attributes
122      * @return Filtered attributes, or null if the advertisement should be ignored.
123      */
124     abstract ContainerNode effectiveAttributes(PeerRole sourceRole, ContainerNode attributes);
125 }