Search in sources :

Example 16 with SwitchProperties

use of org.openkilda.model.SwitchProperties in project open-kilda by telstra.

the class LagPortOperationService method validatePhysicalPort.

private void validatePhysicalPort(SwitchId switchId, Set<SwitchFeature> features, Integer portNumber) throws InvalidDataException {
    if (portNumber == null || portNumber <= 0) {
        throw new InvalidDataException(format("Invalid physical port number %s. It can't be null or negative.", portNumber));
    }
    int bfdPortOffset = config.getBfdPortOffset();
    int bfdPortMaxNumber = config.getBfdPortMaxNumber();
    if (features.contains(BFD) && portNumber >= bfdPortOffset && portNumber <= bfdPortMaxNumber) {
        throw new InvalidDataException(format("Physical port number %d intersects with BFD port range [%d, %d]", portNumber, bfdPortOffset, bfdPortMaxNumber));
    }
    long lagPortOffset = config.getPoolConfig().getIdMinimum();
    if (portNumber >= lagPortOffset) {
        throw new InvalidDataException(format("Physical port number %d can't be greater than LAG port offset %d.", portNumber, lagPortOffset));
    }
    Collection<Isl> isls = islRepository.findByEndpoint(switchId, portNumber);
    if (!isls.isEmpty()) {
        throw new InvalidDataException(format("Physical port number %d intersects with existing ISLs %s.", portNumber, isls));
    }
    Optional<SwitchProperties> properties = switchPropertiesRepository.findBySwitchId(switchId);
    if (properties.isPresent() && Objects.equals(properties.get().getServer42Port(), portNumber)) {
        throw new InvalidDataException(format("Physical port number %d on switch %s is server42 port.", portNumber, switchId));
    }
    Set<String> flowIds = flowRepository.findByEndpoint(switchId, portNumber).stream().map(Flow::getFlowId).collect(Collectors.toSet());
    if (!flowIds.isEmpty()) {
        throw new InvalidDataException(format("Physical port %d already used by following flows: %s. You must " + "remove these flows to be able to use the port in LAG.", portNumber, flowIds));
    }
    Collection<FlowMirrorPath> mirrorPaths = flowMirrorPathRepository.findByEgressSwitchIdAndPort(switchId, portNumber);
    if (!mirrorPaths.isEmpty()) {
        Map<String, List<PathId>> mirrorPathByFLowIdMap = new HashMap<>();
        for (FlowMirrorPath path : mirrorPaths) {
            String flowId = path.getFlowMirrorPoints().getFlowPath().getFlowId();
            mirrorPathByFLowIdMap.computeIfAbsent(flowId, ignore -> new ArrayList<>());
            mirrorPathByFLowIdMap.get(flowId).add(path.getPathId());
        }
        String message = mirrorPathByFLowIdMap.entrySet().stream().map(entry -> format("flow '%s': %s", entry.getKey(), entry.getValue())).collect(Collectors.joining(", "));
        throw new InvalidDataException(format("Physical port %d already used as sink by following mirror points %s", portNumber, message));
    }
}
Also used : TransactionManager(org.openkilda.persistence.tx.TransactionManager) SwitchFeature(org.openkilda.model.SwitchFeature) LRUMap(org.apache.commons.collections4.map.LRUMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SwitchNotFoundException(org.openkilda.wfm.topology.switchmanager.error.SwitchNotFoundException) Flow(org.openkilda.model.Flow) PoolManager(org.openkilda.wfm.share.utils.PoolManager) IslRepository(org.openkilda.persistence.repositories.IslRepository) Map(java.util.Map) FlowRepository(org.openkilda.persistence.repositories.FlowRepository) LagLogicalPort(org.openkilda.model.LagLogicalPort) LagPortNotFoundException(org.openkilda.wfm.topology.switchmanager.error.LagPortNotFoundException) PathId(org.openkilda.model.PathId) SwitchProperties(org.openkilda.model.SwitchProperties) IpSocketAddress(org.openkilda.model.IpSocketAddress) Switch(org.openkilda.model.Switch) PhysicalPortRepository(org.openkilda.persistence.repositories.PhysicalPortRepository) InconsistentDataException(org.openkilda.wfm.topology.switchmanager.error.InconsistentDataException) NonNull(lombok.NonNull) Collection(java.util.Collection) SetView(com.google.common.collect.Sets.SetView) Set(java.util.Set) RetryPolicy(net.jodah.failsafe.RetryPolicy) BFD(org.openkilda.model.SwitchFeature.BFD) FlowMirrorPathRepository(org.openkilda.persistence.repositories.FlowMirrorPathRepository) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) RepositoryFactory(org.openkilda.persistence.repositories.RepositoryFactory) SwitchPropertiesRepository(org.openkilda.persistence.repositories.SwitchPropertiesRepository) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) SwitchId(org.openkilda.model.SwitchId) LagLogicalPortRepository(org.openkilda.persistence.repositories.LagLogicalPortRepository) FlowMirrorPath(org.openkilda.model.FlowMirrorPath) InvalidDataException(org.openkilda.wfm.topology.switchmanager.error.InvalidDataException) Optional(java.util.Optional) ConstraintViolationException(org.openkilda.persistence.exceptions.ConstraintViolationException) Isl(org.openkilda.model.Isl) PhysicalPort(org.openkilda.model.PhysicalPort) SwitchRepository(org.openkilda.persistence.repositories.SwitchRepository) Isl(org.openkilda.model.Isl) HashMap(java.util.HashMap) InvalidDataException(org.openkilda.wfm.topology.switchmanager.error.InvalidDataException) ArrayList(java.util.ArrayList) List(java.util.List) SwitchProperties(org.openkilda.model.SwitchProperties) FlowMirrorPath(org.openkilda.model.FlowMirrorPath)

Example 17 with SwitchProperties

use of org.openkilda.model.SwitchProperties in project open-kilda by telstra.

the class CommandBuilderImpl method buildCommandsToSyncMissingRules.

@Override
public List<BaseFlow> buildCommandsToSyncMissingRules(SwitchId switchId, List<Long> switchRules) {
    List<BaseFlow> commands = new ArrayList<>(buildInstallDefaultRuleCommands(switchId, switchRules));
    commands.addAll(buildInstallFlowSharedRuleCommands(switchId, switchRules));
    flowPathRepository.findBySegmentDestSwitch(switchId).forEach(flowPath -> {
        FlowSegmentCookie mirrorCookie = flowPath.getCookie().toBuilder().mirror(true).build();
        boolean switchRulesContainsFlowPathCookie = switchRules.contains(flowPath.getCookie().getValue());
        boolean switchRulesContainsMirrorCookie = switchRules.contains(mirrorCookie.getValue());
        if (switchRulesContainsFlowPathCookie || switchRulesContainsMirrorCookie) {
            PathSegment segment = flowPath.getSegments().stream().filter(pathSegment -> pathSegment.getDestSwitchId().equals(switchId)).findAny().orElseThrow(() -> new IllegalStateException(format("PathSegment not found, path %s, switch %s", flowPath, switchId)));
            log.info("Rule {} is to be (re)installed on switch {}", flowPath.getCookie(), switchId);
            commands.addAll(buildInstallCommandFromSegment(flowPath, segment, switchRulesContainsFlowPathCookie, switchRulesContainsMirrorCookie));
        }
    });
    SwitchProperties switchProperties = getSwitchProperties(switchId);
    flowPathRepository.findByEndpointSwitch(switchId).forEach(flowPath -> {
        FlowSegmentCookie mirrorCookie = flowPath.getCookie().toBuilder().mirror(true).build();
        boolean switchRulesContainsFlowPathCookie = switchRules.contains(flowPath.getCookie().getValue());
        boolean switchRulesContainsMirrorCookie = switchRules.contains(mirrorCookie.getValue());
        if (switchRulesContainsFlowPathCookie || switchRulesContainsMirrorCookie) {
            Flow flow = getFlow(flowPath);
            if (flowPath.isOneSwitchFlow()) {
                log.info("One-switch flow {} is to be (re)installed on switch {}", flowPath.getCookie(), switchId);
                SwitchId swId = flowPath.isForward() ? flow.getDestSwitchId() : flow.getSrcSwitchId();
                int port = flowPath.isForward() ? flow.getDestPort() : flow.getSrcPort();
                if (switchRulesContainsMirrorCookie) {
                    MirrorConfig mirrorConfig = makeMirrorConfig(flowPath, swId, port);
                    commands.add(flowCommandFactory.makeOneSwitchMirrorRule(flow, flowPath, mirrorConfig));
                }
                if (switchRulesContainsFlowPathCookie) {
                    commands.add(flowCommandFactory.makeOneSwitchRule(flow, flowPath));
                }
            } else if (flowPath.getSrcSwitchId().equals(switchId)) {
                log.info("Ingress flow {} is to be (re)installed on switch {}", flowPath.getCookie(), switchId);
                if (flowPath.getSegments().isEmpty()) {
                    log.warn("Output port was not found for ingress flow rule");
                } else {
                    PathSegment foundIngressSegment = flowPath.getSegments().get(0);
                    EncapsulationResources encapsulationResources = getEncapsulationResources(flowPath, flow);
                    if (switchRulesContainsMirrorCookie) {
                        MirrorConfig mirrorConfig = makeMirrorConfig(flowPath, foundIngressSegment.getSrcSwitchId(), foundIngressSegment.getSrcPort());
                        commands.add(flowCommandFactory.buildInstallIngressMirrorFlow(flow, flowPath, foundIngressSegment.getSrcPort(), encapsulationResources, foundIngressSegment.isSrcWithMultiTable(), mirrorConfig));
                    }
                    if (switchRulesContainsFlowPathCookie) {
                        commands.add(flowCommandFactory.buildInstallIngressFlow(flow, flowPath, foundIngressSegment.getSrcPort(), encapsulationResources, foundIngressSegment.isSrcWithMultiTable()));
                    }
                }
            }
        }
        long server42Cookie = flowPath.getCookie().toBuilder().type(CookieType.SERVER_42_FLOW_RTT_INGRESS).build().getValue();
        if (switchRules.contains(server42Cookie) && !flowPath.isOneSwitchFlow() && flowPath.getSrcSwitchId().equals(switchId)) {
            log.info("Ingress server 42 flow {} is to be (re)installed on switch {}", server42Cookie, switchId);
            if (flowPath.getSegments().isEmpty()) {
                log.warn("Output port was not found for server 42 ingress flow rule {}", server42Cookie);
            } else {
                Flow flow = getFlow(flowPath);
                PathSegment foundIngressSegment = flowPath.getSegments().get(0);
                EncapsulationResources encapsulationResources = getEncapsulationResources(flowPath, flow);
                commands.add(flowCommandFactory.buildInstallServer42IngressFlow(flow, flowPath, foundIngressSegment.getSrcPort(), switchProperties.getServer42Port(), switchProperties.getServer42MacAddress(), encapsulationResources, foundIngressSegment.isSrcWithMultiTable()));
            }
        }
        long loopCookie = flowPath.getCookie().toBuilder().looped(true).build().getValue();
        if (switchRules.contains(loopCookie)) {
            log.info("Loop rule with cookie {} is to be reinstalled on switch {}", loopCookie, switchId);
            Flow flow = getFlow(flowPath);
            EncapsulationResources encapsulationResources = getEncapsulationResources(flowPath, flow);
            if (flowPath.getSrcSwitch().getSwitchId().equals(switchId)) {
                boolean srcWithMultiTable = flowPath.getSegments().get(0).isSrcWithMultiTable();
                commands.add(flowCommandFactory.buildInstallIngressLoopFlow(flow, flowPath, encapsulationResources, srcWithMultiTable));
            } else {
                PathSegment lastSegment = flowPath.getSegments().get(flowPath.getSegments().size() - 1);
                boolean destWithMultiTable = lastSegment.isDestWithMultiTable();
                commands.add(flowCommandFactory.buildInstallTransitLoopFlow(flow, flowPath, lastSegment.getDestPort(), encapsulationResources, destWithMultiTable));
            }
        }
    });
    return commands;
}
Also used : FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) BaseFlow(org.openkilda.messaging.command.flow.BaseFlow) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) InstallServer42Flow(org.openkilda.messaging.command.flow.InstallServer42Flow) BaseFlow(org.openkilda.messaging.command.flow.BaseFlow) Flow(org.openkilda.model.Flow) RemoveFlow(org.openkilda.messaging.command.flow.RemoveFlow) BaseInstallFlow(org.openkilda.messaging.command.flow.BaseInstallFlow) InstallSharedFlow(org.openkilda.messaging.command.flow.InstallSharedFlow) EncapsulationResources(org.openkilda.wfm.share.flow.resources.EncapsulationResources) MirrorConfig(org.openkilda.model.MirrorConfig) SwitchProperties(org.openkilda.model.SwitchProperties)

Example 18 with SwitchProperties

use of org.openkilda.model.SwitchProperties in project open-kilda by telstra.

the class PersistenceDataAdapterTest method shouldProvideCorrectSwitchProperties.

@Test
public void shouldProvideCorrectSwitchProperties() {
    Set<SwitchId> switchIds = Sets.newHashSet(SWITCH_ID_1, SWITCH_ID_2);
    Switch sw1 = buildSwitch(SWITCH_ID_1, Collections.emptySet());
    SwitchProperties switchProperties1 = buildSwitchProperties(sw1, false);
    Switch sw2 = buildSwitch(SWITCH_ID_2, Collections.emptySet());
    SwitchProperties switchProperties2 = buildSwitchProperties(sw2, true);
    Map<SwitchId, SwitchProperties> switchProperties = new HashMap<>();
    switchProperties.put(SWITCH_ID_1, switchProperties1);
    switchProperties.put(SWITCH_ID_2, switchProperties2);
    when(switchPropertiesRepository.findBySwitchIds(switchIds)).thenReturn(switchProperties);
    adapter = PersistenceDataAdapter.builder().switchIds(switchIds).persistenceManager(persistenceManager).build();
    assertEquals(switchProperties1, adapter.getSwitchProperties(SWITCH_ID_1));
    assertEquals(switchProperties2, adapter.getSwitchProperties(SWITCH_ID_2));
    verify(switchPropertiesRepository).findBySwitchIds(switchIds);
    verifyNoMoreInteractions(switchPropertiesRepository);
}
Also used : Utils.buildSwitch(org.openkilda.rulemanager.Utils.buildSwitch) Switch(org.openkilda.model.Switch) HashMap(java.util.HashMap) SwitchId(org.openkilda.model.SwitchId) Utils.buildSwitchProperties(org.openkilda.rulemanager.Utils.buildSwitchProperties) SwitchProperties(org.openkilda.model.SwitchProperties) Test(org.junit.Test)

Example 19 with SwitchProperties

use of org.openkilda.model.SwitchProperties in project open-kilda by telstra.

the class RuleManagerImpl method getServiceRuleGenerators.

@VisibleForTesting
List<RuleGenerator> getServiceRuleGenerators(SwitchId switchId, DataAdapter adapter) {
    List<RuleGenerator> generators = new ArrayList<>();
    generators.add(serviceRulesFactory.getTableDefaultRuleGenerator(new Cookie(DROP_RULE_COOKIE), OfTable.INPUT));
    generators.add(serviceRulesFactory.getUniCastDiscoveryRuleGenerator());
    generators.add(serviceRulesFactory.getBroadCastDiscoveryRuleGenerator());
    generators.add(serviceRulesFactory.getDropDiscoveryLoopRuleGenerator());
    generators.add(serviceRulesFactory.getBfdCatchRuleGenerator());
    generators.add(serviceRulesFactory.getRoundTripLatencyRuleGenerator());
    generators.add(serviceRulesFactory.getUnicastVerificationVxlanRuleGenerator());
    SwitchProperties switchProperties = adapter.getSwitchProperties(switchId);
    if (switchProperties.isMultiTable()) {
        generators.add(serviceRulesFactory.getTableDefaultRuleGenerator(new Cookie(MULTITABLE_INGRESS_DROP_COOKIE), OfTable.INGRESS));
        generators.add(serviceRulesFactory.getTableDefaultRuleGenerator(new Cookie(MULTITABLE_TRANSIT_DROP_COOKIE), OfTable.TRANSIT));
        generators.add(serviceRulesFactory.getTableDefaultRuleGenerator(new Cookie(MULTITABLE_POST_INGRESS_DROP_COOKIE), OfTable.POST_INGRESS));
        generators.add(serviceRulesFactory.getTablePassThroughDefaultRuleGenerator(new Cookie(MULTITABLE_EGRESS_PASS_THROUGH_COOKIE), OfTable.TRANSIT, OfTable.EGRESS));
        generators.add(serviceRulesFactory.getTablePassThroughDefaultRuleGenerator(new Cookie(MULTITABLE_PRE_INGRESS_PASS_THROUGH_COOKIE), OfTable.INGRESS, OfTable.PRE_INGRESS));
        generators.add(serviceRulesFactory.getLldpPostIngressRuleGenerator());
        generators.add(serviceRulesFactory.getLldpPostIngressVxlanRuleGenerator());
        generators.add(serviceRulesFactory.getLldpPostIngressOneSwitchRuleGenerator());
        generators.add(serviceRulesFactory.getArpPostIngressRuleGenerator());
        generators.add(serviceRulesFactory.getArpPostIngressVxlanRuleGenerator());
        generators.add(serviceRulesFactory.getArpPostIngressOneSwitchRuleGenerator());
        if (switchProperties.isSwitchLldp()) {
            generators.add(serviceRulesFactory.getLldpTransitRuleGenerator());
            generators.add(serviceRulesFactory.getLldpInputPreDropRuleGenerator());
            generators.add(serviceRulesFactory.getLldpIngressRuleGenerator());
        }
        if (switchProperties.isSwitchArp()) {
            generators.add(serviceRulesFactory.getArpTransitRuleGenerator());
            generators.add(serviceRulesFactory.getArpInputPreDropRuleGenerator());
            generators.add(serviceRulesFactory.getArpIngressRuleGenerator());
        }
        Set<Integer> islPorts = adapter.getSwitchIslPorts(switchId);
        islPorts.forEach(islPort -> {
            generators.add(serviceRulesFactory.getEgressIslVxlanRuleGenerator(islPort));
            generators.add(serviceRulesFactory.getEgressIslVlanRuleGenerator(islPort));
            generators.add(serviceRulesFactory.getTransitIslVxlanRuleGenerator(islPort));
        });
    }
    Integer server42Port = switchProperties.getServer42Port();
    Integer server42Vlan = switchProperties.getServer42Vlan();
    MacAddress server42MacAddress = switchProperties.getServer42MacAddress();
    KildaFeatureToggles featureToggles = adapter.getFeatureToggles();
    if (featureToggles.getServer42FlowRtt()) {
        generators.add(serviceRulesFactory.getServer42FlowRttTurningRuleGenerator());
        generators.add(serviceRulesFactory.getServer42FlowRttVxlanTurningRuleGenerator());
        if (switchProperties.isServer42FlowRtt()) {
            generators.add(serviceRulesFactory.getServer42FlowRttOutputVlanRuleGenerator(server42Port, server42Vlan, server42MacAddress));
            generators.add(serviceRulesFactory.getServer42FlowRttOutputVxlanRuleGenerator(server42Port, server42Vlan, server42MacAddress));
        }
    }
    if (featureToggles.getServer42IslRtt() && switchProperties.hasServer42IslRttEnabled()) {
        generators.add(serviceRulesFactory.getServer42IslRttTurningRuleGenerator());
        generators.add(serviceRulesFactory.getServer42IslRttOutputRuleGenerator(server42Port, server42Vlan, server42MacAddress));
        for (Integer islPort : adapter.getSwitchIslPorts(switchId)) {
            generators.add(serviceRulesFactory.getServer42IslRttInputRuleGenerator(server42Port, islPort));
        }
    }
    return generators;
}
Also used : Cookie(org.openkilda.model.cookie.Cookie) KildaFeatureToggles(org.openkilda.model.KildaFeatureToggles) ArrayList(java.util.ArrayList) MacAddress(org.openkilda.model.MacAddress) RuleGenerator(org.openkilda.rulemanager.factory.RuleGenerator) SwitchProperties(org.openkilda.model.SwitchProperties) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 20 with SwitchProperties

use of org.openkilda.model.SwitchProperties in project open-kilda by telstra.

the class PersistenceDataAdapter method getSwitchProperties.

@Override
public SwitchProperties getSwitchProperties(SwitchId switchId) {
    if (switchPropertiesCache == null) {
        switchPropertiesCache = switchPropertiesRepository.findBySwitchIds(switchIds);
        if (keepMultitableForFlow) {
            // Override the multitable flag with actual flow data.
            for (SwitchProperties switchProps : switchPropertiesCache.values()) {
                SwitchId swId = switchProps.getSwitchId();
                Switch sw = switchProps.getSwitchObj();
                if (!switchProps.isMultiTable() && sw.supports(SwitchFeature.MULTI_TABLE) && (!flowPathRepository.findBySegmentSwitchWithMultiTable(swId, true).isEmpty() || !flowRepository.findByEndpointSwitchWithMultiTableSupport(swId).isEmpty())) {
                    switchPropertiesRepository.detach(switchProps);
                    switchProps.setMultiTable(true);
                }
            }
        }
    }
    return switchPropertiesCache.get(switchId);
}
Also used : Switch(org.openkilda.model.Switch) SwitchId(org.openkilda.model.SwitchId) SwitchProperties(org.openkilda.model.SwitchProperties)

Aggregations

SwitchProperties (org.openkilda.model.SwitchProperties)45 Switch (org.openkilda.model.Switch)19 SwitchId (org.openkilda.model.SwitchId)19 Test (org.junit.Test)17 ArrayList (java.util.ArrayList)9 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)8 List (java.util.List)8 Set (java.util.Set)7 InMemoryGraphBasedTest (org.openkilda.persistence.inmemory.InMemoryGraphBasedTest)7 KildaFeatureToggles (org.openkilda.model.KildaFeatureToggles)6 Utils.buildSwitch (org.openkilda.rulemanager.Utils.buildSwitch)6 Utils.buildSwitchProperties (org.openkilda.rulemanager.Utils.buildSwitchProperties)6 Sets (com.google.common.collect.Sets)5 Map (java.util.Map)5 Before (org.junit.Before)5 Collections (java.util.Collections)4 Assert.assertEquals (org.junit.Assert.assertEquals)4 Assert.assertTrue (org.junit.Assert.assertTrue)4 Mockito.mock (org.mockito.Mockito.mock)4