2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. 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.bgpmanager;
10 import java.util.Collections;
14 import org.apache.thrift.TException;
15 import org.opendaylight.bgpmanager.globals.BgpConfiguration;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
21 import org.opendaylight.yangtools.concepts.ListenerRegistration;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpRouter;
25 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpNeighbors;
26 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.BgpNeighbor;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import java.util.List;
33 import com.google.common.base.Optional;
34 import com.google.common.base.Preconditions;
36 public class BgpConfigurationManager {
37 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
38 private ListenerRegistration<DataChangeListener> listenerRegistration;
39 private BgpConfiguration bgpConfiguration;
40 private BgpManager bgpManager;
41 private final DataBroker broker;
42 private static final int MAX_RETRIES_BGP_COMMUNICATION = 1;
44 START_BGP, ADD_NGHBR, DEL_NGHBR
47 public BgpConfigurationManager(final DataBroker db, BgpConfiguration bgpCfg, BgpManager bgpMgr) {
49 bgpConfiguration = bgpCfg;
51 BgpRtrCfgManager rtrCfgManager = new BgpRtrCfgManager(broker);
52 BgpNghbrCfgManager nghbrCfgManager = new BgpNghbrCfgManager(broker);
55 public class BgpRtrCfgManager extends AbstractDataChangeListener<BgpRouter> implements AutoCloseable {
57 public BgpRtrCfgManager(final DataBroker db) {
58 super(BgpRouter.class);
62 private void registerListener(final DataBroker db) {
64 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
65 getWildCardPath(), BgpRtrCfgManager.this, DataChangeScope.SUBTREE);
66 } catch (final Exception e) {
67 LOG.error("BGP Configuration DataChange listener registration fail!", e);
68 throw new IllegalStateException("BGP Configuration registration Listener failed.", e);
72 private synchronized void removeBgpRouter(BgpRouter del)
74 bgpManager.disconnect();
76 bgpConfiguration.setRouterId("");
77 bgpConfiguration.setAsNum(0);
82 protected void remove(InstanceIdentifier<BgpRouter> identifier,
85 LOG.debug("Bgp Router deleted in DS - key: {} value={} ", identifier, del);
91 private synchronized void updateBgpRouter(BgpRouter original, BgpRouter update)
93 if(bgpConfiguration.getAsNum() != update.getLocalAsNumber()) {
94 bgpConfiguration.setAsNum(update.getLocalAsNumber());
95 bgpConfiguration.setConfigUpdated();
97 if(bgpConfiguration.getRouterId() != update.getLocalAsIdentifier().getIpv4Address().getValue()) {
98 bgpConfiguration.setRouterId(update.getLocalAsIdentifier().getIpv4Address().getValue());
99 bgpConfiguration.setConfigUpdated();
102 if(bgpConfiguration.isConfigUpdated()) {
103 configureBgpServer(BgpOp.START_BGP);
104 bgpConfiguration.unsetConfigUpdated();
110 protected void update(InstanceIdentifier<BgpRouter> identifier,
111 BgpRouter original, BgpRouter update) {
113 LOG.debug("Bgp Router Updated in DS - key: {}, original={}, update={} ", identifier, original, update);
115 updateBgpRouter(original, update);
118 private synchronized void addBgpRouter(BgpRouter value){
119 if(value.getLocalAsNumber() != null) {
120 bgpConfiguration.setAsNum(value.getLocalAsNumber());
122 if(value.getLocalAsIdentifier() != null) {
123 bgpConfiguration.setRouterId(value.getLocalAsIdentifier().getIpv4Address().getValue());
126 if(value.getLocalAsNumber() == null || value.getLocalAsIdentifier() == null)
129 configureBgpServer(BgpOp.START_BGP);
133 protected void add(InstanceIdentifier<BgpRouter> identifier,
135 LOG.debug("Bgp Router added in DS - key: {}, value={} ",identifier, value);
140 private InstanceIdentifier<BgpRouter> getWildCardPath() {
141 return InstanceIdentifier.create(BgpRouter.class);
145 public void close() throws Exception {
146 if (listenerRegistration != null) {
148 listenerRegistration.close();
149 } catch (final Exception e) {
150 LOG.error("Error when cleaning up DataChangeListener.", e);
152 listenerRegistration = null;
154 LOG.info("Bgp Router Manager Closed");
158 public class BgpNghbrCfgManager extends AbstractDataChangeListener<BgpNeighbors> implements AutoCloseable {
160 public BgpNghbrCfgManager(final DataBroker db) {
161 super(BgpNeighbors.class);
162 registerListener(db);
165 private void registerListener(final DataBroker db) {
167 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
168 getWildCardPath(), BgpNghbrCfgManager.this, DataChangeScope.SUBTREE);
169 } catch (final Exception e) {
170 LOG.error("BGP Neighbor DataChange listener registration fail!", e);
171 throw new IllegalStateException("BGP Neighbor registration Listener failed.", e);
175 private synchronized void removeBgpNeighbors(BgpNeighbors del) {
176 List<BgpNeighbor> bgpNeighborList = del.getBgpNeighbor();
177 BgpNeighbor gateway = bgpNeighborList.get(0);
179 if(gateway != null) {
180 if ((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
181 IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress) gateway.getPeerAddressType()).getIpAddress();
182 LOG.debug("Bgp Neighbor IP Address {} ", neighborIPAddr.getIpv4Address().getValue());
184 configureBgpServer(BgpOp.DEL_NGHBR);
186 bgpConfiguration.setNeighbourIp("");
187 bgpConfiguration.setNeighbourAsNum(0);
195 protected void remove(InstanceIdentifier<BgpNeighbors> identifier,
198 LOG.debug("Bgp Neighbors deleted in DS - key: {}, value={} ", identifier, del);
199 removeBgpNeighbors(del);
202 private synchronized void updateBgpNeighbors(BgpNeighbors original, BgpNeighbors update) {
204 List<BgpNeighbor> bgpNeighborList = update.getBgpNeighbor();
206 //handle the case where there are no neighbors configured - single neighbor entry has been deleted
207 if(bgpNeighborList.isEmpty()) {
208 configureBgpServer(BgpOp.DEL_NGHBR);
212 //We will always consider the first element of this list, since there can be just one DC Gateway
213 BgpNeighbor gateway = bgpNeighborList.get(0);
215 if(gateway != null) {
216 if(gateway.getAsNumber() != null ||
217 ((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress))) {
218 //there is an updated neighbor, so we need to delete the old neighbor
219 configureBgpServer(BgpOp.DEL_NGHBR);
221 if(gateway.getAsNumber() != null) {
222 LOG.debug("Bgp Neighbor AS number {} ", gateway.getAsNumber());
223 if(bgpConfiguration.getNeighbourAsNum() != gateway.getAsNumber()) {
224 bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
225 bgpConfiguration.setConfigUpdated();
228 if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
229 IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
230 LOG.debug("Bgp Neighbor IP Address {}", neighborIPAddr.getIpv4Address().getValue());
231 if(bgpConfiguration.getNeighbourIp() != neighborIPAddr.getIpv4Address().getValue()) {
232 bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
233 bgpConfiguration.setConfigUpdated();
238 if(bgpConfiguration.isConfigUpdated()) {
239 //add the newly configured neighbor
240 configureBgpServer(BgpOp.ADD_NGHBR);
245 protected void update(InstanceIdentifier<BgpNeighbors> identifier,
246 BgpNeighbors original, BgpNeighbors update) {
248 LOG.debug("Bgp Neighbors Updated in DS - key: {}, original={}, update={} ", identifier, original, update);
250 updateBgpNeighbors(original, update);
254 private synchronized void addBgpNeighbors(BgpNeighbors value) {
255 List<BgpNeighbor> bgpNeighborList = value.getBgpNeighbor();
257 //We will always consider the first element of this list, since there can be just one DC Gateway
258 BgpNeighbor gateway = bgpNeighborList.get(0);
260 if(gateway != null) {
261 if(gateway.getAsNumber() != null) {
262 LOG.debug("Bgp Neighbor AS number {} ", gateway.getAsNumber());
263 bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
265 if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
266 IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
267 LOG.debug("Bgp Neighbor IP Address {} ", neighborIPAddr.getIpv4Address().getValue());
268 bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
271 if(bgpConfiguration.getNeighbourAsNum() != 0 && bgpConfiguration.getNeighbourIp() != null) {
272 configureBgpServer(BgpOp.ADD_NGHBR);
279 protected void add(InstanceIdentifier<BgpNeighbors> identifier,
280 BgpNeighbors value) {
281 LOG.debug("Bgp Neighbor added in DS - key: {}, value={} ", identifier, value);
283 addBgpNeighbors(value);
286 private InstanceIdentifier<?> getWildCardPath() {
287 return InstanceIdentifier.create(BgpNeighbors.class);
292 public void close() throws Exception {
293 if (listenerRegistration != null) {
295 listenerRegistration.close();
296 } catch (final Exception e) {
297 LOG.error("Error when cleaning up DataChangeListener.", e);
299 listenerRegistration = null;
301 LOG.info("Bgp Neighbor Manager Closed");
306 private void configureBgpServer(BgpOp bgpOp) {
308 boolean retry = false;
313 bgpManager.startBgpService();
316 bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
319 bgpManager.deleteNeighbor(bgpConfiguration.getNeighbourIp());
322 LOG.error("Invalid configuration option {}", bgpOp);
326 } catch (TException t) {
330 } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);