import org.opendaylight.controller.forwardingrulesmanager.implementation.data.FlowEntryDistributionOrder;
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.ActionType;
+import org.opendaylight.controller.sal.action.Enqueue;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
import org.opendaylight.controller.sal.action.Output;
import org.opendaylight.controller.sal.connection.ConnectionLocality;
import org.opendaylight.controller.sal.core.Config;
return null;
}
+ /**
+ * Checks if the FlowEntry targets are valid for this container
+ *
+ * @param flowEntry
+ * The flow entry to test
+ * @return a Status object representing the result of the validation
+ */
+ private Status validateEntry(FlowEntry flowEntry) {
+ // Node presence check
+ Node node = flowEntry.getNode();
+ if (!switchManager.getNodes().contains(node)) {
+ return new Status(StatusCode.BADREQUEST, String.format("Node %s is not present in this container", node));
+ }
+
+ // Ports and actions validation check
+ Flow flow = flowEntry.getFlow();
+ Match match = flow.getMatch();
+ if (match.isPresent(MatchType.IN_PORT)) {
+ NodeConnector inputPort = (NodeConnector)match.getField(MatchType.IN_PORT).getValue();
+ if (!switchManager.getNodeConnectors(node).contains(inputPort)) {
+ String msg = String.format("Ingress port %s is not present on this container", inputPort);
+ return new Status(StatusCode.BADREQUEST, msg);
+ }
+ }
+ for (Action action : flow.getActions()) {
+ if (action instanceof Flood && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) {
+ return new Status(StatusCode.BADREQUEST, String.format("Flood is only allowed in default container"));
+ }
+ if (action instanceof FloodAll && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) {
+ return new Status(StatusCode.BADREQUEST, String.format("FloodAll is only allowed in default container"));
+ }
+ if (action instanceof Output) {
+ Output out = (Output)action;
+ NodeConnector outputPort = out.getPort();
+ if (!switchManager.getNodeConnectors(node).contains(outputPort)) {
+ String msg = String.format("Output port %s is not present on this container", outputPort);
+ return new Status(StatusCode.BADREQUEST, msg);
+ }
+ }
+ if (action instanceof Enqueue) {
+ Enqueue out = (Enqueue)action;
+ NodeConnector outputPort = out.getPort();
+ if (!switchManager.getNodeConnectors(node).contains(outputPort)) {
+ String msg = String.format("Enqueue port %s is not present on this container", outputPort);
+ return new Status(StatusCode.BADREQUEST, msg);
+ }
+ }
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
+
/**
* Adds a flow entry onto the network node It runs various validity checks
* and derive the final container flows merged entries that will be
return new Status(StatusCode.NOTACCEPTABLE, INVALID_FLOW_ENTRY);
}
+ // Operational check: input, output and queue ports presence check and
+ // action validation for this container
+ Status status = validateEntry(flowEntry);
+ if (!status.isSuccess()) {
+ String msg = String.format("%s: %s", INVALID_FLOW_ENTRY, status.getDescription());
+ log.warn("{}: {}", msg, flowEntry);
+ return new Status(StatusCode.NOTACCEPTABLE, msg);
+ }
+
/*
* Redundant Check: Check if the request is a redundant one from the
* same application the flowEntry is equal to an existing one. Given we
return new Status(StatusCode.SUCCESS, msg);
}
+ // Operational check: input, output and queue ports presence check and
+ // action validation for this container
+ Status status = validateEntry(newFlowEntry);
+ if (!status.isSuccess()) {
+ String msg = String.format("Modify: %s: %s", INVALID_FLOW_ENTRY, status.getDescription());
+ log.warn("{}: {}", msg, newFlowEntry);
+ return new Status(StatusCode.NOTACCEPTABLE, msg);
+ }
+
/*
* Conflict Check: Verify the new entry would not conflict with an
* existing one. This is a loose check on the previous original flow
@Override
public Status addStaticFlow(FlowConfig config) {
// Configuration object validation
- Status status = config.validate(container);
+ Status status = config.validate();
if (!status.isSuccess()) {
log.warn("Invalid Configuration for flow {}. The failure is {}", config, status.getDescription());
String error = "Invalid Configuration (" + status.getDescription() + ")";
config.setStatus(StatusCode.SUCCESS.toString());
break;
default:
+ break;
}
}
}
}
// Validity Check
- Status status = newFlowConfig.validate(container);
+ Status status = newFlowConfig.validate();
if (!status.isSuccess()) {
String msg = "Invalid Configuration (" + status.getDescription() + ")";
newFlowConfig.setStatus(msg);
}
}
if (target != null) {
- Status status = target.validate(container);
+ Status status = target.validate();
if (!status.isSuccess()) {
log.warn(status.getDescription());
return status;
this.reinstallAllFlowEntries();
break;
default:
+ break;
}
// Update our configuration DB