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;
77 public static final int ignore = 0;
84 private static BgpOp bop;
86 public synchronized void disconnect() {
89 if (transport != null) {
94 public synchronized boolean connect(String bgpHost, int bgpPort) {
95 String msgPiece = "BGP config server at "+bgpHost+":"+bgpPort;
97 this.bgpHost = bgpHost;
98 this.bgpHostPort = bgpPort;
101 setConnectTS(System.currentTimeMillis());
103 TSocket ts = new TSocket(bgpHost, bgpPort, CONNECTION_TIMEOUT);
108 setLastConnectedTS(System.currentTimeMillis());
109 } catch (TTransportException tte) {
110 LOGGER.error("Failed connecting to " + msgPiece + "; Exception: " + tte);
114 protocol = new TBinaryProtocol(transport);
115 bgpClient = new BgpConfigurator.Client(protocol);
116 LOGGER.info("Connected to "+msgPiece);
120 public boolean isBgpConnected() {
124 private BgpRouter() {
128 private static BgpRouter br = null;
130 public static synchronized BgpRouter getInstance() {
131 return (br == null ? br = new BgpRouter() : br);
134 private void dispatch(BgpOp op) throws TException, BgpRouterException {
137 if (bgpClient == null) {
138 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
143 setStartTS(System.currentTimeMillis());
144 LOGGER.debug("startBgp thrift call for AsId {}",op.asNumber);
145 result = bgpClient.startBgp(op.ints[0], op.strs[0],
146 op.ignore, op.ignore, op.ignore, op.ints[1], op.add);
147 LOGGER.debug("Result of startBgp thrift call for AsId {} : {}",op.asNumber,result);
148 startBGPresult = result;
151 result = bgpClient.stopBgp(op.ints[0]);
155 bgpClient.createPeer(op.strs[0], op.ints[0])
156 : bgpClient.deletePeer(op.strs[0]);
160 bgpClient.addVrf(op.strs[0], op.irts, op.erts)
161 : bgpClient.delVrf(op.strs[0]);
164 // order of args is different in addPrefix(), hence the
165 // seeming out-of-order-ness of string indices
167 bgpClient.pushRoute(op.strs[1], op.strs[2],
168 op.strs[0], op.ints[0])
169 : bgpClient.withdrawRoute(op.strs[1], op.strs[0]);
172 result = bgpClient.setLogConfig(op.strs[0], op.strs[1]);
176 bgpClient.setEbgpMultihop(op.strs[0], op.ints[0])
177 : bgpClient.unsetEbgpMultihop(op.strs[0]);
181 bgpClient.setUpdateSource(op.strs[0], op.strs[1])
182 : bgpClient.unsetUpdateSource(op.strs[0]);
186 af_afi afi = af_afi.findByValue(op.ints[0]);
187 af_safi safi = af_safi.findByValue(op.ints[1]);
189 bgpClient.enableAddressFamily(op.strs[0], afi, safi)
190 : bgpClient.disableAddressFamily(op.strs[0], afi, safi);
194 bgpClient.enableGracefulRestart(op.ints[0])
195 : bgpClient.disableGracefulRestart();
199 throw new BgpRouterException(result);
203 public synchronized void startBgp(int asNum, String rtrId, int stalepathTime, boolean announceFbit)
204 throws TException, BgpRouterException {
205 bop.type = Optype.START;
206 bop.add = announceFbit;
208 bop.ints[1] = stalepathTime;
210 LOGGER.debug("Starting BGP with as number {} and router ID {} StalePathTime: {}", asNum, rtrId, stalepathTime);
214 public synchronized void stopBgp(int asNum)
215 throws TException, BgpRouterException {
216 bop.type = Optype.STOP;
218 LOGGER.debug("Stopping BGP with as number {}", asNum);
222 public synchronized void addNeighbor(String nbrIp, int nbrAsNum) throws TException, BgpRouterException {
223 bop.type = Optype.NBR;
226 bop.ints[0] = nbrAsNum;
227 LOGGER.debug("Adding BGP Neighbor {} with as number {} ", nbrIp, nbrAsNum);
231 public synchronized void delNeighbor(String nbrIp) throws TException, BgpRouterException {
232 bop.type = Optype.NBR;
235 LOGGER.debug("Deleting BGP Neighbor {} ", nbrIp);
239 public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
240 throws TException, BgpRouterException {
241 bop.type = Optype.VRF;
246 LOGGER.debug("Adding BGP VRF rd: {} ", rd);
250 public synchronized void delVrf(String rd) throws TException, BgpRouterException {
251 bop.type = Optype.VRF;
254 LOGGER.debug("Deleting BGP VRF rd: {} " + rd);
258 // bit of a mess-up: the order of arguments is different in
259 // the Thrift RPC: prefix-nexthop-rd-label.
261 public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
262 throws TException, BgpRouterException {
263 bop.type = Optype.PFX;
266 bop.strs[1] = prefix;
267 bop.strs[2] = nexthop;
269 LOGGER.debug("Adding BGP route - rd:{} prefix:{} nexthop:{} label:{} ", rd ,prefix, nexthop, label);
273 public synchronized void delPrefix(String rd, String prefix) throws TException, BgpRouterException {
274 bop.type = Optype.PFX;
277 bop.strs[1] = prefix;
278 LOGGER.debug("Deleting BGP route - rd:{} prefix:{} ", rd, prefix);
282 public int initRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
283 if (bgpClient == null) {
284 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
286 if (handle.getState() == BgpSyncHandle.ITERATING) {
287 return BgpRouterException.BGP_ERR_IN_ITER;
289 handle.setState(BgpSyncHandle.INITED);
294 public int endRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
295 if (bgpClient == null) {
296 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
298 int state = handle.getState();
300 case BgpSyncHandle.INITED:
301 case BgpSyncHandle.ITERATING:
302 handle.setState(BgpSyncHandle.ABORTED);
304 case BgpSyncHandle.DONE:
306 case BgpSyncHandle.NEVER_DONE:
307 return BgpRouterException.BGP_ERR_NOT_ITER;
314 public Routes doRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
315 if (bgpClient == null) {
316 throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
318 int state = handle.getState();
319 if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
320 Routes r = new Routes();
321 r.setErrcode(BgpRouterException.BGP_ERR_NOT_ITER);
324 int op = (state == BgpSyncHandle.INITED) ?
325 GET_RTS_INIT : GET_RTS_NEXT;
326 handle.setState(BgpSyncHandle.ITERATING);
327 int winSize = handle.getMaxCount()*handle.getRouteSize();
328 Routes outRoutes = bgpClient.getRoutes(op, winSize);
329 if (outRoutes.errcode != 0) {
332 handle.setMore(outRoutes.more);
333 if (outRoutes.more == 0) {
334 handle.setState(BgpSyncHandle.DONE);
339 public synchronized void setLogging(String fileName, String debugLevel) throws TException, BgpRouterException {
340 bop.type = Optype.LOG;
341 bop.strs[0] = fileName;
342 bop.strs[1] = debugLevel;
343 LOGGER.debug("Setting Log file to BGP VRF rd: {} ", fileName, debugLevel);
347 public synchronized void addEbgpMultihop(String nbrIp, int nhops) throws TException, BgpRouterException {
348 bop.type = Optype.MHOP;
352 LOGGER.debug("ebgp-multihop set for peer {}, num hops = {}",
357 public synchronized void delEbgpMultihop(String nbrIp) throws TException, BgpRouterException {
358 bop.type = Optype.MHOP;
361 LOGGER.debug("ebgp-multihop deleted for peer {}", nbrIp);
365 public synchronized void addUpdateSource(String nbrIp, String srcIp) throws TException, BgpRouterException {
366 bop.type = Optype.SRC;
370 LOGGER.debug("update-source added for peer {}, src-ip = {}",
375 public synchronized void delUpdateSource(String nbrIp) throws TException, BgpRouterException {
376 bop.type = Optype.SRC;
379 LOGGER.debug("update-source deleted for peer {}", nbrIp);
383 public synchronized void addAddressFamily(String nbrIp, af_afi afi, af_safi safi)
384 throws TException, BgpRouterException {
385 bop.type = Optype.AF;
388 bop.ints[0] = afi.getValue();
389 bop.ints[1] = safi.getValue();
390 LOGGER.debug("addr family added for peer {}, afi = {}, safi = {}",
391 nbrIp, bop.ints[0], bop.ints[1]);
395 public synchronized void delAddressFamily(String nbrIp, af_afi afi, af_safi safi)
396 throws TException, BgpRouterException {
397 bop.type = Optype.AF;
400 bop.ints[0] = afi.getValue();
401 bop.ints[1] = safi.getValue();
402 LOGGER.debug("addr family deleted for peer {}, afi = {}, safi = {}",
403 nbrIp, bop.ints[0], bop.ints[1]);
407 public synchronized void addGracefulRestart(int stalepathTime) throws TException, BgpRouterException {
408 bop.type = Optype.GR;
410 bop.ints[0] = stalepathTime;
411 LOGGER.debug("graceful restart added, stale-path-time = {}",
416 public synchronized void delGracefulRestart() throws TException, BgpRouterException {
417 bop.type = Optype.GR;
419 LOGGER.debug("graceful restart deleted");