*/
package org.opendaylight.netvirt.bgpmanager;
-import com.google.common.base.Optional;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.utils.batching.ActionableResource;
import org.opendaylight.genius.utils.batching.ActionableResourceImpl;
import org.opendaylight.genius.utils.batching.DefaultBatchHandler;
import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.encap_type;
import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
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.BgpControlPlaneType;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.LayerType;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.Vrfs;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrf;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
private static final String RESOURCE_TYPE = "BGP-RESOURCES";
private static final int DEFAULT_BATCH_SIZE = 1000;
private static final int DEFAULT_BATCH_INTERVAL = 500;
+ private int enableBfdFlag = -1;
private final DataBroker dataBroker;
+ private final IFibManager fibManager;
+
private final BlockingQueue<ActionableResource> bgpResourcesBufferQ = new LinkedBlockingQueue<>();
@Inject
- public BgpUtil(DataBroker dataBroker) {
+ public BgpUtil(DataBroker dataBroker, final IFibManager fibManager) {
this.dataBroker = dataBroker;
+ this.fibManager = fibManager;
}
@PostConstruct
return retValue;
}
- public <T extends DataObject> void update(final LogicalDatastoreType datastoreType,
- final InstanceIdentifier<T> path, final T data) {
- ActionableResource actResource = new ActionableResourceImpl(path.toString());
+ public <T extends DataObject> void update(final InstanceIdentifier<T> path, final T data) {
+ ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
actResource.setAction(ActionableResource.UPDATE);
actResource.setInstanceIdentifier(path);
actResource.setInstance(data);
bgpResourcesBufferQ.add(actResource);
}
- public <T extends DataObject> void write(final LogicalDatastoreType datastoreType, final InstanceIdentifier<T> path,
- final T data) {
- ActionableResource actResource = new ActionableResourceImpl(path.toString());
+ public <T extends DataObject> void write(final InstanceIdentifier<T> path, final T data) {
+ ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
actResource.setAction(ActionableResource.CREATE);
actResource.setInstanceIdentifier(path);
actResource.setInstance(data);
bgpResourcesBufferQ.add(actResource);
}
- public <T extends DataObject> void delete(final LogicalDatastoreType datastoreType,
- final InstanceIdentifier<T> path) {
- ActionableResource actResource = new ActionableResourceImpl(path.toString());
+ public <T extends DataObject> void delete(final InstanceIdentifier<T> path) {
+ ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
actResource.setAction(ActionableResource.DELETE);
actResource.setInstanceIdentifier(path);
actResource.setInstance(null);
public VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
InstanceIdentifier<VpnInstanceOpDataEntry> id = getVpnInstanceOpDataIdentifier(rd);
- Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = MDSALUtil.read(dataBroker,
- LogicalDatastoreType.OPERATIONAL, id);
+ Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = Optional.empty();
+ try {
+ vpnInstanceOpData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception while reading VpnInstanceOpDataEntry DS for the Vpn Rd {}", rd, e);
+ }
if (vpnInstanceOpData.isPresent()) {
return vpnInstanceOpData.get();
}
private String getElanNamefromRd(String rd) {
InstanceIdentifier<EvpnRdToNetwork> id = getEvpnRdToNetworkIdentifier(rd);
- Optional<EvpnRdToNetwork> evpnRdToNetworkOpData = MDSALUtil.read(dataBroker,
- LogicalDatastoreType.CONFIGURATION, id);
+ Optional<EvpnRdToNetwork> evpnRdToNetworkOpData = Optional.empty();
+ try {
+ evpnRdToNetworkOpData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception while reading EvpnRdToNetwork DS for the Vpn Rd {}", rd, e);
+ }
if (evpnRdToNetworkOpData.isPresent()) {
return evpnRdToNetworkOpData.get().getNetworkId();
}
InstanceIdentifier<ExternalTeps> externalTepsId = getExternalTepsIdentifier(elanName, tepIp);
ExternalTepsBuilder externalTepsBuilder = new ExternalTepsBuilder();
ExternalTepsKey externalTepsKey = externalTepsId.firstKeyOf(ExternalTeps.class);
- externalTepsBuilder.setKey(externalTepsKey);
externalTepsBuilder.setTepIp(externalTepsKey.getTepIp());
- update(LogicalDatastoreType.CONFIGURATION, externalTepsId, externalTepsBuilder.build());
+ update(externalTepsId, externalTepsBuilder.build());
}
public void deleteTepFromElanInstance(String rd, String tepIp) {
}
LOG.debug("Deleting tepIp {} from elan {}", tepIp, elanName);
InstanceIdentifier<ExternalTeps> externalTepsId = getExternalTepsIdentifier(elanName, tepIp);
- delete(LogicalDatastoreType.CONFIGURATION, externalTepsId);
+ delete(externalTepsId);
}
private static InstanceIdentifier<ExternalTeps> getExternalTepsIdentifier(String elanInstanceName, String tepIp) {
- IpAddress tepAdress = tepIp == null ? null : new IpAddress(tepIp.toCharArray());
+ IpAddress tepAdress = tepIp == null ? null : new IpAddress(new Ipv4Address(tepIp));
return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
new ElanInstanceKey(elanInstanceName)).child(ExternalTeps.class,
new ExternalTepsKey(tepAdress)).build();
}
public String getVpnNameFromRd(String rd) {
- VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
- return vpnInstanceOpData != null ? vpnInstanceOpData.getVpnInstanceName() : null;
+ final Map<String, String> rdtoVpnMap = new HashMap<>();
+ if (rdtoVpnMap.get(rd) != null) {
+ return rdtoVpnMap.get(rd);
+ } else {
+ VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
+ String vpnName = vpnInstanceOpData != null ? vpnInstanceOpData.getVpnInstanceName() : null;
+ rdtoVpnMap.put(rd, vpnName);
+ return vpnName;
+ }
}
/** get the vrf with the RouterDistinguisher pass in param.
public Vrfs getVrfFromRd(String rd) {
Vrfs vrfs = null;
KeyedInstanceIdentifier<Vrfs, VrfsKey> id = InstanceIdentifier.create(Bgp.class)
+ .child(VrfsContainer.class)
.child(Vrfs.class, new VrfsKey(rd));
- Optional<Vrfs> vrfsFromDs = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ Optional<Vrfs> vrfsFromDs = Optional.empty();
+ try {
+ vrfsFromDs = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception while reading BGP VRF table for the Vpn Rd {}", rd, e);
+ }
if (vrfsFromDs.isPresent()) {
vrfs = vrfsFromDs.get();
}
*/
public static LayerType getLayerType(AddressFamiliesVrf adf) {
LayerType layerTypeValue = null;
- if (adf.getSafi() == af_safi.SAFI_EVPN.getValue()) {
+ if (adf.getSafi().intValue() == af_safi.SAFI_EVPN.getValue()) {
layerTypeValue = LayerType.LAYER2;
- } else if (adf.getSafi() == af_safi.SAFI_MPLS_VPN.getValue()) {
+ } else if (adf.getSafi().intValue() == af_safi.SAFI_MPLS_VPN.getValue()) {
layerTypeValue = LayerType.LAYER3;
}
return layerTypeValue;
InstanceIdentifier.builder(FibEntries.class)
.child(VrfTables.class, new VrfTablesKey(rd))
.child(VrfEntry.class, new VrfEntryKey(vrfEntry.getDestPrefix())).build();
- delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+ delete(vrfEntryId);
+ }
+
+ public void enableBfdFlag() {
+ enableBfdFlag = 1;
+ }
+
+ public void disableBfdFlag() {
+ enableBfdFlag = 0;
+ }
+
+ public boolean isBfdEnabled() {
+ if (enableBfdFlag == 1) {
+ return true;
+ } else if (enableBfdFlag == 0) {
+ return false;
+ }
+ BfdConfig bfdConfig = getBfdConfig();
+ if (bfdConfig != null) {
+ return bfdConfig.isBfdEnabled();
+ }
+ return false;
+ }
+
+ public BfdConfig getBfdConfig() {
+ InstanceIdentifier<BfdConfig> id =
+ InstanceIdentifier.builder(BfdConfig.class).build();
+ Optional<BfdConfig> bfdConfigOptional = Optional.empty();
+ try {
+ bfdConfigOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception while reading BfdConfig", e);
+ }
+ if (bfdConfigOptional.isPresent()) {
+ return bfdConfigOptional.get();
+ }
+ return null;
+ }
+
+ public DcgwTepList getDcgwTepConfig() {
+ InstanceIdentifier<DcgwTepList> id =
+ InstanceIdentifier.builder(Bgp.class).child(DcgwTepList.class).build();
+ Optional<DcgwTepList> dcgwTepListOptional = Optional.empty();
+ try {
+ dcgwTepListOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("getDcgwTepConfig: Exception while reading DcgwTepList", e);
+ }
+ if (dcgwTepListOptional.isPresent()) {
+ return dcgwTepListOptional.get();
+ }
+ return null;
+ }
+
+ public List<String> getDcgwTepConfig(String dcgwIp) {
+ InstanceIdentifier<DcgwTep> id =
+ InstanceIdentifier.builder(Bgp.class)
+ .child(DcgwTepList.class)
+ .child(DcgwTep.class, new DcgwTepKey(dcgwIp)).build();
+ Optional<DcgwTep> tepListOptional = Optional.empty();
+ try {
+ tepListOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception while reading DcgwTep for the IP {}", dcgwIp, e);
+ }
+ if (tepListOptional.isPresent()) {
+ return tepListOptional.get().getTepIps();
+ }
+ LOG.debug("No tep configured for DCGW {}", dcgwIp);
+ return null;
+ }
+
+ public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
+ InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
+ Optional<DpnEndpoints> dpnEndpoints = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
+ if (dpnEndpoints.isPresent()) {
+ return dpnEndpoints.get().getDPNTEPsInfo();
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ public void removeOrUpdateLBGroups(String tepIp, int addRemoveOrUpdate) {
+ getDpnTEPsInfos(dataBroker).forEach(dpnInfo -> {
+ if (NwConstants.MOD_FLOW == addRemoveOrUpdate) {
+ LOG.debug("Updating bucket in DPN {}", dpnInfo.getDPNID());
+ } else if (NwConstants.DEL_FLOW == addRemoveOrUpdate) {
+ LOG.debug("Deleting groups in DPN {}", dpnInfo.getDPNID());
+ }
+ Class<? extends TunnelTypeBase> tunType = TunnelTypeMplsOverGre.class;
+ fibManager.programDcGwLoadBalancingGroup(dpnInfo.getDPNID(),
+ tepIp, addRemoveOrUpdate, false, tunType);
+ });
}
}