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();
}
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()));
}
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();
}
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());
}
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();
}
Aggregations