Search in sources :

Example 16 with Tunnel

use of org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel 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 17 with Tunnel

use of org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel in project netvirt by opendaylight.

the class NexthopManager method removeOrUpdateDcGwLoadBalancingGroup.

/**
 * This method is invoked when the tunnel state is removed from DS.
 * If the there is just one DC-GW left in configuration then the LB groups can be deleted.
 * Otherwise, the groups are just updated.
 */
public void removeOrUpdateDcGwLoadBalancingGroup(List<String> availableDcGws, BigInteger dpnId, String destinationIp) {
    Preconditions.checkNotNull(availableDcGws, "There are no dc-gws present");
    WriteTransaction configTx = dataBroker.newWriteOnlyTransaction();
    WriteTransaction operationalTx = dataBroker.newWriteOnlyTransaction();
    int noOfDcGws = availableDcGws.size();
    // If availableDcGws does not contain the destination Ip it means this is a configuration delete.
    if (!availableDcGws.contains(destinationIp)) {
        availableDcGws.add(destinationIp);
        Collections.sort(availableDcGws);
    }
    // TODO : Place the logic to construct all possible DC-GW combination here.
    int bucketId = availableDcGws.indexOf(destinationIp);
    Optional<DpnLbNexthops> dpnLbNextHops = fibUtil.getDpnLbNexthops(dpnId, destinationIp);
    if (!dpnLbNextHops.isPresent()) {
        return;
    }
    List<String> nextHopKeys = dpnLbNextHops.get().getNexthopKey();
    nextHopKeys.forEach(nextHopKey -> {
        Optional<Nexthops> optionalNextHops = fibUtil.getNexthops(nextHopKey);
        if (!optionalNextHops.isPresent()) {
            return;
        }
        Nexthops nexthops = optionalNextHops.get();
        final String groupId = nexthops.getGroupId();
        final long groupIdValue = Long.parseLong(groupId);
        if (noOfDcGws > 1) {
            mdsalApiManager.removeBucketToTx(dpnId, groupIdValue, bucketId, configTx);
        } else {
            Group group = MDSALUtil.buildGroup(groupIdValue, nextHopKey, GroupTypes.GroupSelect, MDSALUtil.buildBucketLists(Collections.emptyList()));
            LOG.trace("Removed LB group {} on dpn {}", group, dpnId);
            mdsalApiManager.removeGroupToTx(dpnId, group, configTx);
            removeNextHopPointer(nextHopKey);
        }
        // When the DC-GW is removed from configuration.
        if (noOfDcGws != availableDcGws.size()) {
            FibUtil.removeOrUpdateNextHopInfo(dpnId, nextHopKey, groupId, nexthops, operationalTx);
        }
    });
    FibUtil.removeDpnIdToNextHopInfo(destinationIp, dpnId, operationalTx);
    configTx.submit();
    operationalTx.submit();
    return;
}
Also used : WriteTransaction(org.opendaylight.controller.md.sal.binding.api.WriteTransaction) DpnLbNexthops(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpid.l3vpn.lb.nexthops.DpnLbNexthops) ActionGroup(org.opendaylight.genius.mdsalutil.actions.ActionGroup) Group(org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group) VpnNexthops(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops) Nexthops(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops) DpnLbNexthops(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpid.l3vpn.lb.nexthops.DpnLbNexthops)

Example 18 with Tunnel

use of org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel in project netvirt by opendaylight.

the class ElanL2GatewayMulticastUtils method getTepIpOfDesignatedSwitchForExternalTunnel.

/**
 * Gets the tep ip of designated switch for external tunnel.
 *
 * @param l2GwDevice
 *            the l2 gw device
 * @param elanInstanceName
 *            the elan instance name
 * @return the tep ip of designated switch for external tunnel
 */
public IpAddress getTepIpOfDesignatedSwitchForExternalTunnel(L2GatewayDevice l2GwDevice, String elanInstanceName) {
    IpAddress tepIp = null;
    if (l2GwDevice.getTunnelIp() == null) {
        LOG.warn("Tunnel IP not found for {}", l2GwDevice.getDeviceName());
        return tepIp;
    }
    DesignatedSwitchForTunnel desgSwitch = getDesignatedSwitchForExternalTunnel(l2GwDevice.getTunnelIp(), elanInstanceName);
    if (desgSwitch != null) {
        tepIp = elanItmUtils.getSourceDpnTepIp(BigInteger.valueOf(desgSwitch.getDpId()), new NodeId(l2GwDevice.getHwvtepNodeId()));
    }
    return tepIp;
}
Also used : DesignatedSwitchForTunnel(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp.rev160428.designated.switches._for.external.tunnels.DesignatedSwitchForTunnel) NodeId(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId) IpAddress(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress)

Example 19 with Tunnel

use of org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel in project netvirt by opendaylight.

the class ElanDmacUtils method buildDmacFlowForExternalRemoteMac.

/**
 * Builds a Flow to be programmed in a DPN's DMAC table. This method must be
 * used when the MAC is located in an External Device (TOR). The flow
 * matches on the specified MAC and 1) sends the packet over the CSS-TOR
 * tunnel if SHFlag is not set, or 2) drops it if SHFlag is set (what means
 * the packet came from an external tunnel)
 *
 * @param dpId
 *            DPN whose DMAC table is going to be modified
 * @param extDeviceNodeId
 *            Hwvtep node where the mac is attached to
 * @param elanTag
 *            ElanId to which the MAC is being added to
 * @param vni
 *            the vni
 * @param dstMacAddress
 *            The mac address to be programmed
 * @param displayName
 *            the display name
 * @return the flow
 */
@SuppressWarnings("checkstyle:IllegalCatch")
public Flow buildDmacFlowForExternalRemoteMac(BigInteger dpId, String extDeviceNodeId, long elanTag, Long vni, String dstMacAddress, String displayName) {
    List<MatchInfo> mkMatches = ElanUtils.buildMatchesForElanTagShFlagAndDstMac(elanTag, /* shFlag */
    false, dstMacAddress);
    List<Instruction> mkInstructions = new ArrayList<>();
    try {
        List<Action> actions = elanItmUtils.getExternalTunnelItmEgressAction(dpId, new NodeId(extDeviceNodeId), vni);
        mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
    } catch (Exception e) {
        LOG.error("Could not get Egress Actions for DpId {} externalNode {}", dpId, extDeviceNodeId, e);
    }
    return MDSALUtil.buildFlowNew(NwConstants.ELAN_DMAC_TABLE, ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, extDeviceNodeId, dstMacAddress, elanTag, false), 20, /* prio */
    displayName, 0, /* idleTimeout */
    0, /* hardTimeout */
    ElanConstants.COOKIE_ELAN_KNOWN_DMAC.add(BigInteger.valueOf(elanTag)), mkMatches, mkInstructions);
}
Also used : Action(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action) MatchInfo(org.opendaylight.genius.mdsalutil.MatchInfo) ArrayList(java.util.ArrayList) NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId) Instruction(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction) ElanException(org.opendaylight.netvirt.elan.ElanException)

Example 20 with Tunnel

use of org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel in project netvirt by opendaylight.

the class ElanItmUtils method getExternalTunnelItmEgressAction.

/**
 * Builds the list of actions to be taken when sending the packet over an
 * external VxLan tunnel interface, such as stamping the VNI on the VxLAN
 * header, setting the vlanId if it proceeds and output the packet over the
 * right port.
 *
 * @param srcDpnId
 *            Dpn where the tunnelInterface is located
 * @param torNode
 *            NodeId of the ExternalDevice where the packet must be sent to.
 * @param vni
 *            Vni to be stamped on the VxLAN Header.
 * @return the external itm egress action
 */
public List<Action> getExternalTunnelItmEgressAction(BigInteger srcDpnId, NodeId torNode, long vni) {
    List<Action> result = Collections.emptyList();
    GetExternalTunnelInterfaceNameInput input = new GetExternalTunnelInterfaceNameInputBuilder().setDestinationNode(torNode.getValue()).setSourceNode(srcDpnId.toString()).setTunnelType(TunnelTypeVxlan.class).build();
    Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> output = itmRpcService.getExternalTunnelInterfaceName(input);
    try {
        if (output.get().isSuccessful()) {
            GetExternalTunnelInterfaceNameOutput tunnelInterfaceNameOutput = output.get().getResult();
            String tunnelIfaceName = tunnelInterfaceNameOutput.getInterfaceName();
            LOG.debug("Received tunnelInterfaceName from getTunnelInterfaceName RPC {}", tunnelIfaceName);
            result = buildTunnelItmEgressActions(tunnelIfaceName, vni);
        }
    } catch (InterruptedException | ExecutionException e) {
        LOG.error("Error in RPC call getTunnelInterfaceName {}", e);
    }
    return result;
}
Also used : Action(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action) GetExternalTunnelInterfaceNameInput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput) GetExternalTunnelInterfaceNameOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput) RpcResult(org.opendaylight.yangtools.yang.common.RpcResult) TunnelTypeVxlan(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan) ExecutionException(java.util.concurrent.ExecutionException) GetExternalTunnelInterfaceNameInputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInputBuilder)

Aggregations

BigInteger (java.math.BigInteger)45 ArrayList (java.util.ArrayList)43 IfTunnel (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel)27 RpcResult (org.opendaylight.yangtools.yang.common.RpcResult)23 ExecutionException (java.util.concurrent.ExecutionException)19 WriteTransaction (org.opendaylight.controller.md.sal.binding.api.WriteTransaction)17 Interface (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface)17 TunnelTypeVxlan (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan)17 ParentRefs (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs)16 IpAddress (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress)15 Action (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action)14 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)12 List (java.util.List)12 InterfaceKey (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey)12 Uuid (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid)12 Test (org.junit.Test)8 TransportZone (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone)8 MacAddress (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress)7 IfTunnelBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder)7 TunnelIpv4MatchBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder)7