8be46f93f0c7e503c4324d072b8b37b18c29f86f
[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             default:
39                 break;
40             }
41             return attributes;
42         }
43     }
44
45     // Invoked on routes which we send to our normal home AS peers.
46     private static class ToInternalExportPolicy extends AbstractExportPolicy {
47         protected static ContainerNode prependClusterId(final ContainerNode attributes) {
48             // FIXME: prepend local CLUSTER_ID to CLUSTER_LIST
49             return attributes;
50         }
51
52         // Attributes when reflecting a route
53         protected static ContainerNode toClientAttributes(final ContainerNode attributes) {
54             // TODO: (defensiveness) verify ORIGINATOR_ID (should have been set)
55
56             return prependClusterId(attributes);
57         }
58
59         @Override
60         ContainerNode effectiveAttributes(final PeerRole sourceRole, final ContainerNode attributes) {
61             // Implement filtering according to <a ref="http://tools.ietf.org/html/rfc4456#section-8"/>.
62
63             switch (sourceRole) {
64             case Ebgp:
65                 // eBGP -> Non-Client iBGP, propagate
66                 return attributes;
67
68             case Ibgp:
69                 // Non-Client iBGP -> Non-Client iBGP, block
70                 return null;
71
72             case RrClient:
73                 // Client iBGP -> Non-Client iBGP, reflect
74                 return toClientAttributes(attributes);
75             default:
76                 break;
77             }
78             return attributes;
79         }
80     }
81
82     /**
83      * Invoked on routes which we send to our reflector peers. This is a special-case of
84      * FromInternalImportPolicy.
85      */
86     private static final class ToReflectorClientExportPolicy extends AbstractExportPolicy {
87         @Override
88         ContainerNode effectiveAttributes(final PeerRole sourceRole, final ContainerNode attributes) {
89             switch (sourceRole) {
90             case Ebgp:
91                 // eBGP -> Client iBGP, propagate
92                 return attributes;
93             case Ibgp:
94                 // Non-Client iBGP -> Client iBGP, reflect
95                 // FIXME: add ORIGINATOR_ID
96
97                 return ToInternalExportPolicy.prependClusterId(attributes);
98             case RrClient:
99                 // Client iBGP -> Client iBGP, reflect
100                 return ToInternalExportPolicy.toClientAttributes(attributes);
101             default:
102                 throw new IllegalStateException("Unhandled source role " + sourceRole);
103             }
104         }
105     }
106
107     static final Map<PeerRole, AbstractExportPolicy> POLICIES;
108
109     static {
110         final Map<PeerRole, AbstractExportPolicy> p = new EnumMap<PeerRole, AbstractExportPolicy>(PeerRole.class);
111         p.put(PeerRole.Ebgp, new ToExternalExportPolicy());
112         p.put(PeerRole.Ibgp, new ToInternalExportPolicy());
113         p.put(PeerRole.RrClient, new ToReflectorClientExportPolicy());
114         POLICIES = Maps.immutableEnumMap(p);
115     }
116
117     static AbstractExportPolicy forRole(final PeerRole peerRole) {
118         return POLICIES.get(peerRole);
119     }
120
121     /**
122      * Transform outgoing attributes according to policy.
123      *
124      * @param sourceRole role of the peer which originated the routes
125      * @param attributes outgoing attributes
126      * @return Filtered attributes, or null if the advertisement should be ignored.
127      */
128     abstract ContainerNode effectiveAttributes(PeerRole sourceRole, ContainerNode attributes);
129 }