package org.opennaas.extensions.openflowswitch.driver.floodlight.actionssets.actions;
import org.opennaas.core.resources.action.ActionException;
import org.opennaas.core.resources.action.ActionResponse;
import org.opennaas.core.resources.protocol.IProtocolSessionManager;
import org.opennaas.core.resources.protocol.ProtocolException;
import org.opennaas.extensions.openflowswitch.capability.OpenflowForwardingActionSet;
import org.opennaas.extensions.openflowswitch.driver.floodlight.actionssets.FloodlightAction;
import org.opennaas.extensions.openflowswitch.driver.floodlight.actionssets.FloodlightConstants;
import org.opennaas.extensions.openflowswitch.driver.floodlight.protocol.client.IFloodlightStaticFlowPusherClient;
import org.opennaas.extensions.openflowswitch.model.FloodlightOFAction;
import org.opennaas.extensions.openflowswitch.model.FloodlightOFFlow;
import org.opennaas.extensions.openflowswitch.model.OpenflowSwitchModel;
/**
*
* @author Adrian Rosello (i2CAT)
*
*/
public class CreateOFForwardingAction extends FloodlightAction {
private static final String FORWARDING_ACTION = "output";
@Override
public ActionResponse execute(IProtocolSessionManager protocolSessionManager) throws ActionException {
try {
// TODO we have to find another place where we could put switchId in model.
setSwitchIdInModel(protocolSessionManager);
setSwitchIdToFlow();
FloodlightOFFlow flow = (FloodlightOFFlow) params;
flow = updateFlowWithControllerRequiredValues(flow);
IFloodlightStaticFlowPusherClient client = getFloodlightProtocolSession(protocolSessionManager).getFloodlightClientForUse();
client.addFlow(flow);
} catch (Exception e) {
throw new ActionException(e);
}
return ActionResponse.okResponse(OpenflowForwardingActionSet.CREATEOFFORWARDINGRULE);
}
private FloodlightOFFlow updateFlowWithControllerRequiredValues(FloodlightOFFlow flow) {
if (flow.getPriority() == null || flow.getPriority().isEmpty()) {
flow.setPriority(FloodlightConstants.DEFAULT_PRIORITY);
}
if (flow.getMatch() != null) {
// if (flow.getMatch().getSrcIp() != null || flow.getMatch().getDstIp() != null || flow.getMatch().getTosBits() != null) {
if ((!flow.getMatch().getEtherType().equals("2054")) && (flow.getMatch().getSrcIp() != null || flow.getMatch().getDstIp() != null || flow.getMatch().getTosBits() != null)) {
// To avoid following message in floodlight controller:
// Warning! Pushing a static flow entry that matches IP fields without matching for IP payload (ether-type 2048)
// will cause the switch to wildcard higher level fields.
flow.getMatch().setEtherType("2048");
}
}
return flow;
}
@Override
public boolean checkParams(Object params) throws ActionException {
if (params == null || !(params instanceof FloodlightOFFlow))
throw new ActionException("Invalid parameters for action " + this.actionID);
FloodlightOFFlow flowRule = (FloodlightOFFlow) params;
if (flowRule.getName() == null || flowRule.getName().isEmpty())
throw new ActionException("No flow id given to params in action " + this.actionID);
for (FloodlightOFAction action : flowRule.getActions()) {
if (action.getType() == null || action.getType().isEmpty())
throw new ActionException("No OFAction type given to params in action " + this.actionID);
if (action.getValue() == null || action.getValue().isEmpty())
throw new ActionException("No OFAction value given to params in action " + this.actionID);
if (!(action.getType().equals(FORWARDING_ACTION)))
throw new ActionException(
"Wrong action type given to params in " + this.actionID + ". Expected was \"" + FORWARDING_ACTION + "\", but \"" + action
.getType() + "\" was given.");
}
// if flowRule has priority
if (flowRule.getPriority() != null && !flowRule.getPriority().isEmpty()) {
// check priority is a number
int priority;
try {
priority = Integer.parseInt(flowRule.getPriority());
} catch (NumberFormatException e) {
throw new ActionException("Invalid priority in action " + this.actionID, e);
}
// check priority is in valid range
int max = Integer.parseInt(FloodlightConstants.MAX_PRIORITY);
int min = Integer.parseInt(FloodlightConstants.MIN_PRIORITY);
if (priority > max || priority < min) {
throw new ActionException("Invalid priority in action " + this.actionID + ". Valid range is [" + min + "," + max + "]");
}
}
return true;
}
private void setSwitchIdToFlow() {
OpenflowSwitchModel model = (OpenflowSwitchModel) getModelToUpdate();
FloodlightOFFlow flowRule = (FloodlightOFFlow) params;
flowRule.setSwitchId(model.getSwitchId());
}
private void setSwitchIdInModel(IProtocolSessionManager protocolSessionManager) throws ProtocolException {
OpenflowSwitchModel model = (OpenflowSwitchModel) getModelToUpdate();
model.setSwitchId(getSwitchIdFromSession(protocolSessionManager));
}
}