X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FFlowProgrammerService.java;fp=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FFlowProgrammerService.java;h=b30b5c76c10470655f94a30827fe8bebca49638b;hb=29f7cfb54b580928c7feac63abce028a7014b0d5;hp=0000000000000000000000000000000000000000;hpb=42210c03b0a4c54706320ba9f55794c0abd4d201;p=controller.git diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java new file mode 100644 index 0000000000..b30b5c76c1 --- /dev/null +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java @@ -0,0 +1,245 @@ + +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.protocol_plugin.openflow.internal; + +import org.opendaylight.controller.protocol_plugin.openflow.core.IController; +import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; +import org.openflow.protocol.OFError; +import org.openflow.protocol.OFFlowMod; +import org.openflow.protocol.OFMessage; +import org.openflow.protocol.OFPort; + +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.core.Node.NodeIDType; +import org.opendaylight.controller.sal.flowprogrammer.Flow; +import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService; +import org.opendaylight.controller.sal.utils.StatusCode; +import org.opendaylight.controller.sal.utils.Status; + +/** + * Represents the openflow plugin component in charge of programming the flows + * on the switch. It servers the install requests coming from the SAL layer. + * + * + * + */ +public class FlowProgrammerService implements IPluginInFlowProgrammerService { + private IController controller; + + public FlowProgrammerService() { + controller = null; + } + + public void setController(IController core) { + this.controller = core; + } + + public void unsetController(IController core) { + if (this.controller == core) { + this.controller = null; + } + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + * + */ + void init() { + } + + /** + * Function called by the dependency manager when at least one + * dependency become unsatisfied or when the component is shutting + * down because for example bundle is being stopped. + * + */ + void destroy() { + } + + /** + * Function called by dependency manager after "init ()" is called + * and after the services provided by the class are registered in + * the service registry + * + */ + void start() { + } + + /** + * Function called by the dependency manager before the services + * exported by the component are unregistered, this will be + * followed by a "destroy ()" calls + * + */ + void stop() { + } + + @Override + public Status addFlow(Node node, Flow flow) { + String action = "add"; + if (!node.getType().equals(NodeIDType.OPENFLOW)) { + return new Status(StatusCode.NOTACCEPTABLE, + errorString("send", action, "Invalid node type")); + } + + if (controller != null) { + ISwitch sw = controller.getSwitch((Long) node.getID()); + if (sw != null) { + FlowConverter x = new FlowConverter(flow); + OFMessage msg = x.getOFFlowMod(OFFlowMod.OFPFC_ADD, null); + + /* + * Synchronous message send + */ + Object result = sw.syncSend(msg); + if (result instanceof Boolean) { + return ((Boolean) result == Boolean.TRUE) ? + new Status(StatusCode.SUCCESS, null) + : new Status(StatusCode.TIMEOUT, + errorString(null, action, + "Request Timed Out")); + } else if (result instanceof OFError) { + return new Status(StatusCode.INTERNALERROR, + errorString("program", action, Utils + .getOFErrorString((OFError) result))); + } else { + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal Error")); + } + } else { + return new Status(StatusCode.GONE, errorString("send", action, + "Switch is not available")); + } + } + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal plugin error")); + } + + @Override + public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) { + String action = "modify"; + if (!node.getType().equals(NodeIDType.OPENFLOW)) { + return new Status(StatusCode.NOTACCEPTABLE, + errorString("send", action, "Invalid node type")); + } + if (controller != null) { + ISwitch sw = controller.getSwitch((Long) node.getID()); + if (sw != null) { + OFMessage msg1 = null, msg2 = null; + + // If priority and match portion are the same, send a modification message + if (oldFlow.getPriority() != newFlow.getPriority() + || !oldFlow.getMatch().equals(newFlow.getMatch())) { + msg1 = new FlowConverter(oldFlow).getOFFlowMod( + OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE); + msg2 = new FlowConverter(newFlow).getOFFlowMod( + OFFlowMod.OFPFC_ADD, null); + } else { + msg1 = new FlowConverter(newFlow).getOFFlowMod( + OFFlowMod.OFPFC_MODIFY_STRICT, null); + } + /* + * Synchronous message send + */ + action = (msg2 == null) ? "modify" : "delete"; + Object result = sw.syncSend(msg1); + if (result instanceof Boolean) { + if ((Boolean) result == Boolean.FALSE) { + return new Status(StatusCode.TIMEOUT, + errorString(null, action, + "Request Timed Out")); + } else if (msg2 == null) { + return new Status(StatusCode.SUCCESS, null); + } + } else if (result instanceof OFError) { + return new Status(StatusCode.INTERNALERROR, + errorString("program", action, Utils + .getOFErrorString((OFError) result))); + } else { + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal Error")); + } + + if (msg2 != null) { + action = "add"; + result = sw.syncSend(msg2); + if (result instanceof Boolean) { + return ((Boolean) result == Boolean.TRUE) ? + new Status(StatusCode.SUCCESS, null) + : new Status(StatusCode.TIMEOUT, + errorString(null, action, + "Request Timed Out")); + } else if (result instanceof OFError) { + return new Status(StatusCode.INTERNALERROR, + errorString("program", action, Utils + .getOFErrorString((OFError) result))); + } else { + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal Error")); + } + } + } else { + return new Status(StatusCode.GONE, errorString("send", action, + "Switch is not available")); + } + } + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal plugin error")); + } + + @Override + public Status removeFlow(Node node, Flow flow) { + String action = "remove"; + if (!node.getType().equals(NodeIDType.OPENFLOW)) { + return new Status(StatusCode.NOTACCEPTABLE, + errorString("send", action, "Invalid node type")); + } + if (controller != null) { + ISwitch sw = controller.getSwitch((Long) node.getID()); + if (sw != null) { + OFMessage msg = new FlowConverter(flow).getOFFlowMod( + OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE); + Object result = sw.syncSend(msg); + if (result instanceof Boolean) { + return ((Boolean) result == Boolean.TRUE) ? + new Status(StatusCode.SUCCESS, null) + : new Status(StatusCode.TIMEOUT, + errorString(null, action, + "Request Timed Out")); + } else if (result instanceof OFError) { + return new Status(StatusCode.INTERNALERROR, + errorString("program", action, Utils + .getOFErrorString((OFError) result))); + } else { + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal Error")); + } + } else { + return new Status(StatusCode.GONE, errorString("send", action, + "Switch is not available")); + } + } + return new Status(StatusCode.INTERNALERROR, + errorString("send", action, "Internal plugin error")); + } + + @Override + public Status removeAllFlows(Node node) { + return new Status(StatusCode.SUCCESS, null); + } + + private String errorString(String phase, String action, String cause) { + return "Failed to " + + ((phase != null) ? phase + " the " + action + + " flow message: " : action + " the flow: ") + cause; + } + +}