3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.protocol_plugin.openflow.internal;
12 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
13 import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
14 import org.openflow.protocol.OFError;
15 import org.openflow.protocol.OFFlowMod;
16 import org.openflow.protocol.OFMessage;
17 import org.openflow.protocol.OFPort;
19 import org.opendaylight.controller.sal.core.Node;
20 import org.opendaylight.controller.sal.core.Node.NodeIDType;
21 import org.opendaylight.controller.sal.flowprogrammer.Flow;
22 import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
23 import org.opendaylight.controller.sal.utils.StatusCode;
24 import org.opendaylight.controller.sal.utils.Status;
27 * Represents the openflow plugin component in charge of programming the flows
28 * on the switch. It servers the install requests coming from the SAL layer.
33 public class FlowProgrammerService implements IPluginInFlowProgrammerService {
34 private IController controller;
36 public FlowProgrammerService() {
40 public void setController(IController core) {
41 this.controller = core;
44 public void unsetController(IController core) {
45 if (this.controller == core) {
46 this.controller = null;
51 * Function called by the dependency manager when all the required
52 * dependencies are satisfied
59 * Function called by the dependency manager when at least one
60 * dependency become unsatisfied or when the component is shutting
61 * down because for example bundle is being stopped.
68 * Function called by dependency manager after "init ()" is called
69 * and after the services provided by the class are registered in
70 * the service registry
77 * Function called by the dependency manager before the services
78 * exported by the component are unregistered, this will be
79 * followed by a "destroy ()" calls
86 public Status addFlow(Node node, Flow flow) {
87 String action = "add";
88 if (!node.getType().equals(NodeIDType.OPENFLOW)) {
89 return new Status(StatusCode.NOTACCEPTABLE,
90 errorString("send", action, "Invalid node type"));
93 if (controller != null) {
94 ISwitch sw = controller.getSwitch((Long) node.getID());
96 FlowConverter x = new FlowConverter(flow);
97 OFMessage msg = x.getOFFlowMod(OFFlowMod.OFPFC_ADD, null);
100 * Synchronous message send
102 Object result = sw.syncSend(msg);
103 if (result instanceof Boolean) {
104 return ((Boolean) result == Boolean.TRUE) ?
105 new Status(StatusCode.SUCCESS, null)
106 : new Status(StatusCode.TIMEOUT,
107 errorString(null, action,
108 "Request Timed Out"));
109 } else if (result instanceof OFError) {
110 return new Status(StatusCode.INTERNALERROR,
111 errorString("program", action, Utils
112 .getOFErrorString((OFError) result)));
114 return new Status(StatusCode.INTERNALERROR,
115 errorString("send", action, "Internal Error"));
118 return new Status(StatusCode.GONE, errorString("send", action,
119 "Switch is not available"));
122 return new Status(StatusCode.INTERNALERROR,
123 errorString("send", action, "Internal plugin error"));
127 public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
128 String action = "modify";
129 if (!node.getType().equals(NodeIDType.OPENFLOW)) {
130 return new Status(StatusCode.NOTACCEPTABLE,
131 errorString("send", action, "Invalid node type"));
133 if (controller != null) {
134 ISwitch sw = controller.getSwitch((Long) node.getID());
136 OFMessage msg1 = null, msg2 = null;
138 // If priority and match portion are the same, send a modification message
139 if (oldFlow.getPriority() != newFlow.getPriority()
140 || !oldFlow.getMatch().equals(newFlow.getMatch())) {
141 msg1 = new FlowConverter(oldFlow).getOFFlowMod(
142 OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE);
143 msg2 = new FlowConverter(newFlow).getOFFlowMod(
144 OFFlowMod.OFPFC_ADD, null);
146 msg1 = new FlowConverter(newFlow).getOFFlowMod(
147 OFFlowMod.OFPFC_MODIFY_STRICT, null);
150 * Synchronous message send
152 action = (msg2 == null) ? "modify" : "delete";
153 Object result = sw.syncSend(msg1);
154 if (result instanceof Boolean) {
155 if ((Boolean) result == Boolean.FALSE) {
156 return new Status(StatusCode.TIMEOUT,
157 errorString(null, action,
158 "Request Timed Out"));
159 } else if (msg2 == null) {
160 return new Status(StatusCode.SUCCESS, null);
162 } else if (result instanceof OFError) {
163 return new Status(StatusCode.INTERNALERROR,
164 errorString("program", action, Utils
165 .getOFErrorString((OFError) result)));
167 return new Status(StatusCode.INTERNALERROR,
168 errorString("send", action, "Internal Error"));
173 result = sw.syncSend(msg2);
174 if (result instanceof Boolean) {
175 return ((Boolean) result == Boolean.TRUE) ?
176 new Status(StatusCode.SUCCESS, null)
177 : new Status(StatusCode.TIMEOUT,
178 errorString(null, action,
179 "Request Timed Out"));
180 } else if (result instanceof OFError) {
181 return new Status(StatusCode.INTERNALERROR,
182 errorString("program", action, Utils
183 .getOFErrorString((OFError) result)));
185 return new Status(StatusCode.INTERNALERROR,
186 errorString("send", action, "Internal Error"));
190 return new Status(StatusCode.GONE, errorString("send", action,
191 "Switch is not available"));
194 return new Status(StatusCode.INTERNALERROR,
195 errorString("send", action, "Internal plugin error"));
199 public Status removeFlow(Node node, Flow flow) {
200 String action = "remove";
201 if (!node.getType().equals(NodeIDType.OPENFLOW)) {
202 return new Status(StatusCode.NOTACCEPTABLE,
203 errorString("send", action, "Invalid node type"));
205 if (controller != null) {
206 ISwitch sw = controller.getSwitch((Long) node.getID());
208 OFMessage msg = new FlowConverter(flow).getOFFlowMod(
209 OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE);
210 Object result = sw.syncSend(msg);
211 if (result instanceof Boolean) {
212 return ((Boolean) result == Boolean.TRUE) ?
213 new Status(StatusCode.SUCCESS, null)
214 : new Status(StatusCode.TIMEOUT,
215 errorString(null, action,
216 "Request Timed Out"));
217 } else if (result instanceof OFError) {
218 return new Status(StatusCode.INTERNALERROR,
219 errorString("program", action, Utils
220 .getOFErrorString((OFError) result)));
222 return new Status(StatusCode.INTERNALERROR,
223 errorString("send", action, "Internal Error"));
226 return new Status(StatusCode.GONE, errorString("send", action,
227 "Switch is not available"));
230 return new Status(StatusCode.INTERNALERROR,
231 errorString("send", action, "Internal plugin error"));
235 public Status removeAllFlows(Node node) {
236 return new Status(StatusCode.SUCCESS, null);
239 private String errorString(String phase, String action, String cause) {
241 + ((phase != null) ? phase + " the " + action
242 + " flow message: " : action + " the flow: ") + cause;