Multiple fixes in various modules
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / thrift / client / BgpRouter.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.bgpmanager.thrift.client;
10
11 import java.util.*;
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;
21
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;
34
35     public long getLastConnectedTS() {
36         return lastConnectedTS;
37     }
38
39     public void setLastConnectedTS(long lastConnectedTS) {
40         this.lastConnectedTS = lastConnectedTS;
41     }
42
43     public long getConnectTS() {
44         return connectTS;
45     }
46
47     public void setConnectTS(long connectTS) {
48         this.connectTS = connectTS;
49     }
50
51     public long getStartTS() {
52         return startTS;
53     }
54
55     public void setStartTS(long startTS) {
56         this.startTS = startTS;
57     }
58
59
60     private enum Optype {
61         START, STOP, NBR, VRF, PFX, SRC, MHOP, LOG, AF, GR
62     };
63
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;
67
68
69     private class BgpOp {
70         public Optype type;
71         public boolean add;
72         public String[] strs;
73         public int[] ints;
74         public List<String> irts;
75         public List<String> erts;
76         public long asNumber;
77         public static final int ignore = 0;
78         public BgpOp() {
79             strs = new String[3];
80             ints = new int[2];
81         }
82     }
83
84     private static BgpOp bop;
85
86     public synchronized void disconnect() {
87         bgpClient = null;
88         isConnected = false;
89         if (transport != null) {
90             transport.close();
91         }
92     }
93
94     public synchronized boolean connect(String bgpHost, int bgpPort) {
95         String msgPiece = "BGP config server at "+bgpHost+":"+bgpPort;
96
97         this.bgpHost = bgpHost;
98         this.bgpHostPort = bgpPort;
99
100         disconnect();
101         setConnectTS(System.currentTimeMillis());
102         try {
103             TSocket ts = new TSocket(bgpHost, bgpPort, CONNECTION_TIMEOUT);
104             transport = ts;
105             transport.open();
106             ts.setTimeout(0);
107             isConnected = true;
108             setLastConnectedTS(System.currentTimeMillis());
109         } catch (TTransportException tte) {
110             LOGGER.error("Failed connecting to " + msgPiece + "; Exception: " + tte);
111             isConnected = false;
112             return false;
113         }
114         protocol = new TBinaryProtocol(transport);
115         bgpClient = new BgpConfigurator.Client(protocol);
116         LOGGER.info("Connected to "+msgPiece);
117         return true;
118     }
119
120     public boolean isBgpConnected() {
121         return isConnected;
122     }
123
124     private BgpRouter() {
125         bop = new BgpOp();
126     }
127
128     private static BgpRouter br = null;
129
130     public static synchronized BgpRouter getInstance() {
131         return (br == null ? br = new BgpRouter() : br);
132     }
133
134     private void dispatch(BgpOp op) throws TException, BgpRouterException {
135         int result = 1;
136
137         if (bgpClient == null) {
138             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
139         }
140
141         switch (op.type) {
142             case START:
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;
149                 break;
150             case STOP:
151                 result = bgpClient.stopBgp(op.ints[0]);
152                 break;
153             case NBR:
154                 result = bop.add ?
155                         bgpClient.createPeer(op.strs[0], op.ints[0])
156                         : bgpClient.deletePeer(op.strs[0]);
157                 break;
158             case VRF:
159                 result = bop.add ?
160                         bgpClient.addVrf(op.strs[0], op.irts, op.erts)
161                         : bgpClient.delVrf(op.strs[0]);
162                 break;
163             case PFX:
164                 // order of args is different in addPrefix(), hence the
165                 // seeming out-of-order-ness of string indices
166                 result = bop.add ?
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]);
170                 break;
171             case LOG:
172                 result = bgpClient.setLogConfig(op.strs[0], op.strs[1]);
173                 break;
174             case MHOP:
175                 result = bop.add ?
176                         bgpClient.setEbgpMultihop(op.strs[0], op.ints[0])
177                         : bgpClient.unsetEbgpMultihop(op.strs[0]);
178                 break;
179             case SRC:
180                 result = bop.add ?
181                         bgpClient.setUpdateSource(op.strs[0], op.strs[1])
182                         : bgpClient.unsetUpdateSource(op.strs[0]);
183                 break;
184             default: break;
185             case AF:
186                 af_afi afi = af_afi.findByValue(op.ints[0]);
187                 af_safi safi = af_safi.findByValue(op.ints[1]);
188                 result = bop.add ?
189                         bgpClient.enableAddressFamily(op.strs[0], afi, safi)
190                         : bgpClient.disableAddressFamily(op.strs[0], afi, safi);
191                 break;
192             case GR:
193                 result = bop.add ?
194                         bgpClient.enableGracefulRestart(op.ints[0])
195                         : bgpClient.disableGracefulRestart();
196                 break;
197         }
198         if (result != 0) {
199             throw new BgpRouterException(result);
200         }
201     }
202
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;
207         bop.ints[0] = asNum;
208         bop.ints[1] = stalepathTime;
209         bop.strs[0] = rtrId;
210         LOGGER.debug("Starting BGP with as number {} and router ID {} StalePathTime: {}", asNum, rtrId, stalepathTime);
211         dispatch(bop);
212     }
213
214     public synchronized void stopBgp(int asNum)
215             throws TException, BgpRouterException {
216         bop.type = Optype.STOP;
217         bop.ints[0] = asNum;
218         LOGGER.debug("Stopping BGP with as number {}", asNum);
219         dispatch(bop);
220     }
221
222     public synchronized void addNeighbor(String nbrIp, int nbrAsNum) throws TException, BgpRouterException {
223         bop.type = Optype.NBR;
224         bop.add = true;
225         bop.strs[0] = nbrIp;
226         bop.ints[0] = nbrAsNum;
227         LOGGER.debug("Adding BGP Neighbor {} with as number {} ", nbrIp, nbrAsNum);
228         dispatch(bop);
229     }
230
231     public synchronized void delNeighbor(String nbrIp) throws TException, BgpRouterException {
232         bop.type = Optype.NBR;
233         bop.add = false;
234         bop.strs[0] = nbrIp;
235         LOGGER.debug("Deleting BGP Neighbor {} ", nbrIp);
236         dispatch(bop);
237     }
238
239     public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
240             throws TException, BgpRouterException {
241         bop.type = Optype.VRF;
242         bop.add = true;
243         bop.strs[0] = rd;
244         bop.irts = irts;
245         bop.erts = erts;
246         LOGGER.debug("Adding BGP VRF rd: {} ", rd);
247         dispatch(bop);
248     }
249
250     public synchronized void delVrf(String rd) throws TException, BgpRouterException {
251         bop.type = Optype.VRF;
252         bop.add = false;
253         bop.strs[0] = rd;
254         LOGGER.debug("Deleting BGP VRF rd: {} " + rd);
255         dispatch(bop);
256     }
257
258     // bit of a mess-up: the order of arguments is different in
259     // the Thrift RPC: prefix-nexthop-rd-label.
260
261     public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
262             throws TException, BgpRouterException {
263         bop.type = Optype.PFX;
264         bop.add = true;
265         bop.strs[0] = rd;
266         bop.strs[1] = prefix;
267         bop.strs[2] = nexthop;
268         bop.ints[0] = label;
269         LOGGER.debug("Adding BGP route - rd:{} prefix:{} nexthop:{} label:{} ", rd ,prefix, nexthop, label);
270         dispatch(bop);
271     }
272
273     public synchronized void delPrefix(String rd, String prefix) throws TException, BgpRouterException {
274         bop.type = Optype.PFX;
275         bop.add = false;
276         bop.strs[0] = rd;
277         bop.strs[1] = prefix;
278         LOGGER.debug("Deleting BGP route - rd:{} prefix:{} ", rd, prefix);
279         dispatch(bop);
280     }
281
282     public int initRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
283         if (bgpClient == null) {
284             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
285         }
286         if (handle.getState() == BgpSyncHandle.ITERATING) {
287             return BgpRouterException.BGP_ERR_IN_ITER;
288         }
289         handle.setState(BgpSyncHandle.INITED);
290         handle.setMore(1);
291         return 0;
292     }
293
294     public int endRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
295         if (bgpClient == null) {
296             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
297         }
298         int state = handle.getState();
299         switch (state) {
300             case BgpSyncHandle.INITED:
301             case BgpSyncHandle.ITERATING:
302                 handle.setState(BgpSyncHandle.ABORTED);
303                 break;
304             case BgpSyncHandle.DONE:
305                 break;
306             case BgpSyncHandle.NEVER_DONE:
307                 return BgpRouterException.BGP_ERR_NOT_ITER;
308             default:
309                 break;
310         }
311         return 0;
312     }
313
314     public Routes doRibSync(BgpSyncHandle handle) throws TException, BgpRouterException {
315         if (bgpClient == null) {
316             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
317         }
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);
322             return r;
323         }
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) {
330             return outRoutes;
331         }
332         handle.setMore(outRoutes.more);
333         if (outRoutes.more == 0) {
334             handle.setState(BgpSyncHandle.DONE);
335         }
336         return outRoutes;
337     }
338
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);
344         dispatch(bop);
345     }
346
347     public synchronized void addEbgpMultihop(String nbrIp, int nhops) throws TException, BgpRouterException {
348         bop.type = Optype.MHOP;
349         bop.add = true;
350         bop.strs[0] = nbrIp;
351         bop.ints[0] = nhops;
352         LOGGER.debug("ebgp-multihop set for peer {}, num hops = {}",
353                 nbrIp, nhops);
354         dispatch(bop);
355     }
356
357     public synchronized void delEbgpMultihop(String nbrIp) throws TException, BgpRouterException {
358         bop.type = Optype.MHOP;
359         bop.add = false;
360         bop.strs[0] = nbrIp;
361         LOGGER.debug("ebgp-multihop deleted for peer {}", nbrIp);
362         dispatch(bop);
363     }
364
365     public synchronized void addUpdateSource(String nbrIp, String srcIp) throws TException, BgpRouterException {
366         bop.type = Optype.SRC;
367         bop.add = true;
368         bop.strs[0] = nbrIp;
369         bop.strs[1] = srcIp;
370         LOGGER.debug("update-source added for peer {}, src-ip = {}",
371                 nbrIp, srcIp);
372         dispatch(bop);
373     }
374
375     public synchronized void delUpdateSource(String nbrIp) throws TException, BgpRouterException {
376         bop.type = Optype.SRC;
377         bop.add = false;
378         bop.strs[0] = nbrIp;
379         LOGGER.debug("update-source deleted for peer {}", nbrIp);
380         dispatch(bop);
381     }
382
383     public synchronized void addAddressFamily(String nbrIp, af_afi afi, af_safi safi)
384             throws TException, BgpRouterException {
385         bop.type = Optype.AF;
386         bop.add = true;
387         bop.strs[0] = nbrIp;
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]);
392         dispatch(bop);
393     }
394
395     public synchronized void delAddressFamily(String nbrIp, af_afi afi, af_safi safi)
396             throws TException, BgpRouterException {
397         bop.type = Optype.AF;
398         bop.add = false;
399         bop.strs[0] = nbrIp;
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]);
404         dispatch(bop);
405     }
406
407     public synchronized void addGracefulRestart(int stalepathTime) throws TException, BgpRouterException {
408         bop.type = Optype.GR;
409         bop.add = true;
410         bop.ints[0] = stalepathTime;
411         LOGGER.debug("graceful restart added, stale-path-time = {}",
412                 stalepathTime);
413         dispatch(bop);
414     }
415
416     public synchronized void delGracefulRestart() throws TException, BgpRouterException {
417         bop.type = Optype.GR;
418         bop.add = false;
419         LOGGER.debug("graceful restart deleted");
420         dispatch(bop);
421     }
422 }