Updated BgpManager for Be
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / thrift / client / BgpRouter.java
diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/BgpRouter.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/BgpRouter.java
new file mode 100644 (file)
index 0000000..720ebf9
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.bgpmanager.thrift.client;
+
+import java.util.*;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.TException;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.opendaylight.bgpmanager.thrift.gen.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BgpRouter {
+    private static TTransport transport;
+    private static TProtocol protocol;
+    private static BgpConfigurator.Client bgpClient=null;
+    private static final Logger LOGGER = LoggerFactory.getLogger(BgpRouter.class);
+
+    private enum Optype {
+        START, STOP, NBR, VRF, PFX, SRC, MHOP, LOG, AF, GR
+    };
+
+    private final static int GET_RTS_INIT = 0;
+    private final static int GET_RTS_NEXT = 1;
+    private final static int CONNECTION_TIMEOUT = 2000;
+
+
+    private class BgpOp {
+        public Optype type;
+        public boolean add;
+        public String[] strs;
+        public int[] ints;
+        public List<String> irts;
+        public List<String> erts;
+        public static final int ignore = 0;
+        public BgpOp() {
+            strs = new String[3];
+            ints = new int[2];
+        }
+    }
+
+    private static BgpOp bop;
+
+    public synchronized void disconnect() {
+        bgpClient = null;
+        if (transport != null) {
+            transport.close();
+        }
+    }
+
+    public synchronized boolean connect(String bgpHost, int bgpPort) {
+        String msgPiece = "BGP config server at "+bgpHost+":"+bgpPort;
+
+        disconnect();
+        try {
+            TSocket ts = new TSocket(bgpHost, bgpPort, CONNECTION_TIMEOUT);
+            transport = ts; 
+            transport.open();
+            ts.setTimeout(0);
+        } catch (TTransportException tte) {
+            LOGGER.error("Failed connecting to "+msgPiece+
+                         "; Exception: "+tte);
+            return false;
+        }
+        protocol = new TBinaryProtocol(transport);
+        bgpClient = new BgpConfigurator.Client(protocol);
+        LOGGER.info("Connected to "+msgPiece);
+        return true;
+    }
+
+    private BgpRouter() {
+        bop = new BgpOp();
+    }
+
+    private static BgpRouter br = null;
+
+    public static synchronized BgpRouter getInstance() {
+        return (br == null ? br = new BgpRouter() : br);
+    }
+
+    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:
+                result = bgpClient.startBgp(op.ints[0], op.strs[0],
+                    op.ignore, op.ignore, op.ignore, op.ints[1], op.add);
+                break;
+            case STOP:
+                result = bgpClient.stopBgp(op.ints[0]);
+                break;
+            case NBR:
+                result = bop.add ? 
+                           bgpClient.createPeer(op.strs[0], op.ints[0]) 
+                           : bgpClient.deletePeer(op.strs[0]); 
+                break;
+            case VRF:
+                result = bop.add ? 
+                           bgpClient.addVrf(op.strs[0], op.irts, op.erts)
+                           : bgpClient.delVrf(op.strs[0]);
+                break;
+            case PFX:
+                // order of args is different in addPrefix(), hence the
+                // seeming out-of-order-ness of string indices
+                result = bop.add ? 
+                           bgpClient.pushRoute(op.strs[1], op.strs[2], 
+                                                op.strs[0], op.ints[0])
+                      : bgpClient.withdrawRoute(op.strs[1], op.strs[0]);
+                break;
+            case LOG:
+                result = bgpClient.setLogConfig(op.strs[0], op.strs[1]);
+                break;
+            case MHOP: 
+                result = bop.add ? 
+                      bgpClient.setEbgpMultihop(op.strs[0], op.ints[0])
+                      : bgpClient.unsetEbgpMultihop(op.strs[0]);
+                break;
+            case SRC: 
+                result = bop.add ?
+                      bgpClient.setUpdateSource(op.strs[0], op.strs[1])
+                      : bgpClient.unsetUpdateSource(op.strs[0]);
+                break;
+            default: break;
+            case AF: 
+                af_afi afi = af_afi.findByValue(op.ints[0]);
+                af_safi safi = af_safi.findByValue(op.ints[1]);
+                result = bop.add ?
+                  bgpClient.enableAddressFamily(op.strs[0], afi, safi)
+                  : bgpClient.disableAddressFamily(op.strs[0], afi, safi);
+                break;
+            case GR: 
+                result = bop.add ?
+                           bgpClient.enableGracefulRestart(op.ints[0])
+                           : bgpClient.disableGracefulRestart();
+                break;
+        }
+        if (result != 0) {
+            throw new BgpRouterException(result);
+        }
+    }
+
+    public synchronized void startBgp(int asNum, String rtrId, int stalepathTime,
+                         boolean announceFbit)
+        throws TException, BgpRouterException {
+        bop.type = Optype.START;
+        bop.add = announceFbit;
+        bop.ints[0] = asNum;
+        bop.ints[1] = stalepathTime;
+        bop.strs[0] = rtrId;
+        LOGGER.debug("Starting BGP with as number {} and router ID {} ", asNum, rtrId);
+        dispatch(bop);
+    }
+
+    public synchronized void stopBgp(int asNum)
+        throws TException, BgpRouterException {
+        bop.type = Optype.STOP;
+        bop.ints[0] = asNum;
+        LOGGER.debug("Stopping BGP with as number {}", asNum);
+        dispatch(bop);
+    }
+
+    public synchronized void addNeighbor(String nbrIp, int nbrAsNum)
+        throws TException, BgpRouterException {
+        bop.type = Optype.NBR;
+        bop.add = true;
+        bop.strs[0] = nbrIp;
+        bop.ints[0] = nbrAsNum;
+        LOGGER.debug("Adding BGP Neighbor {} with as number {} ", nbrIp, nbrAsNum);
+        dispatch(bop);
+    }
+
+    public synchronized void delNeighbor(String nbrIp)
+        throws TException, BgpRouterException {
+        bop.type = Optype.NBR;
+        bop.add = false;
+        bop.strs[0] = nbrIp;
+        LOGGER.debug("Deleting BGP Neighbor {} ", nbrIp);
+        dispatch(bop);
+    }
+
+    public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
+        throws TException, BgpRouterException {
+        bop.type = Optype.VRF;
+        bop.add = true;
+        bop.strs[0] = rd;
+        bop.irts = irts;
+        bop.erts = erts;
+        LOGGER.debug("Adding BGP VRF rd: {} ", rd);
+        dispatch(bop);
+    }
+
+    public synchronized void delVrf(String rd)
+        throws TException, BgpRouterException {
+        bop.type = Optype.VRF;
+        bop.add = false;
+        bop.strs[0] = rd;
+        LOGGER.debug("Deleting BGP VRF rd: {} " + rd);
+        dispatch(bop);
+    }
+
+    // bit of a mess-up: the order of arguments is different in
+    // the Thrift RPC: prefix-nexthop-rd-label. 
+
+    public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
+        throws TException, BgpRouterException {
+        bop.type = Optype.PFX;
+        bop.add = true;
+        bop.strs[0] = rd;
+        bop.strs[1] = prefix;
+        bop.strs[2] = nexthop;
+        bop.ints[0] = label;
+        LOGGER.debug("Adding BGP route - rd:{} prefix:{} nexthop:{} label:{} ", rd ,prefix, nexthop, label);
+        dispatch(bop);
+    }
+
+    public synchronized void delPrefix(String rd, String prefix)
+        throws TException, BgpRouterException {
+        bop.type = Optype.PFX;
+        bop.add = false;
+        bop.strs[0] = rd;
+        bop.strs[1] = prefix;
+        LOGGER.debug("Deleting BGP route - rd:{} prefix:{} ", rd, 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;
+    }
+
+    public synchronized void setLogging(String fileName, String debugLevel)
+            throws TException, BgpRouterException {
+        bop.type = Optype.LOG;
+        bop.strs[0] = fileName;
+        bop.strs[1] = debugLevel;
+        LOGGER.debug("Setting Log file to BGP VRF rd: {} ", fileName, debugLevel);
+        dispatch(bop);
+    }
+
+    public synchronized void addEbgpMultihop(String nbrIp, int nhops)
+        throws TException, BgpRouterException {
+        bop.type = Optype.MHOP;
+        bop.add = true;
+        bop.strs[0] = nbrIp;
+        bop.ints[0] = nhops;
+        LOGGER.debug("ebgp-multihop set for peer {}, num hops = {}",
+                      nbrIp, nhops);
+        dispatch(bop);
+    }
+
+    public synchronized void delEbgpMultihop(String nbrIp)
+        throws TException, BgpRouterException {
+        bop.type = Optype.MHOP;
+        bop.add = false;
+        bop.strs[0] = nbrIp;
+        LOGGER.debug("ebgp-multihop deleted for peer {}", nbrIp);
+        dispatch(bop);
+    }
+
+    public synchronized void addUpdateSource(String nbrIp, String srcIp)
+        throws TException, BgpRouterException {
+        bop.type = Optype.SRC;
+        bop.add = true;
+        bop.strs[0] = nbrIp;
+        bop.strs[1] = srcIp;
+        LOGGER.debug("update-source added for peer {}, src-ip = {}", 
+                      nbrIp, srcIp);
+        dispatch(bop);
+    }
+
+    public synchronized void delUpdateSource(String nbrIp)
+        throws TException, BgpRouterException {
+        bop.type = Optype.SRC;
+        bop.add = false;
+        bop.strs[0] = nbrIp;
+        LOGGER.debug("update-source deleted for peer {}", nbrIp);
+        dispatch(bop);
+    }
+
+    public synchronized void addAddressFamily(String nbrIp, 
+                                  af_afi afi, af_safi safi)
+        throws TException, BgpRouterException {
+        bop.type = Optype.AF;
+        bop.add = true;
+        bop.strs[0] = nbrIp;
+        bop.ints[0] = afi.getValue();
+        bop.ints[1] = safi.getValue();
+        LOGGER.debug("addr family added for peer {}, afi = {}, safi = {}",
+                     nbrIp, bop.ints[0], bop.ints[1]);
+        dispatch(bop);
+    }
+
+    public synchronized void delAddressFamily(String nbrIp,
+                                  af_afi afi, af_safi safi)
+        throws TException, BgpRouterException {
+        bop.type = Optype.AF;
+        bop.add = false;
+        bop.strs[0] = nbrIp;
+        bop.ints[0] = afi.getValue();
+        bop.ints[1] = safi.getValue();
+        LOGGER.debug("addr family deleted for peer {}, afi = {}, safi = {}",
+                     nbrIp, bop.ints[0], bop.ints[1]);
+        dispatch(bop);
+    }
+
+    public synchronized void addGracefulRestart(int stalepathTime)
+        throws TException, BgpRouterException {
+        bop.type = Optype.GR;
+        bop.add = true;
+        bop.ints[0] = stalepathTime;
+        LOGGER.debug("graceful restart added, stale-path-time = {}",
+                      stalepathTime);
+        dispatch(bop);
+    }
+
+    public synchronized void delGracefulRestart()
+        throws TException, BgpRouterException {
+        bop.type = Optype.GR;
+        bop.add = false;
+        LOGGER.debug("graceful restart deleted");
+        dispatch(bop);
+    }
+}