package org.opendaylight.netvirt.bgpmanager.thrift.client;
+import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_LIMIT;
+import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_THRESHOLD;
+
import com.google.common.annotations.VisibleForTesting;
import java.net.ConnectException;
+import java.util.Arrays;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
-import javax.annotation.Nullable;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.netvirt.bgpmanager.BgpConfigurationManager;
import org.opendaylight.netvirt.bgpmanager.RetryOnException;
+import org.opendaylight.netvirt.bgpmanager.thrift.gen.BfdConfigData;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.BgpConfigurator;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.encap_type;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.layer_type;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.LayerType;
import org.slf4j.Logger;
private static final int CONNECTION_TIMEOUT = 60000;
private enum Optype {
- START, STOP, NBR, VRF, PFX, SRC, MHOP, LOG, AF, GR, MP, VRFMP, EOR, DELAY_EOR
+ START, STOP, NBR, VRF, PFX, SRC, MHOP, LOG, AF, GR, MP, VRFMP, EOR, DELAY_EOR, BFD, PEER_STATUS
}
private static class BgpOp {
Optype type;
boolean add;
+ boolean multiHop;
String[] strs;
int[] ints;
List<String> irts;
String macAddress;
int l2label;
int l3label;
+ int holdTime;
+ int kaTime;
encap_type thriftEncapType;
String routermac;
public af_afi afi;
BgpOp() {
strs = new String[3];
- ints = new int[2];
+ ints = new int[3];
+ }
+
+ BgpOp(BgpOp bgpOp) {
+ strs = new String[3];
+ ints = new int[3];
+ this.strs = bgpOp.strs;
+ this.ints = bgpOp.ints;
+ this.afi = bgpOp.afi;
+ this.safi = bgpOp.safi;
+ this.type = bgpOp.type;
+ this.add = bgpOp.add;
+ this.multiHop = bgpOp.multiHop;
+ this.asNumber = bgpOp.asNumber;
+ this.holdTime = bgpOp.holdTime;
+ this.kaTime = bgpOp.kaTime;
+ this.thriftProtocolType = bgpOp.thriftProtocolType;
+ this.thriftLayerType = bgpOp.thriftLayerType;
+ this.ethernetTag = bgpOp.ethernetTag;
+ this.esi = bgpOp.esi;
+ this.macAddress = bgpOp.macAddress;
+ this.l2label = bgpOp.l2label;
+ this.l3label = bgpOp.l3label;
+ this.routermac = bgpOp.routermac;
+ this.thriftEncapType = bgpOp.thriftEncapType;
+ this.delayEOR = bgpOp.delayEOR;
+
+ }
+
+ @Override
+ public String toString() {
+ //TODO pretty print
+ return "BgpOp{"
+ + "type=" + type
+ + ", add=" + add
+ + ",multihop=" + multiHop
+ + ", strs=" + Arrays.toString(strs)
+ + ", ints=" + Arrays.toString(ints)
+ + ", irts=" + irts
+ + ", erts=" + erts
+ + ", asNumber=" + asNumber
+ + ", Hold Time=" + holdTime
+ + ", KA Time=" + kaTime
+ + ", thriftLayerType=" + thriftLayerType
+ + ", thriftProtocolType=" + thriftProtocolType
+ + ", ethernetTag=" + ethernetTag
+ + ", esi='" + esi + '\''
+ + ", macAddress='" + macAddress + '\''
+ + ", l2label=" + l2label
+ + ", l3label=" + l3label
+ + ", thriftEncapType=" + thriftEncapType
+ + ", routermac='" + routermac + '\''
+ + ", afi=" + afi
+ + ", delayEOR=" + delayEOR
+ + ", safi=" + safi
+ + '}' + '\n';
}
}
+
+
private final BgpOp bop = new BgpOp();
private final Supplier<Bgp> bgpConfigSupplier;
private final BooleanSupplier isBGPEntityOwner;
private volatile long startTS;
private volatile long connectTS;
private volatile long lastConnectedTS;
+ private final TransactionHistory transactionHistory;
private volatile boolean configServerUpdated = false;
- private BgpRouter(Supplier<Bgp> bgpConfigSupplier, BooleanSupplier isBGPEntityOwner) {
+ private BgpRouter(Supplier<Bgp> bgpConfigSupplier, BooleanSupplier isBGPEntityOwner,
+ TransactionHistory transactionHistory) {
this.bgpConfigSupplier = bgpConfigSupplier;
this.isBGPEntityOwner = isBGPEntityOwner;
+ this.transactionHistory = transactionHistory;
}
// private ctor FOR UNIT TESTS ONLY
private BgpRouter(BgpConfigurator.Client bgpClient) {
- this(() -> null, () -> false);
+ this(() -> null, () -> false, new TransactionHistory(HISTORY_LIMIT, HISTORY_THRESHOLD));
this.bgpClient = bgpClient;
}
return new BgpRouter(bgpClient);
}
- public static BgpRouter newInstance(Supplier<Bgp> bgpConfigSupplier, BooleanSupplier isEntityBGPOwner) {
- return new BgpRouter(bgpConfigSupplier, isEntityBGPOwner);
+ public static BgpRouter newInstance(Supplier<Bgp> bgpConfigSupplier, BooleanSupplier isEntityBGPOwner,
+ TransactionHistory transactionHistory) {
+ return new BgpRouter(bgpConfigSupplier, isEntityBGPOwner,transactionHistory);
}
public TTransport getTransport() {
}
bgpClient = new BgpConfigurator.Client(new TBinaryProtocol(transport));
- LOG.info("Connected to " + msgPiece);
+ LOG.info("Connected to {}", msgPiece);
return true;
}
return isConnected;
}
+ private TransactionType getTransactionType(BgpOp op) {
+ return op.add ? TransactionType.ADD : TransactionType.DELETE;
+ }
+
private void dispatch(BgpOp op) throws TException, BgpRouterException {
try {
dispatchInternal(op);
+ transactionHistory.addToHistory(getTransactionType(op), new BgpOp(op));
+ LOG.trace("History size is {}", transactionHistory.getElements().size());
} catch (TTransportException tte) {
LOG.error("dispatch command to qthriftd failed, command: {}, exception:", op.toString(), tte);
reConnect(tte);
setStartTS(System.currentTimeMillis());
LOG.debug("startBgp thrift call for AsId {}", op.asNumber);
result = bgpClient.startBgp(op.asNumber, op.strs[0],
- BgpOp.IGNORE, BgpOp.IGNORE, BgpOp.IGNORE, op.ints[0], op.add);
+ BgpOp.IGNORE, op.holdTime, op.kaTime, op.ints[0], op.add);
LOG.debug("Result of startBgp thrift call for AsId {} : {}", op.asNumber, result);
break;
case STOP:
case DELAY_EOR:
bgpClient.send_enableEORDelay(op.delayEOR);
break;
+ case BFD:
+ BfdConfigData bfdConfigData = new BfdConfigData();
+ bfdConfigData.setBfdConfigDataVersion((byte)1);
+ bfdConfigData.setBfdDebounceDown(0);
+ bfdConfigData.setBfdDebounceUp(0);
+ bfdConfigData.setBfdFailureThreshold((byte)op.ints[0]);
+ bfdConfigData.setBfdRxInterval(op.ints[1]);
+ bfdConfigData.setBfdTxInterval(op.ints[2]);
+ bfdConfigData.setBfdMultihop(op.multiHop);
+ result = bop.add
+ ? bgpClient.enableBFDFailover(bfdConfigData)
+ : bgpClient.disableBFDFailover();
+ break;
+ case PEER_STATUS:
+ result = bgpClient.getPeerStatus(op.strs[0], op.asNumber).getValue();
+ break;
default:
break;
}
}
}
- public synchronized void startBgp(long asNum, String rtrId, int stalepathTime, boolean announceFbit)
+ public synchronized void startBgp(long asNum, String rtrId, int bgpKaTime, int bgpHoldTime,
+ int stalepathTime, boolean announceFbit)
throws TException, BgpRouterException {
bop.type = Optype.START;
bop.add = announceFbit;
bop.asNumber = asNum;
+ bop.kaTime = bgpKaTime;
+ bop.holdTime = bgpHoldTime;
bop.ints[0] = stalepathTime;
bop.strs[0] = rtrId;
LOG.debug("Starting BGP with as number {} and router ID {} StalePathTime: {}", asNum, rtrId, stalepathTime);
bop.strs[0] = rd;
bop.afi = af_afi.findByValue((int)afi);
bop.safi = af_safi.findByValue((int)safi);
- LOG.debug("Deleting BGP VRF rd: {} " + rd);
+ LOG.debug("Deleting BGP VRF rd: {}", rd);
dispatch(bop);
}
dispatch(bop);
}
+ public synchronized void addBfd(int detectMult, int minRx, int minTx, boolean multiHop)
+ throws TException, BgpRouterException {
+ bop.type = Optype.BFD;
+ bop.add = true;
+ bop.ints[0] = detectMult;
+ bop.ints[1] = minRx;
+ bop.ints[2] = minTx;
+ bop.multiHop = multiHop;
+ LOG.debug("Adding BFD config {} {} {} {}", detectMult, minRx, minTx, multiHop);
+ dispatch(bop);
+ }
+
+ public synchronized void delBfd() throws TException, BgpRouterException {
+ bop.type = Optype.BFD;
+ bop.add = false;
+ LOG.debug("Deleting BFD Config ");
+ dispatch(bop);
+ }
+
public int initRibSync(BgpSyncHandle handle) throws BgpRouterException {
if (bgpClient == null) {
throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
return BgpRouterException.BGP_ERR_IN_ITER;
}
handle.setState(BgpSyncHandle.INITED);
+ handle.setMore(1);
return 0;
}
// TODO: receive correct protocol_type here, currently populating with dummy protocol type
Routes outRoutes = bgpClient.getRoutes(protocol_type.PROTOCOL_ANY, op, winSize, afi);
+ handle.setMore(outRoutes.more);
if (outRoutes.more == 0) {
handle.setState(BgpSyncHandle.DONE);
}
bop.type = Optype.LOG;
bop.strs[0] = fileName;
bop.strs[1] = debugLevel;
- LOG.debug("Setting Log file to BGP VRF rd: {} ", fileName, debugLevel);
+ LOG.debug("Setting Log file to BGP VRF rd: {}, {}", fileName, debugLevel);
dispatch(bop);
}
public synchronized void enableMultipath(af_afi afi, af_safi safi) throws TException, BgpRouterException {
bop.type = Optype.MP;
bop.add = true;
- LOG.debug("Enabling multipath for afi: " + afi.getValue() + " safi: " + safi.getValue());
+ LOG.debug("Enabling multipath for afi {}, safi {}", afi.getValue(), safi.getValue());
bop.ints[0] = afi.getValue();
bop.ints[1] = safi.getValue();
dispatch(bop);
public synchronized void disableMultipath(af_afi afi, af_safi safi) throws TException, BgpRouterException {
bop.type = Optype.MP;
bop.add = false;
- LOG.debug("Disabling multipath for afi: " + afi.getValue() + " safi: " + safi.getValue());
+ LOG.debug("Disabling multipath for afi {}, safi {}", afi.getValue(), safi.getValue());
bop.ints[0] = afi.getValue();
bop.ints[1] = safi.getValue();
dispatch(bop);
LOG.debug("EOR delay time in Seconds sent");
dispatch(bop);
}
+
+ public synchronized void getPeerStatus(String nbrIp, long nbrAsNum)
+ throws TException, BgpRouterException {
+ bop.type = Optype.PEER_STATUS;
+ bop.strs[0] = nbrIp;
+ bop.asNumber = nbrAsNum;
+ dispatch(bop);
+ } // public getPeerStatus( nbrIp, nbrAsNum )
+
}