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