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