Search in sources :

Example 1 with WriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.WriteTransaction in project netvirt by opendaylight.

the class ElanInterfaceManager method addElanInterface.

List<ListenableFuture<Void>> addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) throws ElanException {
    Preconditions.checkNotNull(elanInstance, "elanInstance cannot be null");
    Preconditions.checkNotNull(interfaceInfo, "interfaceInfo cannot be null");
    Preconditions.checkNotNull(elanInterface, "elanInterface cannot be null");
    String interfaceName = elanInterface.getName();
    String elanInstanceName = elanInterface.getElanInstanceName();
    Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
    WriteTransaction tx = broker.newWriteOnlyTransaction();
    if (elanInfo == null) {
        List<String> elanInterfaces = new ArrayList<>();
        elanInterfaces.add(interfaceName);
        ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, tx);
    } else {
        createElanStateList(elanInstanceName, interfaceName, tx);
    }
    boolean isFirstInterfaceInDpn = false;
    // Specific actions to the DPN where the ElanInterface has been added,
    // for example, programming the
    // External tunnel table if needed or adding the ElanInterface to the
    // DpnInterfaces in the operational DS.
    BigInteger dpId = interfaceInfo.getDpId();
    DpnInterfaces dpnInterfaces = null;
    if (dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
        InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
        Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
        if (!existingElanDpnInterfaces.isPresent()) {
            isFirstInterfaceInDpn = true;
            // ELAN's 1st ElanInterface added to this DPN
            dpnInterfaces = createElanInterfacesList(elanInstanceName, interfaceName, dpId, tx);
            // table, but only if Elan has VNI
            if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
                setExternalTunnelTable(dpId, elanInstance);
            }
            elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
        } else {
            List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
            elanInterfaces.add(interfaceName);
            if (elanInterfaces.size() == 1) {
                // 1st dpn interface
                elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
            }
            dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces, tx);
        }
    }
    // add code to install Local/Remote BC group, unknow DMAC entry,
    // terminating service table flow entry
    // call bindservice of interfacemanager to create ingress table flow
    // enty.
    // Add interface to the ElanInterfaceForwardingEntires Container
    createElanInterfaceTablesList(interfaceName, tx);
    List<ListenableFuture<Void>> futures = new ArrayList<>();
    futures.add(ElanUtils.waitForTransactionToComplete(tx));
    installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, dpnInterfaces, isFirstInterfaceInDpn);
    // for internal vlan networks
    if (ElanUtils.isVlan(elanInstance) && !elanInstance.isExternal()) {
        if (interfaceManager.isExternalInterface(interfaceName)) {
            LOG.debug("adding vlan prv intf {} to elan {} BC group", interfaceName, elanInstanceName);
            handleExternalInterfaceEvent(elanInstance, dpnInterfaces, dpId);
        }
    }
    if (isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
        // update the remote-DPNs remoteBC group entry with Tunnels
        LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance, dpId);
        setElanAndEtreeBCGrouponOtherDpns(elanInstance, dpId);
    }
    String jobKey = ElanUtils.getElanInterfaceJobKey(interfaceName);
    InterfaceAddWorkerOnElanInterface addWorker = new InterfaceAddWorkerOnElanInterface(jobKey, elanInterface, interfaceInfo, elanInstance, isFirstInterfaceInDpn, this);
    jobCoordinator.enqueueJob(jobKey, addWorker, ElanConstants.JOB_MAX_RETRIES);
    return futures;
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) ArrayList(java.util.ArrayList) DpnInterfaces(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces) ElanDpnInterfaces(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces) Elan(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan) BigInteger(java.math.BigInteger) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 2 with WriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.WriteTransaction in project netvirt by opendaylight.

the class ElanInterfaceManager method setupEntriesForElanInterface.

List<ListenableFuture<Void>> setupEntriesForElanInterface(ElanInstance elanInstance, ElanInterface elanInterface, InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn) throws ElanException {
    String elanInstanceName = elanInstance.getElanInstanceName();
    String interfaceName = elanInterface.getName();
    WriteTransaction tx = broker.newWriteOnlyTransaction();
    BigInteger dpId = interfaceInfo.getDpId();
    WriteTransaction writeFlowGroupTx = broker.newWriteOnlyTransaction();
    installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo, isFirstInterfaceInDpn, tx, writeFlowGroupTx);
    List<StaticMacEntries> staticMacEntriesList = elanInterface.getStaticMacEntries();
    List<PhysAddress> staticMacAddresses = Lists.newArrayList();
    boolean isInterfaceOperational = isOperational(interfaceInfo);
    if (ElanUtils.isNotEmpty(staticMacEntriesList)) {
        for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
            InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, staticMacEntry.getMacAddress());
            Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
            if (existingMacEntry.isPresent()) {
                elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(), tx);
            } else {
                elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstanceName, interfaceName, staticMacEntry, tx);
            }
            if (isInterfaceOperational) {
                // Setting SMAC, DMAC, UDMAC in this DPN and also in other
                // DPNs
                String macAddress = staticMacEntry.getMacAddress().getValue();
                LOG.info("programming smac and dmacs for {} on source and other DPNs for elan {} and interface {}", macAddress, elanInstanceName, interfaceName);
                elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, staticMacEntry.getMacAddress().getValue(), true, writeFlowGroupTx);
            }
        }
        if (isInterfaceOperational) {
            // on purpose.
            for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
                staticMacAddresses.add(staticMacEntry.getMacAddress());
            }
            elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId, staticMacAddresses);
        }
    }
    List<ListenableFuture<Void>> futures = new ArrayList<>();
    futures.add(ElanUtils.waitForTransactionToComplete(tx));
    futures.add(ElanUtils.waitForTransactionToComplete(writeFlowGroupTx));
    if (isInterfaceOperational && !interfaceManager.isExternalInterface(interfaceName)) {
        // At this point, the interface is operational and D/SMAC flows have been configured, mark the port active
        try {
            Port neutronPort = neutronVpnManager.getNeutronPort(interfaceName);
            if (neutronPort != null) {
                NeutronUtils.updatePortStatus(interfaceName, NeutronUtils.PORT_STATUS_ACTIVE, broker);
            }
        } catch (IllegalArgumentException ex) {
            LOG.trace("Interface: {} is not part of Neutron Network", interfaceName);
        }
    }
    return futures;
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) MacEntry(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry) Port(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port) ArrayList(java.util.ArrayList) StaticMacEntries(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries) BigInteger(java.math.BigInteger) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) PhysAddress(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress)

Example 3 with WriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.WriteTransaction in project netvirt by opendaylight.

the class ElanInterfaceManager method removeElanInterface.

public List<ListenableFuture<Void>> removeElanInterface(ElanInstance elanInfo, String interfaceName, InterfaceInfo interfaceInfo) {
    String elanName = elanInfo.getElanInstanceName();
    boolean isLastElanInterface = false;
    boolean isLastInterfaceOnDpn = false;
    BigInteger dpId = null;
    long elanTag = elanInfo.getElanTag();
    // We use two transaction so we don't suffer on multiple shards (interfaces and flows)
    WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
    Elan elanState = removeElanStateForInterface(elanInfo, interfaceName, interfaceTx);
    if (elanState == null) {
        interfaceTx.cancel();
        return Collections.emptyList();
    }
    WriteTransaction flowTx = broker.newWriteOnlyTransaction();
    List<String> elanInterfaces = elanState.getElanInterfaces();
    if (elanInterfaces.isEmpty()) {
        isLastElanInterface = true;
    }
    if (interfaceInfo != null) {
        dpId = interfaceInfo.getDpId();
        DpnInterfaces dpnInterfaces = removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName, elanTag, interfaceTx);
        /*
             * If there are not elan ports, remove the unknown dmac, terminating
             * service table flows, remote/local bc group
             */
        if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null || dpnInterfaces.getInterfaces().isEmpty()) {
            // No more Elan Interfaces in this DPN
            LOG.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
            if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
                removeDefaultTermFlow(dpId, elanInfo.getElanTag());
            }
            removeUnknownDmacFlow(dpId, elanInfo, flowTx, elanInfo.getElanTag());
            removeEtreeUnknownDmacFlow(dpId, elanInfo, flowTx);
            removeElanBroadcastGroup(elanInfo, interfaceInfo, flowTx);
            removeLocalBroadcastGroup(elanInfo, interfaceInfo, flowTx);
            removeEtreeBroadcastGrups(elanInfo, interfaceInfo, flowTx);
            if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
                if (elanUtils.isOpenstackVniSemanticsEnforced()) {
                    elanUtils.removeTerminatingServiceAction(dpId, elanUtils.getVxlanSegmentationId(elanInfo).intValue());
                }
                unsetExternalTunnelTable(dpId, elanInfo);
            }
            isLastInterfaceOnDpn = true;
        } else {
            setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
        }
    }
    List<ListenableFuture<Void>> futures = new ArrayList<>();
    futures.add(ElanUtils.waitForTransactionToComplete(interfaceTx));
    futures.add(ElanUtils.waitForTransactionToComplete(flowTx));
    if (isLastInterfaceOnDpn && dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
        setElanAndEtreeBCGrouponOtherDpns(elanInfo, dpId);
    }
    InterfaceRemoveWorkerOnElanInterface removeInterfaceWorker = new InterfaceRemoveWorkerOnElanInterface(interfaceName, elanInfo, interfaceInfo, this, isLastElanInterface);
    jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName), removeInterfaceWorker, ElanConstants.JOB_MAX_RETRIES);
    return futures;
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) Elan(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan) DpnInterfaces(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces) ElanDpnInterfaces(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 4 with WriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.WriteTransaction in project netvirt by opendaylight.

the class ElanInterfaceManager method update.

/*
    * Possible Scenarios for update
    *   a. if orig={1,2,3,4}   and updated=null or updated={}
        then all {1,2,3,4} should be removed

        b. if orig=null or orig={}  and  updated ={1,2,3,4}
        then all {1,2,3,4} should be added

        c. if orig = {1,2,3,4} updated={2,3,4}
        then 1 should be removed

        d. basically if orig = { 1,2,3,4} and updated is {1,2,3,4,5}
        then we should just add 5

        e. if orig = {1,2,3,4} updated={2,3,4,5}
        then 1 should be removed , 5 should be added
    * */
@Override
protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
    // updating the static-Mac Entries for the existing elanInterface
    String elanName = update.getElanInstanceName();
    String interfaceName = update.getName();
    List<StaticMacEntries> originalStaticMacEntries = original.getStaticMacEntries();
    List<StaticMacEntries> updatedStaticMacEntries = update.getStaticMacEntries();
    List<StaticMacEntries> deletedEntries = ElanUtils.diffOf(originalStaticMacEntries, updatedStaticMacEntries);
    List<StaticMacEntries> updatedEntries = ElanUtils.diffOf(updatedStaticMacEntries, originalStaticMacEntries);
    deletedEntries.forEach((deletedEntry) -> removeInterfaceStaticMacEntries(elanName, interfaceName, deletedEntry.getMacAddress()));
    /*if updatedStaticMacEntries is NOT NULL, which means as part of update call these entries were added.
        * Hence add the macentries for the same.*/
    for (StaticMacEntries staticMacEntry : updatedEntries) {
        InstanceIdentifier<MacEntry> macEntryIdentifier = getMacEntryOperationalDataPath(elanName, staticMacEntry.getMacAddress());
        Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macEntryIdentifier);
        WriteTransaction tx = broker.newWriteOnlyTransaction();
        if (existingMacEntry.isPresent()) {
            elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(), tx);
        } else {
            elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanName, interfaceName, staticMacEntry, tx);
        }
        ElanUtils.waitForTransactionToComplete(tx);
    }
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) MacEntry(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry) StaticMacEntries(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries)

Example 5 with WriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.WriteTransaction in project netvirt by opendaylight.

the class VpnInterfaceManager method handleVpnsExportingRoutes.

// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
void handleVpnsExportingRoutes(String vpnName, String vpnRd) {
    List<VpnInstanceOpDataEntry> vpnsToExportRoute = getVpnsExportingMyRoute(vpnName);
    for (VpnInstanceOpDataEntry vpn : vpnsToExportRoute) {
        List<VrfEntry> vrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn.getVrfId());
        WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
        if (vrfEntries != null) {
            for (VrfEntry vrfEntry : vrfEntries) {
                try {
                    if (!FibHelper.isControllerManagedNonInterVpnLinkRoute(RouteOrigin.value(vrfEntry.getOrigin()))) {
                        LOG.info("handleVpnsExportingRoutes: vrfEntry with rd {} prefix {}" + " is not a controller managed non intervpn link route. Ignoring.", vpn.getVrfId(), vrfEntry.getDestPrefix());
                        continue;
                    }
                    String prefix = vrfEntry.getDestPrefix();
                    String gwMac = vrfEntry.getGatewayMacAddress();
                    vrfEntry.getRoutePaths().forEach(routePath -> {
                        String nh = routePath.getNexthopAddress();
                        int label = routePath.getLabel().intValue();
                        if (FibHelper.isControllerManagedVpnInterfaceRoute(RouteOrigin.value(vrfEntry.getOrigin()))) {
                            LOG.info("handleVpnsExportingRoutesImporting: Importing fib entry rd {} prefix {}" + " nexthop {} label {} to vpn {} vpnRd {}", vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
                            fibManager.addOrUpdateFibEntry(vpnRd, null, /*macAddress*/
                            prefix, Collections.singletonList(nh), VrfEntry.EncapType.Mplsgre, label, 0, /*l3vni*/
                            gwMac, null, /*parentVpnRd*/
                            RouteOrigin.SELF_IMPORTED, writeConfigTxn);
                        } else {
                            LOG.info("handleVpnsExportingRoutes: Importing subnet route fib entry rd {} prefix {}" + " nexthop {} label {} to vpn {} vpnRd {}", vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
                            SubnetRoute route = vrfEntry.getAugmentation(SubnetRoute.class);
                            importSubnetRouteForNewVpn(vpnRd, prefix, nh, label, route, writeConfigTxn);
                        }
                    });
                } catch (RuntimeException e) {
                    LOG.error("getNextHopAddressList: Exception occurred while importing route with rd {}" + " prefix {} routePaths {} to vpn {} vpnRd {}", vpn.getVrfId(), vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), vpnName, vpnRd);
                }
            }
            writeConfigTxn.submit();
        } else {
            LOG.info("getNextHopAddressList: No vrf entries to import from vpn {} with rd {} to vpn {} with rd {}", vpn.getVpnInstanceName(), vpn.getVrfId(), vpnName, vpnRd);
        }
    }
}
Also used : WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) VrfEntry(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry) VpnInstanceOpDataEntry(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry) SubnetRoute(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.SubnetRoute)

Aggregations

WriteTransaction (org.opendaylight.controller.md.sal.binding.api.WriteTransaction)320 ArrayList (java.util.ArrayList)74 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)60 BigInteger (java.math.BigInteger)43 Test (org.junit.Test)38 Uuid (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid)37 ExecutionException (java.util.concurrent.ExecutionException)33 InstanceIdentifier (org.opendaylight.yangtools.yang.binding.InstanceIdentifier)28 TransactionCommitFailedException (org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException)25 DataBroker (org.opendaylight.controller.md.sal.binding.api.DataBroker)23 Nodes (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes)23 FlowCapableNode (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode)22 LogicalDatastoreType (org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType)19 RpcResult (org.opendaylight.yangtools.yang.common.RpcResult)17 List (java.util.List)16 Node (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node)16 VpnInstanceOpDataEntry (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry)16 DataObject (org.opendaylight.yangtools.yang.binding.DataObject)15 Flow (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow)14 VpnToDpnList (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList)14