2 * Copyright (c) 2016 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
9 package org.opendaylight.netvirt.bgpmanager.thrift.client;
12 import org.apache.thrift.protocol.TBinaryProtocol;
13 import org.apache.thrift.protocol.TProtocol;
14 import org.apache.thrift.TException;
15 import org.apache.thrift.transport.TSocket;
16 import org.apache.thrift.transport.TTransport;
17 import org.apache.thrift.transport.TTransportException;
18 import org.opendaylight.netvirt.bgpmanager.thrift.gen.*;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 public class BgpRouter {
23 private static TTransport transport;
24 private static TProtocol protocol;
25 private static BgpConfigurator.Client bgpClient=null;
26 boolean isConnected = false;
27 private static final Logger LOGGER = LoggerFactory.getLogger(BgpRouter.class);
28 public int startBGPresult = Integer.MIN_VALUE;
29 public String bgpHost = null;
30 public int bgpHostPort = 0;
31 private long startTS = 0;
32 private long connectTS = 0;
33 private long lastConnectedTS = 0;
35 public long getLastConnectedTS() {
36 return lastConnectedTS;
39 public void setLastConnectedTS(long lastConnectedTS) {
40 this.lastConnectedTS = lastConnectedTS;
43 public long getConnectTS() {
47 public void setConnectTS(long connectTS) {
48 this.connectTS = connectTS;
51 public long getStartTS() {
55 public void setStartTS(long startTS) {
56 this.startTS = startTS;
61 START, STOP, NBR, VRF, PFX, SRC, MHOP, LOG, AF, GR
64 private final static int GET_RTS_INIT = 0;
65 private final static int GET_RTS_NEXT = 1;
66 private final static int CONNECTION_TIMEOUT = 60000;
74 public List<String> irts;
75 public List<String> erts;
76 public static final int ignore = 0;
83 private static BgpOp bop;
85 public synchronized void disconnect() {
88 if (transport != null) {
93 public synchronized boolean connect(String bgpHost, int bgpPort) {
94 String msgPiece = "BGP config server at "+bgpHost+":"+bgpPort;
96 this.bgpHost = bgpHost;
97 this.bgpHostPort = bgpPort;
100 setConnectTS(System.currentTimeMillis());
102 TSocket ts = new TSocket(bgpHost, bgpPort, CONNECTION_TIMEOUT);
107 setLastConnectedTS(System.currentTimeMillis());
108 } catch (TTransportException tte) {
109 LOGGER.error("Failed connecting to " + msgPiece + "; Exception: " + tte);
113 protocol = new TBinaryProtocol(transport);
114 bgpClient = new BgpConfigurator.Client(protocol);
115 LOGGER.info("Connected to "+msgPiece);
119 public boolean isBgpConnected() {
123 private BgpRouter() {
127 private static BgpRouter br = null;
129 public static synchronized BgpRouter getInstance() {
130 return (br == null ? br = new BgpRouter() : br);
133 private void dispatch(BgpOp op) throws TException, BgpRouterException {
136 if (bgpClient == null) {
137 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
142 setStartTS(System.currentTimeMillis());
143 result = bgpClient.startBgp(op.ints[0], op.strs[0],
144 op.ignore, op.ignore, op.ignore, op.ints[1], op.add);
145 startBGPresult = result;
148 result = bgpClient.stopBgp(op.ints[0]);
152 bgpClient.createPeer(op.strs[0], op.ints[0])
153 : bgpClient.deletePeer(op.strs[0]);
157 bgpClient.addVrf(op.strs[0], op.irts, op.erts)
158 : bgpClient.delVrf(op.strs[0]);
161 // order of args is different in addPrefix(), hence the
162 // seeming out-of-order-ness of string indices
164 bgpClient.pushRoute(op.strs[1], op.strs[2],
165 op.strs[0], op.ints[0])
166 : bgpClient.withdrawRoute(op.strs[1], op.strs[0]);
169 result = bgpClient.setLogConfig(op.strs[0], op.strs[1]);
173 bgpClient.setEbgpMultihop(op.strs[0], op.ints[0])
174 : bgpClient.unsetEbgpMultihop(op.strs[0]);
178 bgpClient.setUpdateSource(op.strs[0], op.strs[1])
179 : bgpClient.unsetUpdateSource(op.strs[0]);
183 af_afi afi = af_afi.findByValue(op.ints[0]);
184 af_safi safi = af_safi.findByValue(op.ints[1]);
186 bgpClient.enableAddressFamily(op.strs[0], afi, safi)
187 : bgpClient.disableAddressFamily(op.strs[0], afi, safi);
191 bgpClient.enableGracefulRestart(op.ints[0])
192 : bgpClient.disableGracefulRestart();
196 throw new BgpRouterException(result);
200 public synchronized void startBgp(int asNum, String rtrId, int stalepathTime, boolean announceFbit)
201 throws TException, BgpRouterException {
202 bop.type = Optype.START;
203 bop.add = announceFbit;
205 bop.ints[1] = stalepathTime;
207 LOGGER.debug("Starting BGP with as number {} and router ID {} StalePathTime: {}", asNum, rtrId, stalepathTime);
211 public synchronized void stopBgp(int asNum)
212 throws TException, BgpRouterException {
213 bop.type = Optype.STOP;
215 LOGGER.debug("Stopping BGP with as number {}", asNum);
219 public synchronized void addNeighbor(String nbrIp, int nbrAsNum) throws TException, BgpRouterException {
220 bop.type = Optype.NBR;
223 bop.ints[0] = nbrAsNum;
224 LOGGER.debug("Adding BGP Neighbor {} with as number {} ", nbrIp, nbrAsNum);
228 public synchronized void delNeighbor(String nbrIp) throws TException, BgpRouterException {
229 bop.type = Optype.NBR;
232 LOGGER.debug("Deleting BGP Neighbor {} ", nbrIp);
236 public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
237 throws TException, BgpRouterException {
238 bop.type = Optype.VRF;
243 LOGGER.debug("Adding BGP VRF rd: {} ", rd);
247 public synchronized void delVrf(String rd) throws TException, BgpRouterException {
248 bop.type = Optype.VRF;
251 LOGGER.debug("Deleting BGP VRF rd: {} " + rd);
255 // bit of a mess-up: the order of arguments is different in
256 // the Thrift RPC: prefix-nexthop-rd-label.
258 public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
259 throws TException, BgpRouterException {
260 bop.type = Optype.PFX;
263 bop.strs[1] = prefix;
264 bop.strs[2] = nexthop;
266 LOGGER.debug("Adding BGP route - rd:{} prefix:{} nexthop:{} label:{} ", rd ,prefix, nexthop, label);
270 public synchronized void delPrefix(String rd, String prefix) throws TException, BgpRouterException {
271 bop.type = Optype.PFX;
274 bop.strs[1] = prefix;
275 LOGGER.debug("Deleting BGP route - rd:{} prefix:{} ", rd, prefix);
279 public int initRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
280 if (bgpClient == null) {
281 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
283 if (handle.getState() == BgpSyncHandle.ITERATING) {
284 return BgpRouterException.BGP_ERR_IN_ITER;
286 handle.setState(BgpSyncHandle.INITED);
291 public int endRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
292 if (bgpClient == null) {
293 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
295 int state = handle.getState();
297 case BgpSyncHandle.INITED:
298 case BgpSyncHandle.ITERATING:
299 handle.setState(BgpSyncHandle.ABORTED);
301 case BgpSyncHandle.DONE:
303 case BgpSyncHandle.NEVER_DONE:
304 return BgpRouterException.BGP_ERR_NOT_ITER;
311 public Routes doRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
312 if (bgpClient == null) {
313 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
315 int state = handle.getState();
316 if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
317 Routes r = new Routes();
318 r.setErrcode(BgpRouterException.BGP_ERR_NOT_ITER);
321 int op = (state == BgpSyncHandle.INITED) ?
322 GET_RTS_INIT : GET_RTS_NEXT;
323 handle.setState(BgpSyncHandle.ITERATING);
324 int winSize = handle.getMaxCount()*handle.getRouteSize();
325 Routes outRoutes = bgpClient.getRoutes(op, winSize);
326 if (outRoutes.errcode != 0) {
329 handle.setMore(outRoutes.more);
330 if (outRoutes.more == 0) {
331 handle.setState(BgpSyncHandle.DONE);
336 public synchronized void setLogging(String fileName, String debugLevel) throws TException, BgpRouterException {
337 bop.type = Optype.LOG;
338 bop.strs[0] = fileName;
339 bop.strs[1] = debugLevel;
340 LOGGER.debug("Setting Log file to BGP VRF rd: {} ", fileName, debugLevel);
344 public synchronized void addEbgpMultihop(String nbrIp, int nhops) throws TException, BgpRouterException {
345 bop.type = Optype.MHOP;
349 LOGGER.debug("ebgp-multihop set for peer {}, num hops = {}",
354 public synchronized void delEbgpMultihop(String nbrIp) throws TException, BgpRouterException {
355 bop.type = Optype.MHOP;
358 LOGGER.debug("ebgp-multihop deleted for peer {}", nbrIp);
362 public synchronized void addUpdateSource(String nbrIp, String srcIp) throws TException, BgpRouterException {
363 bop.type = Optype.SRC;
367 LOGGER.debug("update-source added for peer {}, src-ip = {}",
372 public synchronized void delUpdateSource(String nbrIp) throws TException, BgpRouterException {
373 bop.type = Optype.SRC;
376 LOGGER.debug("update-source deleted for peer {}", nbrIp);
380 public synchronized void addAddressFamily(String nbrIp, af_afi afi, af_safi safi)
381 throws TException, BgpRouterException {
382 bop.type = Optype.AF;
385 bop.ints[0] = afi.getValue();
386 bop.ints[1] = safi.getValue();
387 LOGGER.debug("addr family added for peer {}, afi = {}, safi = {}",
388 nbrIp, bop.ints[0], bop.ints[1]);
392 public synchronized void delAddressFamily(String nbrIp, af_afi afi, af_safi safi)
393 throws TException, BgpRouterException {
394 bop.type = Optype.AF;
397 bop.ints[0] = afi.getValue();
398 bop.ints[1] = safi.getValue();
399 LOGGER.debug("addr family deleted for peer {}, afi = {}, safi = {}",
400 nbrIp, bop.ints[0], bop.ints[1]);
404 public synchronized void addGracefulRestart(int stalepathTime) throws TException, BgpRouterException {
405 bop.type = Optype.GR;
407 bop.ints[0] = stalepathTime;
408 LOGGER.debug("graceful restart added, stale-path-time = {}",
413 public synchronized void delGracefulRestart() throws TException, BgpRouterException {
414 bop.type = Optype.GR;
416 LOGGER.debug("graceful restart deleted");