X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnservice%2Ffibmanager%2Ffibmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Ffibmanager%2FFibUtil.java;h=883813c6a1ce291336b48870b8cd7a68d1613ed9;hb=4e34f42aaee2038d40b3b4ca1eb2acd7e5ef2381;hp=faf6ef98d19a48d05f6ac7efbcc376723d54426d;hpb=3f93fb9a89410388cfc1de353bb9eb0f2994d5ed;p=netvirt.git diff --git a/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java b/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java index faf6ef98d1..883813c6a1 100644 --- a/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java +++ b/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java @@ -10,14 +10,13 @@ package org.opendaylight.netvirt.fibmanager; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; +import static org.opendaylight.netvirt.fibmanager.VrfEntryListener.isOpenStackVniSemanticsEnforced; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; import java.math.BigInteger; +import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,11 +24,11 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.genius.mdsalutil.BucketInfo; import org.opendaylight.genius.mdsalutil.MDSALUtil; +import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.netvirt.fibmanager.NexthopManager.AdjacencyResult; import org.opendaylight.netvirt.fibmanager.api.FibHelper; import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; @@ -39,16 +38,31 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.re import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; +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.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.RouterInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder; @@ -72,18 +86,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; @@ -91,50 +99,7 @@ import org.slf4j.LoggerFactory; public class FibUtil { private static final Logger LOG = LoggerFactory.getLogger(FibUtil.class); - - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static Optional read(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path) { - - ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); - - Optional result = Optional.absent(); - try { - result = tx.read(datastoreType, path).get(); - } catch (Exception e) { - throw new RuntimeException(e); - } - - return result; - } - - static void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.merge(datastoreType, path, data, true); - Futures.addCallback(tx.submit(), callback); - } - - static void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, true); - CheckedFuture futures = tx.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data, e); - throw new RuntimeException(e.getMessage()); - } - } - - static void delete(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.delete(datastoreType, path); - Futures.addCallback(tx.submit(), DEFAULT_CALLBACK); - } + private static final String FLOWID_PREFIX = "L3."; static InstanceIdentifier getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) { return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang @@ -182,19 +147,6 @@ public class FibUtil { .VpnInterfaceKey(vpnInterfaceName)).build(); } - public static InstanceIdentifier getVpnToDpnListIdentifier(String rd, BigInteger dpnId) { - return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn - .rev130911.VpnInstanceOpData.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data - .VpnInstanceOpDataEntry.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data - .VpnInstanceOpDataEntryKey(rd)) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data - .vpn.instance.op.data.entry.VpnToDpnList.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data - .vpn.instance.op.data.entry.VpnToDpnListKey(dpnId)).build(); - } - static InstanceIdentifier getVpnInstanceOpDataIdentifier(String rd) { return InstanceIdentifier.builder(VpnInstanceOpData.class) .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build(); @@ -202,7 +154,16 @@ public class FibUtil { static Optional getVpnInstanceOpData(DataBroker broker, String rd) { InstanceIdentifier id = getVpnInstanceOpDataIdentifier(rd); - return read(broker, LogicalDatastoreType.OPERATIONAL, id); + return MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + } + + static VpnInstanceOpDataEntry getVpnInstance(DataBroker dataBroker, String rd) { + InstanceIdentifier id = + InstanceIdentifier.create(VpnInstanceOpData.class) + .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)); + Optional vpnInstanceOpData = + MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + return vpnInstanceOpData.isPresent() ? vpnInstanceOpData.get() : null; } static String getNextHopLabelKey(String rd, String prefix) { @@ -211,13 +172,13 @@ public class FibUtil { } static Prefixes getPrefixToInterface(DataBroker broker, Long vpnId, String ipPrefix) { - Optional localNextHopInfoData = read(broker, LogicalDatastoreType.OPERATIONAL, + Optional localNextHopInfoData = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix)); return localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null; } static String getMacAddressFromPrefix(DataBroker broker, String ifName, String ipPrefix) { - Optional adjacencyData = read(broker, LogicalDatastoreType.OPERATIONAL, + Optional adjacencyData = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getAdjacencyIdentifier(ifName, ipPrefix)); return adjacencyData.isPresent() ? adjacencyData.get().getMacAddress() : null; } @@ -247,7 +208,7 @@ public class FibUtil { public static long getVpnId(DataBroker broker, String vpnName) { InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); - return read(broker, LogicalDatastoreType.CONFIGURATION, id).transform(VpnInstance::getVpnId).or(-1L); + return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id).transform(VpnInstance::getVpnId).or(-1L); } /** @@ -261,100 +222,10 @@ public class FibUtil { return getVpnInstanceOpData(broker, rd).transform(VpnInstanceOpDataEntry::getVpnInstanceName); } - static List getAllInterVpnLinks(DataBroker broker) { - InstanceIdentifier interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build(); - - return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid).transform( - InterVpnLinks::getInterVpnLink).or(new ArrayList<>()); - } - - /** - * Returns the instance identifier for a given vpnLinkName. - * - * @param vpnLinkName The vpn link name - * @return InstanceIdentifier - */ - public static InstanceIdentifier getInterVpnLinkStateIid(String vpnLinkName) { - return InstanceIdentifier.builder(InterVpnLinkStates.class) - .child(InterVpnLinkState.class, new InterVpnLinkStateKey(vpnLinkName)).build(); - } - - /** - * Checks if the InterVpnLink is in Active state. - * - * @param broker The DataBroker - * @param vpnLinkName The vpn linkname - * @return The link state - */ - public static boolean isInterVpnLinkActive(DataBroker broker, String vpnLinkName) { - Optional interVpnLinkState = getInterVpnLinkState(broker, vpnLinkName); - if (!interVpnLinkState.isPresent()) { - LOG.warn("Could not find Operative State for InterVpnLink {}", vpnLinkName); - return false; - } - - return interVpnLinkState.get().getState().equals(InterVpnLinkState.State.Active); - } - - /** - * Checks if the state of the interVpnLink. - * - * @param broker The DataBroker - * @param vpnLinkName The vpn linkname - * @return The link state - */ - public static Optional getInterVpnLinkState(DataBroker broker, String vpnLinkName) { - InstanceIdentifier vpnLinkStateIid = getInterVpnLinkStateIid(vpnLinkName); - return read(broker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid); - } - - /** - * Obtains the route-distinguisher for a given vpn-name. - * - * @param broker The DataBroker - * @param vpnName vpn name - * @return route-distinguisher - */ - public static String getVpnRd(DataBroker broker, String vpnName) { - InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); - return read(broker, LogicalDatastoreType.CONFIGURATION, id).transform(VpnInstance::getVrfId).orNull(); - } - - public static int getUniqueId(IdManagerService idManager, String poolName, String idKey) { - AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); - - try { - Future> result = idManager.allocateId(getIdInput); - RpcResult rpcResult = result.get(); - if (rpcResult.isSuccessful()) { - return rpcResult.getResult().getIdValue().intValue(); - } else { - LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors()); - } - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Exception when getting Unique Id", e); - } - return 0; - } - - static final FutureCallback DEFAULT_CALLBACK = - new FutureCallback() { - @Override - public void onSuccess(Void result) { - LOG.debug("Success in Datastore operation"); - } - - @Override - public void onFailure(Throwable error) { - LOG.error("Error in Datastore operation", error); - } - - ; - }; - public static String getVpnNameFromId(DataBroker broker, long vpnId) { InstanceIdentifier id = getVpnIdToVpnInstanceIdentifier(vpnId); - return read(broker, LogicalDatastoreType.CONFIGURATION, id).transform(VpnIds::getVpnInstanceName).orNull(); + return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id).transform(VpnIds::getVpnInstanceName) + .orNull(); } static InstanceIdentifier getVpnIdToVpnInstanceIdentifier(long vpnId) { @@ -362,19 +233,6 @@ public class FibUtil { .child(VpnIds.class, new VpnIdsKey(vpnId)).build(); } - public static void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, true); - CheckedFuture futures = tx.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data, e); - throw new RuntimeException(e.getMessage()); - } - } - // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") public static void addOrUpdateFibEntry(DataBroker broker, String rd, String macAddress, String prefix, @@ -441,7 +299,7 @@ public class FibUtil { // Filling the nextHop with dummy nextHopAddress VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, - FibConstants.DEFAULT_NEXTHOP_IP, RouteOrigin.LOCAL) + FibConstants.DEFAULT_NEXTHOP_IP, RouteOrigin.LOCAL, null /* parentVpnRd */) .addAugmentation(RouterInterface.class, routerInterface).build(); if (writeConfigTxn != null) { @@ -457,7 +315,13 @@ public class FibUtil { private static void buildVpnEncapSpecificInfo(VrfEntryBuilder builder, VrfEntry.EncapType encapType, long label, long l3vni, String macAddress, String gatewayMac, List nextHopList) { - if (!encapType.equals(VrfEntry.EncapType.Mplsgre)) { + if (encapType == null) { + builder.setMac(macAddress); + return; + } + //if (!encapType.equals(VrfEntry.EncapType.Mplsgre)) { + // TODO - validate this check + if (l3vni != 0) { builder.setL3vni(l3vni); } builder.setEncapType(encapType); @@ -511,7 +375,6 @@ public class FibUtil { InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)) .child(VrfEntry.class, new VrfEntryKey(prefix)).build(); Optional entry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); - if (entry.isPresent()) { final List routePaths = entry.get().getRoutePaths(); if (routePaths == null || routePaths.isEmpty()) { @@ -552,56 +415,37 @@ public class FibUtil { } } - public static void updateFibEntry(DataBroker broker, String rd, String prefix, List nextHopList, - String gwMacAddress, long label, WriteTransaction writeConfigTxn) { - - LOG.debug("Updating fib entry for prefix {} with nextHopList {} for rd {}", prefix, nextHopList, rd); - - // Looking for existing prefix in MDSAL database - InstanceIdentifier vrfEntryId = - InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)) - .child(VrfEntry.class, new VrfEntryKey(prefix)).build(); - Optional entry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); + /** + * Adds or removes nextHop from routePath based on the flag nextHopAdd. + */ + public static void updateRoutePathForFibEntry(DataBroker broker, String rd, String prefix, String nextHop, + long label, boolean nextHopAdd, WriteTransaction writeConfigTxn) { - if (entry.isPresent()) { - RouteOrigin routeOrigin = RouteOrigin.value(entry.get().getOrigin()); - // Update the VRF entry with nextHopList - VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder(entry.get(), label, nextHopList, routeOrigin) - .setGatewayMacAddress(gwMacAddress).build(); + LOG.debug("Updating fib entry for prefix {} with nextHop {} for rd {}.", prefix, nextHop, rd); - if (nextHopList.isEmpty()) { - if (writeConfigTxn != null) { - writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry, true); - } else { - MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry); - } + InstanceIdentifier routePathId = FibHelper.buildRoutePathId(rd, prefix, nextHop); + if (nextHopAdd) { + RoutePaths routePaths = FibHelper.buildRoutePath(nextHop, label); + if (writeConfigTxn != null) { + writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, routePathId, routePaths, + WriteTransaction.CREATE_MISSING_PARENTS); } else { - if (writeConfigTxn != null) { - writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry, true); - } else { - MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry); - } + MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, routePathId, routePaths); } - LOG.debug("Updated fib entry for prefix {} with nextHopList {} for rd {}", prefix, nextHopList, rd); + LOG.debug("Added routepath with nextHop {} for prefix {} and label {}.", nextHop, prefix, label); } else { - LOG.warn("Could not find VrfEntry for Route-Distinguisher={} and prefix={}", rd, prefix); - } - } - - public static void addVrfTable(DataBroker broker, String rd, WriteTransaction writeConfigTxn) { - LOG.debug("Adding vrf table for rd {}", rd); - InstanceIdentifier.InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)); - InstanceIdentifier vrfTableId = idBuilder.build(); - VrfTablesBuilder vrfTablesBuilder = new VrfTablesBuilder().setKey(new VrfTablesKey(rd)) - .setRouteDistinguisher(rd).setVrfEntry(new ArrayList<>()); - if (writeConfigTxn != null) { - writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTablesBuilder.build()); - } else { - syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTablesBuilder.build(), - FibUtil.DEFAULT_CALLBACK); + Optional routePath = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, routePathId); + if (!routePath.isPresent()) { + LOG.warn("Couldn't find RoutePath with rd {}, prefix {} and nh {} for deleting", rd, prefix, nextHop); + return; + } + if (writeConfigTxn != null) { + writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, routePathId); + } else { + MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routePathId); + } + LOG.info("Removed routepath with nextHop {} for prefix {} and rd {}.", nextHop, prefix, rd); } - } public static void removeVrfTable(DataBroker broker, String rd, WriteTransaction writeConfigTxn) { @@ -613,20 +457,10 @@ public class FibUtil { if (writeConfigTxn != null) { writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vrfTableId); } else { - delete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId); + MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId); } } - public static List getNextHopListFromRoutePaths(final VrfEntry vrfEntry) { - List routePaths = vrfEntry.getRoutePaths(); - if (routePaths == null || routePaths.isEmpty()) { - return Collections.EMPTY_LIST; - } - return routePaths.stream() - .map(routePath -> routePath.getNexthopAddress()) - .collect(toList()); - } - public static java.util.Optional getLabelFromRoutePaths(final VrfEntry vrfEntry) { List routePaths = vrfEntry.getRoutePaths(); if (routePaths == null || routePaths.isEmpty() || vrfEntry.getRoutePaths().get(0).getLabel() == null) { @@ -671,7 +505,7 @@ public class FibUtil { .state.Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) { InstanceIdentifier ifStateId = buildStateInterfaceId(interfaceName); - Optional ifStateOptional = FibUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId); + Optional ifStateOptional = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId); if (ifStateOptional.isPresent()) { return ifStateOptional.get(); } @@ -683,26 +517,73 @@ public class FibUtil { return "FIB-" + vpnId.toString() + "-" + dpnId.toString() + "-" + prefix; } - public static boolean isTunnelInterface(AdjacencyResult adjacencyResult) { - return Tunnel.class.equals(adjacencyResult.getInterfaceType()); + public static String getJobKeyForRdPrefix(String rd, String prefix) { + return "FIB-" + rd + "-" + prefix; } - public static Optional getLastRoutePathExtraRouteIfPresent(DataBroker dataBroker, Long vpnId, - String rd, String prefix) { - List usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnId, prefix); - String vpnName = getVpnNameFromId(dataBroker, vpnId); - if (usedRds == null || usedRds.isEmpty()) { - LOG.debug("No used rd found for prefix {} on vpn {}", prefix, vpnName); - return Optional.absent(); - } else if (usedRds.size() > 1) { - LOG.debug("The extra route prefix is still present in some DPNs"); - return Optional.absent(); - } else { - rd = usedRds.get(0); + public static String getJobKeyForVpnIdDpnId(Long vpnId, BigInteger dpnId) { + return "FIB-" + vpnId.toString() + "-" + dpnId.toString() ; + } + + public static void updateUsedRdAndVpnToExtraRoute(WriteTransaction writeOperTxn, DataBroker broker, + String tunnelIpRemoved, String primaryRd, String prefix) { + Optional optVpnInstance = getVpnInstanceOpData(broker, primaryRd); + if (!optVpnInstance.isPresent()) { + return; + } + VpnInstanceOpDataEntry vpnInstance = optVpnInstance.get(); + String vpnName = vpnInstance.getVpnInstanceName(); + long vpnId = vpnInstance.getVpnId(); + List usedRds = VpnExtraRouteHelper.getUsedRds(broker, vpnId, prefix); + // To identify the rd to be removed, iterate through the allocated rds for the prefix and check + // which rd is allocated for the particular OVS. + for (String usedRd : usedRds) { + Optional vpnExtraRoutes = VpnExtraRouteHelper + .getVpnExtraroutes(broker, vpnName, usedRd, prefix); + if (vpnExtraRoutes.isPresent()) { + // Since all the nexthops under one OVS will be present under one rd, only 1 nexthop is read + // to identify the OVS + String nextHopRemoved = vpnExtraRoutes.get().getNexthopIpList().get(0); + Prefixes prefixToInterface = getPrefixToInterface(broker, vpnId, getIpPrefix(nextHopRemoved)); + if (prefixToInterface != null && tunnelIpRemoved + .equals(getEndpointIpAddressForDPN(broker, prefixToInterface.getDpnId()))) { + writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, + getAdjacencyIdentifier(prefixToInterface.getVpnInterfaceName(), prefix)); + writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, + VpnExtraRouteHelper.getVpnToExtrarouteVrfIdIdentifier(vpnName, usedRd, prefix)); + writeOperTxn.delete(LogicalDatastoreType.CONFIGURATION, + VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHopRemoved)); + break; + } + } + } + } + + private static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) { + //TODO: Move it to a common place for vpn and fib + String nextHopIp = null; + InstanceIdentifier tunnelInfoId = + InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build(); + Optional tunnelInfo = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId); + if (tunnelInfo.isPresent()) { + List nexthopIpList = tunnelInfo.get().getTunnelEndPoints(); + if (nexthopIpList != null && !nexthopIpList.isEmpty()) { + nextHopIp = String.valueOf(nexthopIpList.get(0).getIpAddress().getValue()); + } } - //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn - return VpnExtraRouteHelper.getVpnExtraroutes(dataBroker, - getVpnNameFromId(dataBroker, vpnId), rd, prefix); + return nextHopIp; + } + + public static String getIpPrefix(String prefix) { + String[] prefixValues = prefix.split(FibConstants.PREFIX_SEPARATOR); + if (prefixValues.length == 1) { + prefix = prefix + NwConstants.IPV4PREFIX; + } + return prefix; + } + + public static boolean isTunnelInterface(AdjacencyResult adjacencyResult) { + return Tunnel.class.equals(adjacencyResult.getInterfaceType()); } public static InstanceIdentifier getNextHopIdentifier(String rd, String prefix) { @@ -712,28 +593,18 @@ public class FibUtil { public static List getNextHopAddresses(DataBroker broker, String rd, String prefix) { InstanceIdentifier vrfEntryId = getNextHopIdentifier(rd, prefix); - Optional vrfEntry = read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); + Optional vrfEntry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); if (vrfEntry.isPresent()) { - return getNextHopListFromRoutePaths(vrfEntry.get()); + return FibHelper.getNextHopListFromRoutePaths(vrfEntry.get()); } else { return Collections.emptyList(); } } - public static Optional getGatewayMac(DataBroker dataBroker, String rd, String localNextHopIP) { - InstanceIdentifier vrfEntryId = getNextHopIdentifier(rd, localNextHopIP); - Optional vrfEntry = read(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); - if (vrfEntry.isPresent()) { - return Optional.fromNullable(vrfEntry.get().getGatewayMacAddress()); - } else { - return Optional.absent(); - } - } - public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) { InstanceIdentifier subnetmapId = InstanceIdentifier.builder(Subnetmaps.class) .child(Subnetmap.class, new SubnetmapKey(subnetId)).build(); - return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull(); + return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull(); } public static String getGreLbGroupKey(List availableDcGws) { @@ -801,7 +672,7 @@ public class FibUtil { public static Optional getNexthops(DataBroker dataBroker, String nextHopKey) { InstanceIdentifier nextHopsId = InstanceIdentifier.builder(L3vpnLbNexthops.class) .child(Nexthops.class, new NexthopsKey(nextHopKey)).build(); - return read(dataBroker, LogicalDatastoreType.OPERATIONAL, nextHopsId); + return MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, nextHopsId); } public static Optional getDpnLbNexthops(DataBroker dataBroker, BigInteger dpnId, @@ -809,6 +680,92 @@ public class FibUtil { InstanceIdentifier id = InstanceIdentifier.builder(DpidL3vpnLbNexthops.class) .child(DpnLbNexthops.class, new DpnLbNexthopsKey(destinationIp, dpnId)) .build(); - return read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + return MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + } + + protected static boolean isVxlanNetworkAndInternalRouterVpn(DataBroker dataBroker, Uuid subnetId, String + vpnInstanceName, String rd) { + if (rd.equals(vpnInstanceName)) { + Subnetmap subnetmap = getSubnetMap(dataBroker, subnetId); + if (subnetmap != null) { + return subnetmap.getNetworkType() == NetworkAttributes.NetworkType.VXLAN; + } + } + return false; + } + + protected static java.util.Optional getVniForVxlanNetwork(DataBroker dataBroker, Uuid subnetId) { + Subnetmap subnetmap = getSubnetMap(dataBroker, subnetId); + if (subnetmap != null && subnetmap.getNetworkType() == NetworkAttributes.NetworkType.VXLAN) { + return java.util.Optional.of(subnetmap.getSegmentationId()); + } + return java.util.Optional.empty(); + } + + protected static boolean enforceVxlanDatapathSemanticsforInternalRouterVpn(DataBroker dataBroker, Uuid subnetId, + long vpnId, String rd) { + return (isOpenStackVniSemanticsEnforced + && isVxlanNetworkAndInternalRouterVpn(dataBroker, subnetId, getVpnNameFromId(dataBroker, vpnId), rd)); + } + + protected static boolean enforceVxlanDatapathSemanticsforInternalRouterVpn(DataBroker dataBroker, Uuid subnetId, + String vpnName, String rd) { + return (isOpenStackVniSemanticsEnforced + && isVxlanNetworkAndInternalRouterVpn(dataBroker, subnetId, vpnName, rd)); + } + + static NodeRef buildNodeRef(BigInteger dpId) { + return new NodeRef(InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(new NodeId("openflow:" + dpId))).build()); + } + + static InstanceIdentifier buildGroupInstanceIdentifier(long groupId, BigInteger dpId) { + InstanceIdentifier groupInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(new NodeId("openflow:" + dpId))).augmentation(FlowCapableNode.class) + .child(Group.class, new GroupKey(new GroupId(groupId))).build(); + return groupInstanceId; + } + + static Buckets buildBuckets(List listBucketInfo) { + long index = 0; + BucketsBuilder bucketsBuilder = new BucketsBuilder(); + if (listBucketInfo != null) { + List bucketList = new ArrayList<>(); + + for (BucketInfo bucketInfo : listBucketInfo) { + BucketBuilder bucketBuilder = new BucketBuilder(); + bucketBuilder.setAction(bucketInfo.buildActions()); + bucketBuilder.setWeight(bucketInfo.getWeight()); + bucketBuilder.setBucketId(new BucketId(index++)); + bucketBuilder.setWeight(bucketInfo.getWeight()).setWatchPort(bucketInfo.getWatchPort()) + .setWatchGroup(bucketInfo.getWatchGroup()); + bucketList.add(bucketBuilder.build()); + } + + bucketsBuilder.setBucket(bucketList); + } + return bucketsBuilder.build(); + } + + static String getFlowRef(BigInteger dpnId, short tableId, long label, int priority) { + return FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + label + + NwConstants.FLOWID_SEPARATOR + priority; + } + + static String getFlowRef(BigInteger dpnId, short tableId, String rd, int priority, InetAddress destPrefix) { + return FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + rd + + NwConstants.FLOWID_SEPARATOR + priority + NwConstants.FLOWID_SEPARATOR + destPrefix.getHostAddress(); + } + + static String getL3VpnGatewayFlowRef(short l3GwMacTable, BigInteger dpId, long vpnId, String gwMacAddress) { + return gwMacAddress + NwConstants.FLOWID_SEPARATOR + vpnId + NwConstants.FLOWID_SEPARATOR + dpId + + NwConstants.FLOWID_SEPARATOR + l3GwMacTable; + } + + static Node buildDpnNode(BigInteger dpnId) { + NodeId nodeId = new NodeId("openflow:" + dpnId); + Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build(); + + return nodeDpn; } }