Search in sources :

Example 51 with FlowEndpoint

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

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = context.getTargetFlow();
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow create feature is disabled");
    }
    try {
        yFlowValidator.validate(targetFlow);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    String yFlowId = targetFlow.getYFlowId();
    YFlow yFlow = transactionManager.doInTransaction(() -> {
        YFlow result = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        if (result.getStatus() == FlowStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Y-flow %s is in progress now", yFlowId));
        }
        // Keep it, just in case we have to revert it.
        stateMachine.setOriginalYFlowStatus(result.getStatus());
        result.setStatus(FlowStatus.IN_PROGRESS);
        return result;
    });
    Set<String> requestedSubFlowIds = targetFlow.getSubFlows().stream().map(SubFlowDto::getFlowId).collect(Collectors.toSet());
    Set<String> originalSubFlowIds = yFlow.getSubFlows().stream().map(YSubFlow::getSubFlowId).collect(Collectors.toSet());
    if (!requestedSubFlowIds.equals(originalSubFlowIds)) {
        throw new FlowProcessingException(ErrorType.PARAMETERS_INVALID, format("Unable to map provided sub-flows set onto existing y-flow %s", yFlowId));
    }
    YSubFlow subFlow = yFlow.getSubFlows().stream().findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("No sub-flows of the y-flow %s were found", yFlowId)));
    stateMachine.setMainAffinityFlowId(subFlow.getFlow().getAffinityGroupId());
    List<FlowEndpoint> subFlowEndpoints = targetFlow.getSubFlows().stream().map(SubFlowDto::getEndpoint).collect(Collectors.toList());
    dashboardLogger.onYFlowUpdate(yFlowId, targetFlow.getSharedEndpoint(), subFlowEndpoints, targetFlow.getMaximumBandwidth());
    stateMachine.setTargetFlow(targetFlow);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.UPDATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) YFlow(org.openkilda.model.YFlow) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) YSubFlow(org.openkilda.model.YSubFlow)

Example 52 with FlowEndpoint

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

the class IngressFlowModFactory method makeOuterOnlyVlanForwardMessage.

/**
 * Make rule to match traffic by port+vlan and route it into ISL/egress end.
 */
public OFFlowMod makeOuterOnlyVlanForwardMessage(EffectiveIds effectiveIds) {
    FlowEndpoint endpoint = command.getEndpoint();
    OFFlowMod.Builder builder = flowModBuilderFactory.makeBuilder(of, TableId.of(SwitchManager.INGRESS_TABLE_ID)).setMatch(OfAdapter.INSTANCE.matchVlanId(of, of.buildMatch(), endpoint.getOuterVlanId()).setExact(MatchField.IN_PORT, OFPort.of(endpoint.getPortNumber())).build());
    return makeForwardMessage(builder, effectiveIds, FlowEndpoint.makeVlanStack(endpoint.getOuterVlanId()));
}
Also used : FlowEndpoint(org.openkilda.model.FlowEndpoint) Builder(org.projectfloodlight.openflow.protocol.OFFlowMod.Builder) OFFlowMod(org.projectfloodlight.openflow.protocol.OFFlowMod)

Example 53 with FlowEndpoint

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

the class IngressFlowModFactory method makeSingleVlanFlowLoopMessage.

/**
 * Make ingress flow loop rule to match all flow traffic by port&vlan and route it back to port from
 * where it came.
 */
public OFFlowMod makeSingleVlanFlowLoopMessage() {
    FlowEndpoint endpoint = command.getEndpoint();
    RoutingMetadata metadata = RoutingMetadata.builder().outerVlanId(endpoint.getOuterVlanId()).build(switchFeatures);
    return flowModBuilderFactory.makeBuilder(of, TableId.of(SwitchManager.INGRESS_TABLE_ID)).setMatch(of.buildMatch().setExact(MatchField.IN_PORT, OFPort.of(endpoint.getPortNumber())).setMasked(MatchField.METADATA, OFMetadata.of(metadata.getValue()), OFMetadata.of(metadata.getMask())).build()).setCookie(U64.of(command.getCookie().getValue())).setInstructions(makeIngressFlowLoopInstructions(endpoint)).build();
}
Also used : FlowEndpoint(org.openkilda.model.FlowEndpoint) RoutingMetadata(org.openkilda.floodlight.utils.metadata.RoutingMetadata)

Example 54 with FlowEndpoint

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

the class IngressFlowModFactory method makeSingleVlanForwardMessage.

/**
 * Make rule to forward traffic matched by outer VLAN tag and forward in in ISL (or out port in case one-switch
 * flow).
 */
public OFFlowMod makeSingleVlanForwardMessage(EffectiveIds effectiveIds) {
    FlowEndpoint endpoint = command.getEndpoint();
    RoutingMetadata metadata = RoutingMetadata.builder().outerVlanId(endpoint.getOuterVlanId()).build(switchFeatures);
    OFFlowMod.Builder builder = flowModBuilderFactory.makeBuilder(of, TableId.of(SwitchManager.INGRESS_TABLE_ID)).setMatch(of.buildMatch().setExact(MatchField.IN_PORT, OFPort.of(endpoint.getPortNumber())).setMasked(MatchField.METADATA, OFMetadata.of(metadata.getValue()), OFMetadata.of(metadata.getMask())).build());
    // list as current vlanStack
    return makeForwardMessage(builder, effectiveIds, Collections.emptyList());
}
Also used : FlowEndpoint(org.openkilda.model.FlowEndpoint) RoutingMetadata(org.openkilda.floodlight.utils.metadata.RoutingMetadata) Builder(org.projectfloodlight.openflow.protocol.OFFlowMod.Builder) OFFlowMod(org.projectfloodlight.openflow.protocol.OFFlowMod)

Example 55 with FlowEndpoint

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

the class IngressFlowModFactory method makeOuterVlanMatchSharedMessage.

/**
 * Make rule to match traffic by port and vlan, write vlan into metadata and pass packet into "next" table. This
 * rule is shared across all flow with equal port and vlan(outer).
 */
public OFFlowMod makeOuterVlanMatchSharedMessage() {
    FlowEndpoint endpoint = command.getEndpoint();
    FlowSharedSegmentCookie cookie = FlowSharedSegmentCookie.builder(SharedSegmentType.QINQ_OUTER_VLAN).portNumber(endpoint.getPortNumber()).vlanId(endpoint.getOuterVlanId()).build();
    return flowModBuilderFactory.makeBuilder(of, TableId.of(SwitchManager.PRE_INGRESS_TABLE_ID)).setCookie(U64.of(cookie.getValue())).setMatch(of.buildMatch().setExact(MatchField.IN_PORT, OFPort.of(endpoint.getPortNumber())).setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlan(endpoint.getOuterVlanId())).build()).setInstructions(makeOuterVlanMatchInstructions()).build();
}
Also used : FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowSharedSegmentCookie(org.openkilda.model.cookie.FlowSharedSegmentCookie)

Aggregations

FlowEndpoint (org.openkilda.model.FlowEndpoint)105 Test (org.junit.Test)26 Flow (org.openkilda.model.Flow)22 ArrayList (java.util.ArrayList)15 RoutingMetadata (org.openkilda.floodlight.utils.metadata.RoutingMetadata)12 YFlow (org.openkilda.model.YFlow)11 FlowPath (org.openkilda.model.FlowPath)10 FlowSpeakerData (org.openkilda.rulemanager.FlowSpeakerData)9 SpeakerData (org.openkilda.rulemanager.SpeakerData)9 SwitchId (org.openkilda.model.SwitchId)8 YSubFlow (org.openkilda.model.YSubFlow)8 HashSet (java.util.HashSet)7 FlowSideAdapter (org.openkilda.adapter.FlowSideAdapter)7 FlowSourceAdapter (org.openkilda.adapter.FlowSourceAdapter)7 IngressFlowSegmentInstallCommand (org.openkilda.floodlight.command.flow.ingress.IngressFlowSegmentInstallCommand)7 EffectiveIds (org.openkilda.floodlight.model.EffectiveIds)7 FlowSegmentWrapperCommand (org.openkilda.floodlight.command.flow.FlowSegmentWrapperCommand)6 FlowProcessingException (org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)6 OFFlowAdd (org.projectfloodlight.openflow.protocol.OFFlowAdd)6 MessageContext (org.openkilda.messaging.MessageContext)5