Search in sources :

Example 6 with GroupEntity

use of org.opendaylight.genius.mdsalutil.GroupEntity in project netvirt by opendaylight.

the class NaptSwitchHA method installSnatGroupEntry.

// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
protected void installSnatGroupEntry(BigInteger dpnId, List<BucketInfo> bucketInfo, String routerName) {
    GroupEntity groupEntity = null;
    try {
        long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
        LOG.debug("installSnatGroupEntry : install SnatMissEntry for groupId {} for dpnId {} for router {}", groupId, dpnId, routerName);
        groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll, bucketInfo);
        mdsalManager.syncInstallGroup(groupEntity);
        LOG.debug("installSnatGroupEntry : installed the SNAT to NAPT GroupEntity:{}", groupEntity);
    } catch (Exception ex) {
        LOG.error("installSnatGroupEntry : Failed to install group for groupEntity {}", groupEntity, ex);
    }
}
Also used : GroupEntity(org.opendaylight.genius.mdsalutil.GroupEntity) ExecutionException(java.util.concurrent.ExecutionException)

Example 7 with GroupEntity

use of org.opendaylight.genius.mdsalutil.GroupEntity in project netvirt by opendaylight.

the class NaptSwitchHA method isNaptSwitchDown.

// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public boolean isNaptSwitchDown(String routerName, Long routerId, BigInteger dpnId, BigInteger naptSwitch, Long routerVpnId, Collection<String> externalIpCache, boolean isClearBgpRts, WriteTransaction writeFlowInvTx) {
    externalIpsCache = externalIpCache;
    if (!naptSwitch.equals(dpnId)) {
        LOG.debug("isNaptSwitchDown : DpnId {} is not a naptSwitch {} for Router {}", dpnId, naptSwitch, routerName);
        return false;
    }
    LOG.debug("NaptSwitch {} is down for Router {}", naptSwitch, routerName);
    if (routerId == NatConstants.INVALID_ID) {
        LOG.error("isNaptSwitchDown : Invalid routerId returned for routerName {}", routerName);
        return true;
    }
    Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
    String vpnName = getExtNetworkVpnName(routerName, networkId);
    // elect a new NaptSwitch
    naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
    if (natMode == NatMode.Conntrack) {
        Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
        natServiceManager.notify(extRouters, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
        natServiceManager.notify(extRouters, naptSwitch, naptSwitch, SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
    } else {
        if (naptSwitch.equals(BigInteger.ZERO)) {
            LOG.warn("isNaptSwitchDown : No napt switch is elected since all the switches for router {}" + " are down. SNAT IS NOT SUPPORTED FOR ROUTER {}", routerName, routerName);
            boolean naptUpdatedStatus = updateNaptSwitch(routerName, naptSwitch);
            if (!naptUpdatedStatus) {
                LOG.debug("isNaptSwitchDown : Failed to update naptSwitch {} for router {} in ds", naptSwitch, routerName);
            }
            // clearBgpRoutes
            if (externalIpsCache != null) {
                if (vpnName != null) {
                    // if (externalIps != null) {
                    if (isClearBgpRts) {
                        LOG.debug("isNaptSwitchDown : Clearing both FIB entries and the BGP routes");
                        for (String externalIp : externalIpsCache) {
                            externalRouterListener.clearBgpRoutes(externalIp, vpnName);
                        }
                    } else {
                        LOG.debug("isNaptSwitchDown : Clearing the FIB entries but not the BGP routes");
                        String rd = NatUtil.getVpnRd(dataBroker, vpnName);
                        for (String externalIp : externalIpsCache) {
                            LOG.debug("isNaptSwitchDown : Removing Fib entry rd {} prefix {}", rd, externalIp);
                            fibManager.removeFibEntry(rd, externalIp, null);
                        }
                    }
                } else {
                    LOG.debug("isNaptSwitchDown : vpn is not associated to extn/w for router {}", routerName);
                }
            } else {
                LOG.debug("isNaptSwitchDown : No ExternalIps found for subnets under router {}, " + "no bgp routes need to be cleared", routerName);
            }
            return true;
        }
        // checking elected switch health status
        if (!getSwitchStatus(naptSwitch)) {
            LOG.error("isNaptSwitchDown : Newly elected Napt switch {} for router {} is down", naptSwitch, routerName);
            return true;
        }
        LOG.debug("isNaptSwitchDown : New NaptSwitch {} is up for Router {} and can proceed for flow installation", naptSwitch, routerName);
        // update napt model for new napt switch
        boolean naptUpdated = updateNaptSwitch(routerName, naptSwitch);
        if (naptUpdated) {
            // update group of ordinary switch point to naptSwitch tunnel port
            updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
        } else {
            LOG.error("isNaptSwitchDown : Failed to update naptSwitch model for newNaptSwitch {} for router {}", naptSwitch, routerName);
        }
        // update table26 forward packets to table46(outbound napt table)
        FlowEntity flowEntity = buildSnatFlowEntityForNaptSwitch(naptSwitch, routerName, routerVpnId, NatConstants.ADD_FLOW);
        if (flowEntity == null) {
            LOG.error("isNaptSwitchDown : Failed to populate flowentity for router {} in naptSwitch {}", routerName, naptSwitch);
        } else {
            LOG.debug("isNaptSwitchDown : Successfully installed flow in naptSwitch {} for router {}", naptSwitch, routerName);
            mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
        }
        installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, writeFlowInvTx);
        boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerName, routerId, dpnId, naptSwitch, routerVpnId, networkId);
        if (flowInstalledStatus) {
            LOG.debug("isNaptSwitchDown :Installed all active session flows in newNaptSwitch {} for routerName {}", naptSwitch, routerName);
        } else {
            LOG.error("isNaptSwitchDown : Failed to install flows in newNaptSwitch {} for routerId {}", naptSwitch, routerId);
        }
        // remove group in new naptswitch, coz this switch acted previously as ordinary switch
        long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
        GroupEntity groupEntity = null;
        try {
            groupEntity = MDSALUtil.buildGroupEntity(naptSwitch, groupId, routerName, GroupTypes.GroupAll, Collections.emptyList());
            LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}", naptSwitch);
            mdsalManager.removeGroup(groupEntity);
        } catch (Exception ex) {
            LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", groupEntity, ex);
        }
    }
    return true;
}
Also used : Uuid(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid) Routers(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers) GroupEntity(org.opendaylight.genius.mdsalutil.GroupEntity) ExecutionException(java.util.concurrent.ExecutionException) FlowEntity(org.opendaylight.genius.mdsalutil.FlowEntity)

Example 8 with GroupEntity

use of org.opendaylight.genius.mdsalutil.GroupEntity in project netvirt by opendaylight.

the class AbstractSnatService method installSnatMissEntry.

protected void installSnatMissEntry(BigInteger dpnId, Long routerId, String routerName, BigInteger primarySwitchId, String externalIp, long extSubnetId, int addOrRemove) {
    LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
    List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
    String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
    List<BucketInfo> listBucketInfo = new ArrayList<>();
    if (ifNamePrimary != null) {
        LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
        listActionInfoPrimary = NatUtil.getEgressActionsForInterface(interfaceManager, ifNamePrimary, routerId);
    }
    BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
    listBucketInfo.add(0, bucketPrimary);
    LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId, listBucketInfo.get(0));
    // Install the select group
    long groupId = createGroupId(getGroupIdKey(routerName));
    GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll, listBucketInfo);
    LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
    mdsalManager.installGroup(groupEntity);
    // Install miss entry pointing to group
    LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}", dpnId, routerName, groupId);
    List<MatchInfo> matches = new ArrayList<>();
    matches.add(new MatchEthernetType(0x0800L));
    matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
    List<ActionInfo> actionsInfo = new ArrayList<>();
    actionsInfo.add(new ActionSetFieldTunnelId(BigInteger.valueOf(routerId)));
    LOG.debug("installSnatMissEntry : Setting the tunnel to the list of action infos {}", actionsInfo);
    actionsInfo.add(new ActionGroup(groupId));
    List<InstructionInfo> instructions = new ArrayList<>();
    instructions.add(new InstructionApplyActions(actionsInfo));
    String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
    syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
    // Install the FIB entry for traffic destined to SNAT IP in Non-NAPT switch.
    matches = new ArrayList<>();
    actionsInfo = new ArrayList<>();
    matches.add(new MatchEthernetType(0x0800L));
    if (addOrRemove == NwConstants.ADD_FLOW) {
        if (extSubnetId == NatConstants.INVALID_ID) {
            LOG.error("installSnatMissEntry : external subnet id is invalid.");
            return;
        }
        actionsInfo.add(new ActionSetFieldTunnelId(BigInteger.valueOf(extSubnetId)));
        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId), MetaDataUtil.METADATA_MASK_VRFID));
    }
    matches.add(new MatchIpv4Destination(externalIp, "32"));
    LOG.debug("installSnatMissEntry : Setting the tunnel to the list of action infos {}", actionsInfo);
    actionsInfo.add(new ActionGroup(groupId));
    instructions = new ArrayList<>();
    instructions.add(new InstructionApplyActions(actionsInfo));
    flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
    flowRef = flowRef + "inboundmiss" + externalIp;
    syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
}
Also used : MatchMetadata(org.opendaylight.genius.mdsalutil.matches.MatchMetadata) ArrayList(java.util.ArrayList) MatchIpv4Destination(org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination) ActionInfo(org.opendaylight.genius.mdsalutil.ActionInfo) ActionSetFieldTunnelId(org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId) MatchEthernetType(org.opendaylight.genius.mdsalutil.matches.MatchEthernetType) MatchInfo(org.opendaylight.genius.mdsalutil.MatchInfo) ActionGroup(org.opendaylight.genius.mdsalutil.actions.ActionGroup) InstructionInfo(org.opendaylight.genius.mdsalutil.InstructionInfo) GroupEntity(org.opendaylight.genius.mdsalutil.GroupEntity) BucketInfo(org.opendaylight.genius.mdsalutil.BucketInfo) InstructionApplyActions(org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions)

Example 9 with GroupEntity

use of org.opendaylight.genius.mdsalutil.GroupEntity in project netvirt by opendaylight.

the class NexthopManager method removeLocalNextHop.

public void removeLocalNextHop(BigInteger dpnId, Long vpnId, String ipNextHopAddress, String ipPrefixAddress) {
    String ipPrefixStr = vpnId + ipPrefixAddress;
    VpnNexthop prefixNh = null;
    synchronized (ipPrefixStr.intern()) {
        prefixNh = getVpnNexthop(vpnId, ipPrefixAddress);
    }
    String ipAddress = prefixNh != null ? ipPrefixAddress : ipNextHopAddress;
    String nextHopLockStr = vpnId + ipAddress;
    synchronized (nextHopLockStr.intern()) {
        VpnNexthop nh = getVpnNexthop(vpnId, ipAddress);
        if (nh != null) {
            int newFlowrefCnt = nh.getFlowrefCount() - 1;
            if (newFlowrefCnt == 0) {
                // remove the group only if there are no more flows using this group
                GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupAll, Collections.EMPTY_LIST);
                // remove Group ...
                mdsalApiManager.removeGroup(groupEntity);
                // update MD-SAL DS
                removeVpnNexthopFromDS(vpnId, ipAddress);
                // release groupId
                removeNextHopPointer(getNextHopKey(vpnId, ipAddress));
                LOG.debug("Local Next hop {} for {} {} on dpn {} successfully deleted", nh.getEgressPointer(), vpnId, ipAddress, dpnId);
            } else {
                // just update the flowrefCount of the vpnNexthop
                VpnNexthop currNh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(newFlowrefCnt).build();
                LOG.trace("Updating vpnnextHop {} for refCount {} to Operational DS", currNh, newFlowrefCnt);
                MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.OPERATIONAL, getVpnNextHopIdentifier(vpnId, ipAddress), currNh);
            }
        } else {
            // throw error
            LOG.error("Local Next hop for Prefix {} VpnId {} on dpn {} not deleted", ipAddress, vpnId, dpnId);
        }
    }
}
Also used : VpnNexthopKey(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopKey) GroupEntity(org.opendaylight.genius.mdsalutil.GroupEntity) VpnNexthop(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop) VpnNexthopBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopBuilder)

Example 10 with GroupEntity

use of org.opendaylight.genius.mdsalutil.GroupEntity in project netvirt by opendaylight.

the class NexthopManager method createLocalNextHop.

public long createLocalNextHop(long vpnId, BigInteger dpnId, String ifName, String ipNextHopAddress, String ipPrefixAddress, String gwMacAddress, String jobKey) {
    String vpnName = fibUtil.getVpnNameFromId(vpnId);
    if (vpnName == null) {
        return 0;
    }
    String macAddress = fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipPrefixAddress);
    String ipAddress = macAddress != null ? ipPrefixAddress : ipNextHopAddress;
    long groupId = createNextHopPointer(getNextHopKey(vpnId, ipAddress));
    if (groupId == 0) {
        LOG.error("Unable to allocate groupId for vpnId {} , prefix {}  IntfName {}, nextHopAddr {}", vpnId, ipAddress, ifName, ipNextHopAddress);
        return groupId;
    }
    String nextHopLockStr = vpnId + ipAddress;
    jobCoordinator.enqueueJob(jobKey, () -> {
        synchronized (nextHopLockStr.intern()) {
            VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
            LOG.trace("nexthop: {} retrieved for vpnId {}, prefix {}, ifName {} on dpn {}", nexthop, vpnId, ipAddress, ifName, dpnId);
            if (nexthop == null) {
                String encMacAddress = macAddress == null ? fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipAddress) : macAddress;
                List<BucketInfo> listBucketInfo = new ArrayList<>();
                List<ActionInfo> listActionInfo = new ArrayList<>();
                int actionKey = 0;
                // MAC re-write
                if (encMacAddress != null) {
                    if (gwMacAddress != null) {
                        LOG.trace("The Local NextHop Group Source Mac {} for VpnInterface {} on VPN {}", gwMacAddress, ifName, vpnId);
                        listActionInfo.add(new ActionSetFieldEthernetSource(actionKey++, new MacAddress(gwMacAddress)));
                    }
                    listActionInfo.add(new ActionSetFieldEthernetDestination(actionKey++, new MacAddress(encMacAddress)));
                // listActionInfo.add(0, new ActionPopMpls());
                } else {
                    // FIXME: Log message here.
                    LOG.debug("mac address for new local nexthop is null");
                }
                listActionInfo.addAll(getEgressActionsForInterface(ifName, actionKey));
                BucketInfo bucket = new BucketInfo(listActionInfo);
                listBucketInfo.add(bucket);
                GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, ipAddress, GroupTypes.GroupAll, listBucketInfo);
                LOG.trace("Install LNH Group: id {}, mac address {}, interface {} for prefix {}", groupId, encMacAddress, ifName, ipAddress);
                // Try to install group directly on the DPN bypassing the FRM, in order to avoid waiting for the
                // group to get installed before programming the flows
                installGroupOnDpn(groupId, dpnId, ipAddress, listBucketInfo, getNextHopKey(vpnId, ipAddress), GroupTypes.GroupAll);
                // install Group
                mdsalApiManager.syncInstallGroup(groupEntity);
                // update MD-SAL DS
                addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
            } else {
                // nexthop exists already; a new flow is going to point to
                // it, increment the flowrefCount by 1
                int flowrefCnt = nexthop.getFlowrefCount() + 1;
                VpnNexthop nh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(flowrefCnt).build();
                LOG.trace("Updating vpnnextHop {} for refCount {} to Operational DS", nh, flowrefCnt);
                MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.OPERATIONAL, getVpnNextHopIdentifier(vpnId, ipAddress), nh);
            }
        }
        return Collections.emptyList();
    });
    return groupId;
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ActionInfo(org.opendaylight.genius.mdsalutil.ActionInfo) VpnNexthop(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop) MacAddress(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress) VpnNexthopBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopBuilder) ActionSetFieldEthernetDestination(org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetDestination) ActionSetFieldEthernetSource(org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource) VpnNexthopKey(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopKey) GroupEntity(org.opendaylight.genius.mdsalutil.GroupEntity) BucketInfo(org.opendaylight.genius.mdsalutil.BucketInfo)

Aggregations

GroupEntity (org.opendaylight.genius.mdsalutil.GroupEntity)17 FlowEntity (org.opendaylight.genius.mdsalutil.FlowEntity)5 BigInteger (java.math.BigInteger)4 ArrayList (java.util.ArrayList)4 BucketInfo (org.opendaylight.genius.mdsalutil.BucketInfo)4 ActionInfo (org.opendaylight.genius.mdsalutil.ActionInfo)3 ExecutionException (java.util.concurrent.ExecutionException)2 Test (org.junit.Test)2 AbstractConcurrentDataBrokerTest (org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest)2 InstructionInfo (org.opendaylight.genius.mdsalutil.InstructionInfo)2 MatchInfo (org.opendaylight.genius.mdsalutil.MatchInfo)2 ActionGroup (org.opendaylight.genius.mdsalutil.actions.ActionGroup)2 ActionSetFieldTunnelId (org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId)2 InstructionApplyActions (org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions)2 MatchEthernetType (org.opendaylight.genius.mdsalutil.matches.MatchEthernetType)2 MatchMetadata (org.opendaylight.genius.mdsalutil.matches.MatchMetadata)2 Uuid (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid)2 VpnNexthop (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop)2 VpnNexthopBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopBuilder)2 VpnNexthopKey (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopKey)2