blob: 52ee5d187694b193f854d3285993b054c4e511d6 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.openflow.drivers;
tom7ef8ff92014-09-17 13:08:06 -070017
Jonathan Hart47f2dde2015-01-14 17:45:06 -080018import java.util.ArrayList;
19import java.util.Collections;
20import java.util.List;
21import java.util.concurrent.atomic.AtomicBoolean;
22
Brian O'Connorabafb502014-12-02 22:26:20 -080023import org.onosproject.openflow.controller.Dpid;
24import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
25import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
26import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
27import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
tom7ef8ff92014-09-17 13:08:06 -070028import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
29import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
30import org.projectfloodlight.openflow.protocol.OFFactory;
31import org.projectfloodlight.openflow.protocol.OFMatchV3;
32import org.projectfloodlight.openflow.protocol.OFMessage;
33import org.projectfloodlight.openflow.protocol.OFOxmList;
34import org.projectfloodlight.openflow.protocol.action.OFAction;
35import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
36import org.projectfloodlight.openflow.types.OFBufferId;
37import org.projectfloodlight.openflow.types.OFPort;
38import org.projectfloodlight.openflow.types.TableId;
tom7ef8ff92014-09-17 13:08:06 -070039
40/**
41 * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
42 * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
43 * 2.1.0 (or whatever version + build) Serial : None
44 */
45public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
46
tom7ef8ff92014-09-17 13:08:06 -070047 private final AtomicBoolean driverHandshakeComplete;
48 private OFFactory factory;
49 private long barrierXidToWaitFor = -1;
50
51 private static final short MIN_PRIORITY = 0x0;
52 private static final int OFPCML_NO_BUFFER = 0xffff;
53
54 public OFSwitchImplOVS13(Dpid dpid, OFDescStatsReply desc) {
55 super(dpid);
56 driverHandshakeComplete = new AtomicBoolean(false);
57 setSwitchDescription(desc);
58 }
59
60 @Override
61 public String toString() {
62 return "OFSwitchImplOVS13 [" + ((channel != null)
63 ? channel.getRemoteAddress() : "?")
64 + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
65 }
66
67 @Override
68 public void startDriverHandshake() {
69 log.debug("Starting driver handshake for sw {}", getStringId());
70 if (startDriverHandshakeCalled) {
71 throw new SwitchDriverSubHandshakeAlreadyStarted();
72 }
73 startDriverHandshakeCalled = true;
74 factory = factory();
75 configureSwitch();
76 }
77
78 @Override
79 public boolean isDriverHandshakeComplete() {
80 if (!startDriverHandshakeCalled) {
81 throw new SwitchDriverSubHandshakeNotStarted();
82 }
83 return driverHandshakeComplete.get();
84 }
85
86 @Override
87 public void processDriverHandshakeMessage(OFMessage m) {
88 if (!startDriverHandshakeCalled) {
89 throw new SwitchDriverSubHandshakeNotStarted();
90 }
91 if (driverHandshakeComplete.get()) {
92 throw new SwitchDriverSubHandshakeCompleted(m);
93 }
94
95 switch (m.getType()) {
96 case BARRIER_REPLY:
97 if (m.getXid() == barrierXidToWaitFor) {
98 driverHandshakeComplete.set(true);
99 }
100 break;
101
102 case ERROR:
103 log.error("Switch {} Error {}", getStringId(), m);
104 break;
105
106 case FEATURES_REPLY:
107 break;
108 case FLOW_REMOVED:
109 break;
110 case GET_ASYNC_REPLY:
111 // OFAsyncGetReply asrep = (OFAsyncGetReply)m;
112 // decodeAsyncGetReply(asrep);
113 break;
114
115 case PACKET_IN:
116 break;
117 case PORT_STATUS:
118 break;
119 case QUEUE_GET_CONFIG_REPLY:
120 break;
121 case ROLE_REPLY:
122 break;
123
124 case STATS_REPLY:
125 // processStatsReply((OFStatsReply) m);
126 break;
127
128 default:
129 log.debug("Received message {} during switch-driver subhandshake "
130 + "from switch {} ... Ignoring message", m, getStringId());
131
132 }
133 }
134
tom7ef8ff92014-09-17 13:08:06 -0700135 private void configureSwitch() {
tom7ef8ff92014-09-17 13:08:06 -0700136 sendBarrier(true);
137 }
138
tom7ef8ff92014-09-17 13:08:06 -0700139 private void sendBarrier(boolean finalBarrier) {
140 int xid = getNextTransactionId();
141 if (finalBarrier) {
142 barrierXidToWaitFor = xid;
143 }
144 OFBarrierRequest br = factory
145 .buildBarrierRequest()
146 .setXid(xid)
147 .build();
alshabib19fdc122014-10-03 11:38:19 -0700148 write(br);
tom7ef8ff92014-09-17 13:08:06 -0700149 }
150
151 @Override
152 public Boolean supportNxRole() {
153 return false;
154 }
155
156 @Override
157 public void write(OFMessage msg) {
158 channel.write(Collections.singletonList(msg));
159
160 }
161
162 @Override
163 public void write(List<OFMessage> msgs) {
164 channel.write(msgs);
165 }
166
167 /**
168 * By default if none of the booleans in the call are set, then the
169 * table-miss entry is added with no instructions, which means that pipeline
170 * execution will stop, and the action set associated with the packet will
171 * be executed.
172 *
173 * @param tableToAdd
174 * @param toControllerNow as an APPLY_ACTION instruction
175 * @param toControllerWrite as a WRITE_ACITION instruction
176 * @param toTable as a GOTO_TABLE instruction
177 * @param tableToSend
178 */
179 @SuppressWarnings("unchecked")
180 private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
181 boolean toControllerWrite,
182 boolean toTable, int tableToSend) {
183 OFOxmList oxmList = OFOxmList.EMPTY;
184 OFMatchV3 match = factory.buildMatchV3()
185 .setOxmList(oxmList)
186 .build();
187 OFAction outc = factory.actions()
188 .buildOutput()
189 .setPort(OFPort.CONTROLLER)
190 .setMaxLen(OFPCML_NO_BUFFER)
191 .build();
192 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
193 if (toControllerNow) {
194 // table-miss instruction to send to controller immediately
195 OFInstruction instr = factory.instructions()
196 .buildApplyActions()
197 .setActions(Collections.singletonList(outc))
198 .build();
199 instructions.add(instr);
200 }
201
202 if (toControllerWrite) {
203 // table-miss instruction to write-action to send to controller
204 // this will be executed whenever the action-set gets executed
205 OFInstruction instr = factory.instructions()
206 .buildWriteActions()
207 .setActions(Collections.singletonList(outc))
208 .build();
209 instructions.add(instr);
210 }
211
212 if (toTable) {
213 // table-miss instruction to goto-table x
214 OFInstruction instr = factory.instructions()
215 .gotoTable(TableId.of(tableToSend));
216 instructions.add(instr);
217 }
218
219 if (!toControllerNow && !toControllerWrite && !toTable) {
220 // table-miss has no instruction - at which point action-set will be
221 // executed - if there is an action to output/group in the action
222 // set
223 // the packet will be sent there, otherwise it will be dropped.
224 instructions = Collections.EMPTY_LIST;
225 }
226
227 OFMessage tableMissEntry = factory.buildFlowAdd()
228 .setTableId(TableId.of(tableToAdd))
229 .setMatch(match) // match everything
230 .setInstructions(instructions)
231 .setPriority(MIN_PRIORITY)
232 .setBufferId(OFBufferId.NO_BUFFER)
233 .setIdleTimeout(0)
234 .setHardTimeout(0)
235 .setXid(getNextTransactionId())
236 .build();
alshabib19fdc122014-10-03 11:38:19 -0700237 write(tableMissEntry);
tom7ef8ff92014-09-17 13:08:06 -0700238 }
239
Saurav Dasfa2fa932015-03-03 11:29:48 -0800240 @Override
241 public TableType getTableType(TableId tid) {
242 return TableType.NONE;
243 }
244
245 @Override
246 public void transformAndSendMsg(OFMessage msg, TableType tableType) {
247 // TODO Auto-generated method stub
248
249 }
250
tom7ef8ff92014-09-17 13:08:06 -0700251}