package org.opennaas.extensions.openflowswitch.driver.opendaylight.actionssets.actions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.opendaylight.actionssets.OpenDaylightAction; import org.opennaas.extensions.openflowswitch.driver.opendaylight.actionssets.OpenDaylightConstants; import org.opennaas.extensions.openflowswitch.driver.opendaylight.protocol.client.IOpenDaylightStaticFlowPusherClient; import org.opennaas.extensions.openflowswitch.model.FloodlightOFAction; import org.opennaas.extensions.openflowswitch.model.OpenDaylightOFFlow; import org.opennaas.extensions.openflowswitch.model.OpenflowSwitchModel; /** * * @author Josep Batallé (i2CAT) * */ public class CreateOFForwardingAction extends OpenDaylightAction { private static final String FORWARDING_ACTION = "OUTPUT";//OpenDaylight requires capital letters Log log = LogFactory.getLog(CreateOFForwardingAction.class); @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(); OpenDaylightOFFlow flow = (OpenDaylightOFFlow) params; String DPID = getSwitchIdInModel(); String name = flow.getName(); log.info("Creating forwarding action. Flow: " + name + " Switch ID: " + DPID); flow = updateFlowWithControllerRequiredValues(flow); IOpenDaylightStaticFlowPusherClient client = getOpenDaylightProtocolSession(protocolSessionManager).getOpenDaylightClientForUse(); client.addFlow(flow, DPID, name); } catch (Exception e) { //probably the flow is not defined correctly throw new ActionException(e); } return ActionResponse.okResponse(OpenflowForwardingActionSet.CREATEOFFORWARDINGRULE); } private OpenDaylightOFFlow updateFlowWithControllerRequiredValues(OpenDaylightOFFlow flow) { if (flow.getPriority() == null || flow.getPriority().isEmpty()) { flow.setPriority(OpenDaylightConstants.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 OpenDaylightOFFlow)) { throw new ActionException("Invalid parameters for action " + this.actionID); } OpenDaylightOFFlow flowRule = (OpenDaylightOFFlow) 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(OpenDaylightConstants.MAX_PRIORITY); int min = Integer.parseInt(OpenDaylightConstants.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(); OpenDaylightOFFlow flowRule = (OpenDaylightOFFlow) params; flowRule.setSwitchId(model.getSwitchId()); } private void setSwitchIdInModel(IProtocolSessionManager protocolSessionManager) throws ProtocolException { OpenflowSwitchModel model = (OpenflowSwitchModel) getModelToUpdate(); model.setSwitchId(getSwitchIdFromSession(protocolSessionManager)); } private String getSwitchIdInModel() { OpenflowSwitchModel model = (OpenflowSwitchModel) getModelToUpdate(); return model.getSwitchId(); } }