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.info("Bgp Router deleted in DS - " + "key: " + identifier + ", value=" + 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.info("Bgp Router Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + 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.info("Bgp Router added in DS - " + "key: " + identifier + ", value=" + value);
136 LOG.info("Bgp Router localASNumber:" + value.getLocalAsNumber());
137 LOG.info("Bgp Router localASIdentifier:" + value.getLocalAsIdentifier());
142 private InstanceIdentifier<BgpRouter> getWildCardPath() {
143 return InstanceIdentifier.create(BgpRouter.class);
147 public void close() throws Exception {
148 if (listenerRegistration != null) {
150 listenerRegistration.close();
151 } catch (final Exception e) {
152 LOG.error("Error when cleaning up DataChangeListener.", e);
154 listenerRegistration = null;
156 LOG.info("Bgp Router Manager Closed");
160 public class BgpNghbrCfgManager extends AbstractDataChangeListener<BgpNeighbors> implements AutoCloseable {
162 public BgpNghbrCfgManager(final DataBroker db) {
163 super(BgpNeighbors.class);
164 registerListener(db);
167 private void registerListener(final DataBroker db) {
169 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
170 getWildCardPath(), BgpNghbrCfgManager.this, DataChangeScope.SUBTREE);
171 } catch (final Exception e) {
172 LOG.error("BGP Neighbor DataChange listener registration fail!", e);
173 throw new IllegalStateException("BGP Neighbor registration Listener failed.", e);
177 private synchronized void removeBgpNeighbors(BgpNeighbors del) {
178 List<BgpNeighbor> bgpNeighborList = del.getBgpNeighbor();
179 BgpNeighbor gateway = bgpNeighborList.get(0);
181 if(gateway != null) {
182 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)) {
183 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();
184 LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
186 configureBgpServer(BgpOp.DEL_NGHBR);
188 bgpConfiguration.setNeighbourIp("");
189 bgpConfiguration.setNeighbourAsNum(0);
197 protected void remove(InstanceIdentifier<BgpNeighbors> identifier,
200 LOG.info("Bgp Neighbors deleted in DS - " + "key: " + identifier + ", value=" + del);
201 removeBgpNeighbors(del);
204 private synchronized void updateBgpNeighbors(BgpNeighbors original, BgpNeighbors update) {
206 List<BgpNeighbor> bgpNeighborList = update.getBgpNeighbor();
208 //handle the case where there are no neighbors configured - single neighbor entry has been deleted
209 if(bgpNeighborList.isEmpty()) {
210 configureBgpServer(BgpOp.DEL_NGHBR);
214 //We will always consider the first element of this list, since there can be just one DC Gateway
215 BgpNeighbor gateway = bgpNeighborList.get(0);
217 if(gateway != null) {
218 if(gateway.getAsNumber() != null ||
219 ((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))) {
220 //there is an updated neighbor, so we need to delete the old neighbor
221 configureBgpServer(BgpOp.DEL_NGHBR);
223 if(gateway.getAsNumber() != null) {
224 LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
225 if(bgpConfiguration.getNeighbourAsNum() != gateway.getAsNumber()) {
226 bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
227 bgpConfiguration.setConfigUpdated();
230 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)) {
231 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();
232 LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
233 if(bgpConfiguration.getNeighbourIp() != neighborIPAddr.getIpv4Address().getValue()) {
234 bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
235 bgpConfiguration.setConfigUpdated();
240 if(bgpConfiguration.isConfigUpdated()) {
241 //add the newly configured neighbor
242 configureBgpServer(BgpOp.ADD_NGHBR);
247 protected void update(InstanceIdentifier<BgpNeighbors> identifier,
248 BgpNeighbors original, BgpNeighbors update) {
250 LOG.info("Bgp Neighbors Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + update);
252 updateBgpNeighbors(original, update);
256 private synchronized void addBgpNeighbors(BgpNeighbors value) {
257 List<BgpNeighbor> bgpNeighborList = value.getBgpNeighbor();
259 //We will always consider the first element of this list, since there can be just one DC Gateway
260 BgpNeighbor gateway = bgpNeighborList.get(0);
262 if(gateway != null) {
263 if(gateway.getAsNumber() != null) {
264 LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
265 bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
267 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)) {
268 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();
269 LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
270 bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
273 if(bgpConfiguration.getNeighbourAsNum() != 0 && bgpConfiguration.getNeighbourIp() != null) {
274 configureBgpServer(BgpOp.ADD_NGHBR);
281 protected void add(InstanceIdentifier<BgpNeighbors> identifier,
282 BgpNeighbors value) {
283 LOG.info("key: " + identifier + ", value=" + value);
284 LOG.info("Bgp Neighbor added in DS - " + "key: " + identifier + ", value=" + value);
286 addBgpNeighbors(value);
289 private InstanceIdentifier<?> getWildCardPath() {
290 return InstanceIdentifier.create(BgpNeighbors.class);
295 public void close() throws Exception {
296 if (listenerRegistration != null) {
298 listenerRegistration.close();
299 } catch (final Exception e) {
300 LOG.error("Error when cleaning up DataChangeListener.", e);
302 listenerRegistration = null;
304 LOG.info("Bgp Neighbor Manager Closed");
309 private void configureBgpServer(BgpOp bgpOp) {
311 boolean retry = false;
316 bgpManager.startBgpService();
319 bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
322 bgpManager.deleteNeighbor(bgpConfiguration.getNeighbourIp());
325 LOG.info("Invalid configuration option");
329 } catch (TException t) {
333 } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);