blob: bd49a8f7cb071bb078104c57d9ecfb195e11f96d [file] [log] [blame]
Jonathan Hart4cb39882015-08-12 23:50:55 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Jonathan Hart4cb39882015-08-12 23:50:55 -04003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.routing.config;
18
19import com.fasterxml.jackson.databind.JsonNode;
papazois7d39a742015-10-14 10:15:56 +030020import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.JsonNodeFactory;
22import com.fasterxml.jackson.databind.node.ObjectNode;
Jonathan Hart4cb39882015-08-12 23:50:55 -040023import com.google.common.collect.Sets;
24import org.onlab.packet.IpAddress;
Luca Prete8f2a3ce2016-03-29 16:13:01 -070025import org.onlab.packet.VlanId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040026import org.onosproject.core.ApplicationId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040027import org.onosproject.net.ConnectPoint;
Jonathan Harta8625482015-09-08 16:14:56 -070028import org.onosproject.net.config.Config;
Jonathan Hart4cb39882015-08-12 23:50:55 -040029
papazois7d39a742015-10-14 10:15:56 +030030import java.util.Objects;
Jonathan Harta8625482015-09-08 16:14:56 -070031import java.util.Optional;
Jonathan Hart4cb39882015-08-12 23:50:55 -040032import java.util.Set;
33
34import static com.google.common.base.Preconditions.checkNotNull;
35
36/**
37 * Configuration object for BGP config.
38 */
39public class BgpConfig extends Config<ApplicationId> {
40
41 public static final String SPEAKERS = "bgpSpeakers";
42 public static final String CONNECT_POINT = "connectPoint";
Jonathan Harta8625482015-09-08 16:14:56 -070043 public static final String NAME = "name";
Jonathan Hart4cb39882015-08-12 23:50:55 -040044 public static final String PEERS = "peers";
Luca Prete8f2a3ce2016-03-29 16:13:01 -070045 public static final String VLAN = "vlan";
Jonathan Hart4cb39882015-08-12 23:50:55 -040046
Jonathan Hart4cb39882015-08-12 23:50:55 -040047 /**
48 * Gets the set of configured BGP speakers.
49 *
50 * @return BGP speakers
51 */
52 public Set<BgpSpeakerConfig> bgpSpeakers() {
53 Set<BgpSpeakerConfig> speakers = Sets.newHashSet();
54
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070055 JsonNode speakersNode = object.get(SPEAKERS);
papazois7d39a742015-10-14 10:15:56 +030056
57 if (speakersNode == null) {
58 return speakers;
59 }
60
Jonathan Hart4cb39882015-08-12 23:50:55 -040061 speakersNode.forEach(jsonNode -> {
62 Set<IpAddress> listenAddresses = Sets.newHashSet();
63 jsonNode.path(PEERS).forEach(addressNode ->
Jonathan Harta8625482015-09-08 16:14:56 -070064 listenAddresses.add(IpAddress.valueOf(addressNode.asText()))
Jonathan Hart4cb39882015-08-12 23:50:55 -040065 );
Jonathan Harta8625482015-09-08 16:14:56 -070066
67 Optional<String> name;
68 if (jsonNode.get(NAME) == null) {
69 name = Optional.empty();
70 } else {
71 name = Optional.of(jsonNode.get(NAME).asText());
72 }
73
Luca Prete8f2a3ce2016-03-29 16:13:01 -070074 VlanId vlan = getVlan(jsonNode);
75
Jonathan Harta8625482015-09-08 16:14:56 -070076 speakers.add(new BgpSpeakerConfig(name,
Luca Prete83bac342016-12-06 19:42:05 -080077 vlan,
78 ConnectPoint.deviceConnectPoint(jsonNode.path(CONNECT_POINT).asText()),
79 listenAddresses));
Jonathan Hart4cb39882015-08-12 23:50:55 -040080 });
81
82 return speakers;
83 }
84
Luca Prete83bac342016-12-06 19:42:05 -080085 /*
86 * If configured, it retrieves a VLAN Id from a BGP speaker node
87 */
Luca Prete8f2a3ce2016-03-29 16:13:01 -070088 private VlanId getVlan(JsonNode node) {
89 VlanId vlan = VlanId.NONE;
90 if (!node.path(VLAN).isMissingNode()) {
91 vlan = VlanId.vlanId(node.path(VLAN).asText());
92 }
93 return vlan;
94 }
95
Jonathan Hart4cb39882015-08-12 23:50:55 -040096 /**
papazois7d39a742015-10-14 10:15:56 +030097 * Examines whether a name of BGP speaker exists in configuration.
98 *
Luca Prete83bac342016-12-06 19:42:05 -080099 * @param name the name of BGP speaker being search
100 * @return the BGP speaker
papazois7d39a742015-10-14 10:15:56 +0300101 */
102 public BgpSpeakerConfig getSpeakerWithName(String name) {
103 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
Sho SHIMIZUef7e2902016-02-12 18:38:29 -0800104 if (speaker.name().filter(name::equals).isPresent()) {
papazois7d39a742015-10-14 10:15:56 +0300105 return speaker;
106 }
107 }
108 return null;
109 }
110
111 /**
Luca Prete83bac342016-12-06 19:42:05 -0800112 * Adds a BGP speaker to the configuration.
papazois7d39a742015-10-14 10:15:56 +0300113 *
Luca Prete83bac342016-12-06 19:42:05 -0800114 * @param speaker the BGP speaker configuration entry
papazois7d39a742015-10-14 10:15:56 +0300115 */
116 public void addSpeaker(BgpSpeakerConfig speaker) {
Luca Prete83bac342016-12-06 19:42:05 -0800117 // Create the new speaker node and set the parameters
papazois7d39a742015-10-14 10:15:56 +0300118 ObjectNode speakerNode = JsonNodeFactory.instance.objectNode();
papazois7d39a742015-10-14 10:15:56 +0300119 speakerNode.put(NAME, speaker.name().get());
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700120 speakerNode.put(VLAN, speaker.vlan().toString());
papazois7d39a742015-10-14 10:15:56 +0300121 speakerNode.put(CONNECT_POINT, speaker.connectPoint().elementId().toString()
122 + "/" + speaker.connectPoint().port().toString());
123
124 ArrayNode peersNode = speakerNode.putArray(PEERS);
125 for (IpAddress peerAddress: speaker.peers()) {
126 peersNode.add(peerAddress.toString());
127 }
128
Luca Prete83bac342016-12-06 19:42:05 -0800129 // Add the new BGP speaker to the existing node array
papazois7d39a742015-10-14 10:15:56 +0300130 ArrayNode speakersArray = bgpSpeakers().isEmpty() ?
Luca Prete83bac342016-12-06 19:42:05 -0800131 initBgpSpeakersConfiguration() : (ArrayNode) object.get(SPEAKERS);
papazois7d39a742015-10-14 10:15:56 +0300132 speakersArray.add(speakerNode);
133 }
134
135 /**
136 * Removes BGP speaker from configuration.
137 *
138 * @param speakerName BGP speaker name
139 */
140 public void removeSpeaker(String speakerName) {
141 ArrayNode speakersArray = (ArrayNode) object.get(SPEAKERS);
142
143 for (int i = 0; i < speakersArray.size(); i++) {
144 if (speakersArray.get(i).hasNonNull(NAME) &&
145 speakersArray.get(i).get(NAME).asText().equals(speakerName)) {
146 speakersArray.remove(i);
147 return;
148 }
149 }
150 }
151
152 /**
153 * Adds peering address to BGP speaker.
154 *
155 * @param speakerName name of BGP speaker
156 * @param peerAddress peering address to be added
157 */
158 public void addPeerToSpeaker(String speakerName, IpAddress peerAddress) {
159 JsonNode speakersNode = object.get(SPEAKERS);
160 speakersNode.forEach(jsonNode -> {
161 if (jsonNode.hasNonNull(NAME) &&
162 jsonNode.get(NAME).asText().equals(speakerName)) {
163 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
164 for (int i = 0; i < peersNode.size(); i++) {
165 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
166 return; // Peer already exists.
167 }
168 }
169 peersNode.add(peerAddress.toString());
170 }
171 });
172 }
173
174 /**
175 * Finds BGP speaker peering with a given external peer.
176 *
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700177 * @param peerAddress BGP peer address
178 * @return BGP speaker
papazois7d39a742015-10-14 10:15:56 +0300179 */
180 public BgpSpeakerConfig getSpeakerFromPeer(IpAddress peerAddress) {
181 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
182 if (speaker.peers().contains(peerAddress)) {
183 return speaker;
184 }
185 }
186 return null;
187 }
188
189 /**
190 * Removes peering address from BGP speaker.
191 *
192 * @param speaker BGP speaker configuration entries
193 * @param peerAddress peering address to be removed
194 */
195 public void removePeerFromSpeaker(BgpSpeakerConfig speaker, IpAddress peerAddress) {
196 JsonNode speakersNode = object.get(SPEAKERS);
197 speakersNode.forEach(jsonNode -> {
198 if (jsonNode.hasNonNull(NAME) &&
199 jsonNode.get(NAME).asText().equals(speaker.name().get())) {
200 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
201 for (int i = 0; i < peersNode.size(); i++) {
202 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
203 peersNode.remove(i);
204 return;
205 }
206 }
207 }
208 });
209 }
210
211 /**
212 * Creates empty configuration for BGP speakers.
213 *
214 * @return empty array of BGP speakers
215 */
Luca Prete83bac342016-12-06 19:42:05 -0800216 private ArrayNode initBgpSpeakersConfiguration() {
papazois7d39a742015-10-14 10:15:56 +0300217 return object.putArray(SPEAKERS);
218 }
219
papazois7d39a742015-10-14 10:15:56 +0300220 /**
Jonathan Hart4cb39882015-08-12 23:50:55 -0400221 * Configuration for a BGP speaker.
222 */
223 public static class BgpSpeakerConfig {
224
Jonathan Harta8625482015-09-08 16:14:56 -0700225 private Optional<String> name;
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700226 private VlanId vlanId;
Jonathan Hart4cb39882015-08-12 23:50:55 -0400227 private ConnectPoint connectPoint;
228 private Set<IpAddress> peers;
229
Luca Prete83bac342016-12-06 19:42:05 -0800230 public BgpSpeakerConfig(Optional<String> name,
231 VlanId vlanId,
232 ConnectPoint connectPoint,
233 Set<IpAddress> peers) {
Jonathan Harta8625482015-09-08 16:14:56 -0700234 this.name = checkNotNull(name);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700235 this.vlanId = checkNotNull(vlanId);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400236 this.connectPoint = checkNotNull(connectPoint);
237 this.peers = checkNotNull(peers);
238 }
239
Jonathan Harta8625482015-09-08 16:14:56 -0700240 public Optional<String> name() {
241 return name;
242 }
243
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700244 public VlanId vlan() {
245 return vlanId;
246 }
247
Jonathan Hart4cb39882015-08-12 23:50:55 -0400248 public ConnectPoint connectPoint() {
249 return connectPoint;
250 }
251
252 public Set<IpAddress> peers() {
253 return peers;
254 }
papazois7d39a742015-10-14 10:15:56 +0300255
256 /**
257 * Examines if BGP peer is connected.
258 *
259 * @param peer IP address of peer
260 * @return result of search
261 */
262 public boolean isConnectedToPeer(IpAddress peer) {
263 for (final IpAddress entry : peers()) {
264 if (entry.equals(peer)) {
265 return true;
266 }
267 }
268 return false;
269 }
270
271 @Override
272 public boolean equals(Object obj) {
273 if (this == obj) {
274 return true;
275 }
276 if (obj instanceof BgpSpeakerConfig) {
277 final BgpSpeakerConfig that = (BgpSpeakerConfig) obj;
278 return Objects.equals(this.name, that.name) &&
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700279 Objects.equals(this.vlanId, that.vlanId) &&
papazois7d39a742015-10-14 10:15:56 +0300280 Objects.equals(this.connectPoint, that.connectPoint) &&
281 Objects.equals(this.peers, that.peers);
282 }
283 return false;
284 }
285
286 @Override
287 public int hashCode() {
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700288 return Objects.hash(name, vlanId, connectPoint, peers);
papazois7d39a742015-10-14 10:15:56 +0300289 }
Jonathan Hart4cb39882015-08-12 23:50:55 -0400290 }
291}