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