208570d663edf45b61b5aa453a9942d497699e33
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / thrift / client / implementation / 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.implementation;
10
11 import org.apache.thrift.TException;
12 import org.apache.thrift.transport.TTransport;
13 import org.apache.thrift.transport.TSocket;
14 import org.apache.thrift.protocol.TBinaryProtocol;
15 import org.apache.thrift.protocol.TProtocol;
16 import java.util.*;
17
18 import org.opendaylight.bgpmanager.thrift.client.globals.Route;
19 import org.opendaylight.bgpmanager.thrift.common.Constants;
20 import org.opendaylight.bgpmanager.thrift.gen.*;
21 import org.opendaylight.bgpmanager.thrift.exceptions.BgpRouterException;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25
26 public class BgpRouter {
27     private TTransport transport;
28     private TProtocol protocol;
29     private static BgpConfigurator.Client bgpClient=null;
30     private static final Logger LOGGER = LoggerFactory.getLogger(BgpRouter.class);
31
32
33     private final static int ADD_NBR = 1;
34     private final static int DEL_NBR = 2;
35     private final static int ADD_VRF = 3;
36     private final static int DEL_VRF = 4;
37     private final static int ADD_PFX = 5;
38     private final static int DEL_PFX = 6;
39     private final static int START_BGP = 7;
40
41     private final static int GET_RTS_INIT = 0;
42     private final static int GET_RTS_NEXT = 1;
43
44
45     private class BgpOp {
46         public int type;
47         public String nbrIp;
48         public int nbrAsNum;
49         public String rd;
50         public List<String> irts;
51         public List<String> erts;
52         public String pfx;
53         public String nh;
54         public int lbl;
55         public int asNum;
56         public String rtrId;
57         public static final int ignore = 0;
58         public BgpOp() {}
59     }
60
61     static BgpOp bop = null;
62
63     private String bgpHost;
64     private int bgpPort;
65
66     public BgpRouter() {
67     }
68
69
70     public void setBgpServer(String host, int port) {
71         this.bgpHost = host;
72         this.bgpPort = port;
73     }
74
75     public void connect(String bgpHost, int bgpPort)
76         throws TException, BgpRouterException {
77         this.bgpHost = bgpHost;
78         this.bgpPort = bgpPort;
79         bop = new BgpOp();
80         try {
81             LOGGER.debug("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
82             reInit();
83         } catch (Exception e) {
84             LOGGER.error("Failed connecting to BGP server ");
85             throw e;
86         }
87     }
88
89     public void disconnect() {
90         if(transport != null) {
91             transport.close();
92         }
93     }
94
95     public void reInit()
96         throws TException, BgpRouterException {
97         if(transport != null) {
98             transport.close();
99         }
100         transport = new TSocket(bgpHost, bgpPort);
101         ((TSocket)transport).setTimeout(Constants.CL_SKT_TIMEO_MS);
102         transport.open();
103         protocol = new TBinaryProtocol(transport);
104         bgpClient = new BgpConfigurator.Client(protocol);
105         if(bop == null) {
106             bop = new BgpOp();
107         }
108     }
109
110     private void dispatch(BgpOp op)
111         throws TException, BgpRouterException {
112         int result = 1;
113
114         if (bgpClient == null) {
115             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
116         }
117
118         switch (op.type) {
119             case START_BGP:
120                 result = bgpClient.startBgpServer(op.asNum, op.rtrId,
121                     op.ignore, op.ignore, op.ignore);
122                 break;
123             case ADD_NBR:
124                 result = bgpClient.createPeer(op.nbrIp, op.nbrAsNum);
125                 break;
126             case DEL_NBR:
127                 result = bgpClient.deletePeer(op.nbrIp);
128                 break;
129             case ADD_VRF:
130                 result = bgpClient.addVrf(op.rd, op.irts, op.erts);
131                 break;
132             case DEL_VRF:
133                 result = bgpClient.delVrf(op.rd);
134                 break;
135             case ADD_PFX:
136                 result = bgpClient.pushRoute(op.pfx, op.nh, op.rd, op.lbl);
137                 break;
138             case DEL_PFX:
139                 result = bgpClient.withdrawRoute(op.pfx, op.rd);
140                 break;
141             default: break;
142         }
143         if (result != 0) {
144             throw new BgpRouterException(result);
145         }
146     }
147
148     public void startBgp(int asNum, String rtrId)
149         throws TException, BgpRouterException {
150         bop.type = START_BGP;
151         bop.asNum = asNum;
152         bop.rtrId = rtrId;
153         LOGGER.debug("Starting BGP Server with as number {} and router ID {} ", asNum, rtrId);
154         dispatch(bop);
155     }
156
157     public synchronized void addNeighbor(String nbrIp, int nbrAsNum)
158         throws TException, BgpRouterException {
159         bop.type = ADD_NBR;
160         bop.nbrIp = nbrIp;
161         bop.nbrAsNum = nbrAsNum;
162         LOGGER.debug("Adding BGP Neighbor {} with as number {} ", nbrIp, nbrAsNum);
163         dispatch(bop);
164     }
165
166     public synchronized void delNeighbor(String nbrIp)
167         throws TException, BgpRouterException {
168         bop.type = DEL_NBR;
169         bop.nbrIp = nbrIp;
170         LOGGER.debug("Deleting BGP Neighbor {} ", nbrIp);
171         dispatch(bop);
172     }
173
174     public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
175         throws TException, BgpRouterException {
176         bop.type = ADD_VRF;
177         bop.rd = rd;
178         bop.irts = irts;
179         bop.erts = erts;
180         LOGGER.debug("Adding BGP VRF rd: {} ", rd);
181         dispatch(bop);
182     }
183
184     public synchronized void delVrf(String rd)
185         throws TException, BgpRouterException {
186         bop.type = DEL_VRF;
187         bop.rd = rd;
188         LOGGER.debug("Deleting BGP VRF rd: {} " + rd);
189         dispatch(bop);
190     }
191
192     public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
193         throws TException, BgpRouterException {
194         bop.type = ADD_PFX;
195         bop.rd = rd;
196         bop.pfx = prefix;
197         bop.nh = nexthop;
198         bop.lbl = label;
199         LOGGER.debug("Adding BGP route - rd:{} prefix:{} nexthop:{} label:{} ", rd ,prefix, nexthop, label);
200         dispatch(bop);
201     }
202
203     public synchronized void delPrefix(String rd, String prefix)
204         throws TException, BgpRouterException {
205         bop.type = DEL_PFX;
206         bop.rd = rd;
207         bop.pfx = prefix;
208         LOGGER.debug("Deleting BGP route - rd:{} prefix:{} ", rd, prefix);
209         dispatch(bop);
210     }
211
212     public int initRibSync(BgpSyncHandle handle)
213         throws TException, BgpRouterException {
214         if (bgpClient == null) {
215             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
216         }
217         if (handle.getState() == BgpSyncHandle.ITERATING) {
218             return BgpRouterException.BGP_ERR_IN_ITER;
219         }
220         handle.setState(BgpSyncHandle.INITED);
221         handle.setMore(1);
222         return 0;
223     }
224
225     public int endRibSync(BgpSyncHandle handle)
226         throws TException, BgpRouterException {
227         if (bgpClient == null) {
228             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
229         }
230         int state = handle.getState();
231         switch (state) {
232             case BgpSyncHandle.INITED:
233             case BgpSyncHandle.ITERATING:
234                 handle.setState(BgpSyncHandle.ABORTED);
235                 break;
236             case BgpSyncHandle.DONE:
237                 break;
238             case BgpSyncHandle.NEVER_DONE:
239                 return BgpRouterException.BGP_ERR_NOT_ITER;
240             default:
241                 break;
242         }
243         return 0;
244     }
245
246     public Routes doRibSync(BgpSyncHandle handle)
247         throws TException, BgpRouterException {
248         if (bgpClient == null) {
249             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
250         }
251         int state = handle.getState();
252         if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
253             Routes r = new Routes();
254             r.setErrcode(BgpRouterException.BGP_ERR_NOT_ITER);
255             return r;
256         }
257         int op = (state == BgpSyncHandle.INITED) ?
258             GET_RTS_INIT : GET_RTS_NEXT;
259         handle.setState(BgpSyncHandle.ITERATING);
260         int winSize = handle.getMaxCount()*handle.getRouteSize();
261         Routes outRoutes = bgpClient.getRoutes(op, winSize);
262        if (outRoutes.errcode != 0) {
263            return outRoutes;
264        }
265         handle.setMore(outRoutes.more);
266         if (outRoutes.more == 0) {
267             handle.setState(BgpSyncHandle.DONE);
268         }
269         return outRoutes;
270     }
271
272     //We would support this only when we support controller restarts
273     public void doRouteSync()
274         throws TException, BgpRouterException {
275         BgpSyncHandle bsh = BgpSyncHandle.getInstance();
276
277         try {
278             LOGGER.debug("Starting BGP Route sync.. ");
279             initRibSync(bsh);
280             while (bsh.getState() != bsh.DONE) {
281                 Routes r = doRibSync(bsh);
282                 if(r.getErrcode() == BgpRouterException.BGP_ERR_INACTIVE) {
283                     //BGP server is inactive; log and return
284                     LOGGER.error("BGP Server is inactive. Failed BGP Route sync");
285                     return;
286                 }
287                 Iterator<Update> iter = r.getUpdatesIterator();
288                 while (iter.hasNext()) {
289                     Update u = iter.next();
290                     Route route = new Route(u.rd, u.prefix, u.prefixlen, u.nexthop, u.label);
291                     //Add to FIB??
292                     /*
293                     if(bgpRouteCb != null) {
294                         bgpRouteCb.setRoute(route);
295                     }*/
296                 }
297             }
298             endRibSync(bsh);
299             LOGGER.debug("Completed BGP Route sync.");
300         }  catch (Exception e) {
301             throw e;
302         }
303     };
304
305
306
307 }