BgpManager Initial commit
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / thrift / client / implementation / BgpRouter.java
diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java
new file mode 100644 (file)
index 0000000..c10bb30
--- /dev/null
@@ -0,0 +1,317 @@
+package org.opendaylight.bgpmanager.thrift.client.implementation;
+
+import org.apache.thrift.TException;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import java.util.*;
+
+import org.opendaylight.bgpmanager.thrift.client.globals.Route;
+import org.opendaylight.bgpmanager.thrift.common.Constants;
+import org.opendaylight.bgpmanager.thrift.gen.*;
+import org.opendaylight.bgpmanager.thrift.exceptions.BgpRouterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class BgpRouter {
+    private TTransport transport;
+    private TSocket sock;
+    private TProtocol protocol;
+    private static BgpConfigurator.Client bgpClient=null;
+    private static final Logger logger = LoggerFactory.getLogger(BgpRouter.class);
+
+
+    private final static int ADD_NBR = 1;
+    private final static int DEL_NBR = 2;
+    private final static int ADD_VRF = 3;
+    private final static int DEL_VRF = 4;
+    private final static int ADD_PFX = 5;
+    private final static int DEL_PFX = 6;
+    private final static int START_BGP = 7;
+
+    //public final static int BGP_ERR_INITED = 101;
+    //public final static int BGP_ERR_NOT_INITED = 102;
+
+
+    private final static int GET_RTS_INIT = 0;
+    private final static int GET_RTS_NEXT = 1;
+
+
+    private class BgpOp {
+        public int type;
+        public String nbrIp;
+        public int nbrAsNum;
+        public String rd;
+        public List<String> irts;
+        public List<String> erts;
+        public String pfx;
+        public String nh;
+        public int lbl;
+        public int asNum;
+        public String rtrId;
+        public static final int ignore = 0;
+        public BgpOp() {}
+    }
+
+    static BgpOp bop = null;
+
+    private String bgpHost;
+    private int bgpPort;
+
+    public BgpRouter() {
+    }
+
+
+    public void setBgpServer(String host, int port) {
+        this.bgpHost = host;
+        this.bgpPort = port;
+    }
+
+    public void connect(String bgpHost, int bgpPort)
+        throws TException, BgpRouterException {
+        this.bgpHost = bgpHost;
+        this.bgpPort = bgpPort;
+        bop = new BgpOp();
+        try {
+            logger.info("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
+            reInit();
+        } catch (Exception e) {
+            logger.error("Failed connecting to BGP server ", e);
+            throw e;
+        }
+    }
+
+    public void disconnect() {
+        if(transport != null)
+            transport.close();
+    }
+
+    public void reInit()
+        throws TException, BgpRouterException {
+        if(transport != null)
+            transport.close();
+        transport = new TSocket(bgpHost, bgpPort);
+        ((TSocket)transport).setTimeout(Constants.CL_SKT_TIMEO_MS);
+        transport.open();
+        protocol = new TBinaryProtocol(transport);
+        bgpClient = new BgpConfigurator.Client(protocol);
+        if(bop == null)
+            bop = new BgpOp();
+    }
+
+    private void dispatch(BgpOp op)
+        throws TException, BgpRouterException {
+        int result = 1;
+
+        if (bgpClient == null)
+            throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+
+        switch (op.type) {
+            case START_BGP:
+                result = bgpClient.startBgpServer(op.asNum, op.rtrId,
+                    op.ignore, op.ignore, op.ignore);
+                break;
+            case ADD_NBR:
+                result = bgpClient.createPeer(op.nbrIp, op.nbrAsNum);
+                break;
+            case DEL_NBR:
+                result = bgpClient.deletePeer(op.nbrIp);
+                break;
+            case ADD_VRF:
+                result = bgpClient.addVrf(op.rd, op.irts, op.erts);
+                break;
+            case DEL_VRF:
+                result = bgpClient.delVrf(op.rd);
+                break;
+            case ADD_PFX:
+                result = bgpClient.pushRoute(op.pfx, op.nh, op.rd, op.lbl);
+                break;
+            case DEL_PFX:
+                result = bgpClient.withdrawRoute(op.pfx, op.rd);
+                break;
+            default: break;
+        }
+        if (result != 0) throw new BgpRouterException(result);
+    }
+
+    public void startBgp(int asNum, String rtrId)
+        throws TException, BgpRouterException {
+        bop.type = START_BGP;
+        bop.asNum = asNum;
+        bop.rtrId = rtrId;
+        logger.info("Starting BGP Server with as number " + asNum + " and router ID " + rtrId);
+        dispatch(bop);
+    }
+
+    public void addNeighbor(String nbrIp, int nbrAsNum)
+        throws TException, BgpRouterException {
+        bop.type = ADD_NBR;
+        bop.nbrIp = nbrIp;
+        bop.nbrAsNum = nbrAsNum;
+        logger.info("Adding BGP Neighbor " + nbrIp + " with as number " + nbrAsNum);
+        dispatch(bop);
+    }
+
+    public void delNeighbor(String nbrIp)
+        throws TException, BgpRouterException {
+        bop.type = DEL_NBR;
+        bop.nbrIp = nbrIp;
+        logger.info("Deleting BGP Neighbor " + nbrIp);
+        dispatch(bop);
+    }
+
+    public void addVrf(String rd, List<String> irts, List<String> erts)
+        throws TException, BgpRouterException {
+        bop.type = ADD_VRF;
+        bop.rd = rd;
+        bop.irts = irts;
+        bop.erts = erts;
+        logger.info("Adding BGP VRF rd: " + rd);
+        dispatch(bop);
+    }
+
+    public void delVrf(String rd)
+        throws TException, BgpRouterException {
+        bop.type = DEL_VRF;
+        bop.rd = rd;
+        logger.info("Deleting BGP VRF rd: " + rd);
+        dispatch(bop);
+    }
+
+    public void addPrefix(String rd, String prefix, String nexthop, int label)
+        throws TException, BgpRouterException {
+        bop.type = ADD_PFX;
+        bop.rd = rd;
+        bop.pfx = prefix;
+        bop.nh = nexthop;
+        bop.lbl = label;
+        logger.info("Adding BGP route - rd:" + rd + " prefix:" + prefix + " nexthop:" + nexthop + " label:" + label);
+        dispatch(bop);
+    }
+
+    public void delPrefix(String rd, String prefix)
+        throws TException, BgpRouterException {
+        bop.type = DEL_PFX;
+        bop.rd = rd;
+        bop.pfx = prefix;
+        logger.info("Deleting BGP route - rd:" + rd + " prefix:" + prefix);
+        dispatch(bop);
+    }
+
+    public int initRibSync(BgpSyncHandle handle)
+        throws TException, BgpRouterException {
+        if (bgpClient == null)
+            throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        if (handle.getState() == BgpSyncHandle.ITERATING)
+            return BgpRouterException.BGP_ERR_IN_ITER;
+        handle.setState(BgpSyncHandle.INITED);
+        handle.setMore(1);
+        return 0;
+    }
+
+    public int endRibSync(BgpSyncHandle handle)
+        throws TException, BgpRouterException {
+        if (bgpClient == null)
+            throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        int state = handle.getState();
+        switch (state) {
+            case BgpSyncHandle.INITED:
+            case BgpSyncHandle.ITERATING:
+                handle.setState(BgpSyncHandle.ABORTED);
+                break;
+            case BgpSyncHandle.DONE:
+                break;
+            case BgpSyncHandle.NEVER_DONE:
+                return BgpRouterException.BGP_ERR_NOT_ITER;
+            default:
+                break;
+        }
+        return 0;
+    }
+
+    public Routes doRibSync(BgpSyncHandle handle)
+        throws TException, BgpRouterException {
+        if (bgpClient == null)
+            throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        int state = handle.getState();
+        if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
+            Routes r = new Routes();
+            r.setErrcode(BgpRouterException.BGP_ERR_NOT_ITER);
+            return r;
+        }
+        int op = (state == BgpSyncHandle.INITED) ?
+            GET_RTS_INIT : GET_RTS_NEXT;
+        handle.setState(BgpSyncHandle.ITERATING);
+        int winSize = handle.getMaxCount()*handle.getRouteSize();
+        Routes outRoutes = bgpClient.getRoutes(op, winSize);
+       if (outRoutes.errcode != 0)
+            return outRoutes;
+        handle.setMore(outRoutes.more);
+        if (outRoutes.more == 0)
+            handle.setState(BgpSyncHandle.DONE);
+        return outRoutes;
+    }
+
+    //We would support this only when we support controller restarts
+    public void doRouteSync()
+        throws TException, BgpRouterException {
+        BgpSyncHandle bsh = BgpSyncHandle.getInstance();
+
+        try {
+            logger.info("Starting BGP Route sync.. ");
+            initRibSync(bsh);
+            while (bsh.getState() != bsh.DONE) {
+                Routes r = doRibSync(bsh);
+                if(r.getErrcode() == BgpRouterException.BGP_ERR_INACTIVE) {
+                    //BGP server is inactive; log and return
+                    logger.error("BGP Server is inactive. Failed BGP Route sync");
+                    return;
+                }
+                Iterator<Update> iter = r.getUpdatesIterator();
+                while (iter.hasNext()) {
+                    Update u = iter.next();
+                    Route route = new Route(u.rd, u.prefix, u.prefixlen, u.nexthop, u.label);
+                    //Add to FIB??
+                    /*
+                    if(bgpRouteCb != null) {
+                        bgpRouteCb.setRoute(route);
+                    }*/
+                }
+            }
+            endRibSync(bsh);
+            logger.info("Completed BGP Route sync.");
+        }  catch (Exception e) {
+            throw e;
+        }
+    };
+
+
+    public List<Route> getRoutes()
+        throws TException, BgpRouterException {
+
+        BgpSyncHandle bsh = BgpSyncHandle.getInstance();
+        List<Route> allRoutes = new ArrayList<Route>();
+
+        try {
+            initRibSync(bsh);
+            while (bsh.getState() != bsh.DONE) {
+                Routes r = doRibSync(bsh);
+                Iterator<Update> iter = r.getUpdatesIterator();
+                while (iter.hasNext()) {
+                    Update u = iter.next();
+                    Route route = new Route(u.rd, u.prefix, u.prefixlen, u.nexthop, u.label);
+
+                    allRoutes.add(route);
+                }
+            }
+            endRibSync(bsh);
+        }  catch (Exception e) {
+            throw e;
+        }
+        return allRoutes;
+    };
+
+
+}