blob: c8ff917a63192e835258b8aca0d02974cc476242 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
18package net.floodlightcontroller.core.web;
19
Srikanth Vavilapallib7258512014-09-29 13:24:11 -070020import java.util.ArrayList;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070021import java.util.List;
22import java.util.concurrent.Future;
23import java.util.concurrent.TimeUnit;
24
25import net.floodlightcontroller.core.IFloodlightProviderService;
26import net.floodlightcontroller.core.IOFSwitch;
27import net.floodlightcontroller.core.annotations.LogMessageDoc;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -070028import net.onrc.onos.core.drivermanager.OFSwitchImplSpringOpenTTP;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070029
30import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
Fahad Naeem Khand89448d2014-10-06 18:40:45 -070031import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -070032import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070033import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry;
34import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
Fahad Naeem Khan8a8daf22014-10-06 14:07:43 -070035import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry;
36import org.projectfloodlight.openflow.protocol.OFGroupStatsReply;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070037import org.projectfloodlight.openflow.protocol.OFMatchV3;
38import org.projectfloodlight.openflow.protocol.OFOxmList;
Srikanth Vavilapallib7258512014-09-29 13:24:11 -070039import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
40import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070041import org.projectfloodlight.openflow.protocol.OFStatsReply;
42import org.projectfloodlight.openflow.protocol.OFStatsRequest;
43import org.projectfloodlight.openflow.protocol.OFStatsType;
Fahad Naeem Khan074892b2014-11-03 14:56:36 -080044import org.projectfloodlight.openflow.types.OFGroup;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070045import org.projectfloodlight.openflow.types.OFPort;
46import org.projectfloodlight.openflow.types.TableId;
47import org.projectfloodlight.openflow.util.HexString;
48import org.restlet.resource.ResourceException;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080049import org.restlet.resource.ServerResource;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070050import org.slf4j.Logger;
51import org.slf4j.LoggerFactory;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080052
53/**
54 * Base class for server resources related to switches
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070055 *
Ray Milkey269ffb92014-04-03 14:43:30 -070056 * @author readams
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080057 */
Ray Milkeyff735142014-05-22 19:06:02 -070058
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080059public class SwitchResourceBase extends ServerResource {
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070060 protected final static Logger log = LoggerFactory.getLogger(SwitchResourceBase.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070061
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080062 public enum REQUESTTYPE {
63 OFSTATS,
64 OFFEATURES
65 }
Ray Milkey269ffb92014-04-03 14:43:30 -070066
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080067 @Override
68 protected void doInit() throws ResourceException {
69 super.doInit();
Ray Milkey269ffb92014-04-03 14:43:30 -070070
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080071 }
Ray Milkey269ffb92014-04-03 14:43:30 -070072
73 @LogMessageDoc(level = "ERROR",
74 message = "Failure retrieving statistics from switch {switch}",
75 explanation = "An error occurred while retrieving statistics" +
76 "from the switch",
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070077 recommendation = LogMessageDoc.CHECK_SWITCH + " " +
78 LogMessageDoc.GENERIC_ACTION)
79
80 protected List<?> getSwitchStatistics(long switchId,
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070081 OFStatsType statType) {
Ray Milkey269ffb92014-04-03 14:43:30 -070082 IFloodlightProviderService floodlightProvider =
83 (IFloodlightProviderService) getContext().getAttributes().
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070084 get(IFloodlightProviderService.class.getCanonicalName());
Ray Milkey269ffb92014-04-03 14:43:30 -070085
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080086 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070087 Future<List<OFStatsReply>> future;
88 List<OFStatsReply> values = null;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080089 if (sw != null) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070090 OFStatsRequest<?> req = null;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070091 if (statType == OFStatsType.FLOW) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070092 log.debug("Switch Flow Stats req sent for switch {}",
93 sw.getStringId());
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070094 OFMatchV3 match = sw.getFactory().buildMatchV3()
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070095 .setOxmList(OFOxmList.EMPTY).build();
96 req = sw.getFactory()
97 .buildFlowStatsRequest()
98 .setMatch(match)
99 .setOutPort(OFPort.ANY)
100 .setTableId(TableId.ALL)
101 .setXid(sw.getNextTransactionId()).build();
Fahad Naeem Khand89448d2014-10-06 18:40:45 -0700102 List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
103 try {
104 future = sw.getStatistics(req);
105 values = future.get(10, TimeUnit.SECONDS);
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800106 for(OFStatsReply value : values){
107 for (OFFlowStatsEntry entry : ((OFFlowStatsReply)value).getEntries()) {
108 OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry, sw);
109 flowStats.add(entryMod);
110 }
Fahad Naeem Khand89448d2014-10-06 18:40:45 -0700111 }
112 log.debug("Switch flow Stats Entries from switch {} are {}",
113 sw.getStringId(), flowStats);
114 } catch (Exception e) {
115 log.error("Failure retrieving statistics from switch " + sw, e);
116 }
117 return flowStats;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700118 }
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700119 else if (statType == OFStatsType.PORT){
120 log.debug("Switch Port Stats: req sent for all "
121 + "ports in switch {}", sw.getStringId());
122 List<OFPortStatsEntryMod> portStats = null;
123 req = sw.getFactory()
124 .buildPortStatsRequest()
125 .setPortNo(OFPort.ANY).setXid
126 (sw.getNextTransactionId()).build();
127 try {
128 future = sw.getStatistics(req);
129 values = future.get(10, TimeUnit.SECONDS);
130 portStats = new ArrayList<OFPortStatsEntryMod>();
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800131 for(OFStatsReply value : values){
132 for (OFPortStatsEntry entry : ((OFPortStatsReply)value).getEntries()) {
Fahad Naeem Khanf52d92e2014-11-04 16:22:10 -0800133 OFPortStatsEntryMod entryMod = new OFPortStatsEntryMod(entry, sw);
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800134 portStats.add(entryMod);
135 }
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700136 }
137 log.debug("Switch Port Stats Entries from switch {} are {}",
138 sw.getStringId(), portStats);
139 } catch (Exception e) {
140 log.error("Failure retrieving statistics from switch " + sw, e);
141 }
142 return portStats;
143 }
144 else if (statType == OFStatsType.GROUP){
145 log.debug("Switch Group Stats: req sent for all "
Fahad Naeem Khan074892b2014-11-03 14:56:36 -0800146 + "groups in switch {}", sw.getStringId());
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700147 req = sw.getFactory().buildGroupStatsRequest().setXid
148 (sw.getNextTransactionId()).build();
Fahad Naeem Khan8a8daf22014-10-06 14:07:43 -0700149 List<OFGroupStatsEntryMod> groupStats = new ArrayList<OFGroupStatsEntryMod>();
150 try {
151 future = sw.getStatistics(req);
152 values = future.get(10, TimeUnit.SECONDS);
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800153 for(OFStatsReply value : values){
154 for (OFGroupStatsEntry entry : ((OFGroupStatsReply)value).getEntries()) {
155 OFGroupStatsEntryMod entryMod = new OFGroupStatsEntryMod(entry);
156 groupStats.add(entryMod);
157 }
Fahad Naeem Khan8a8daf22014-10-06 14:07:43 -0700158 }
159 log.debug("Switch Group Stats Entries from switch {} are {}",
160 sw.getStringId(), groupStats);
161 } catch (Exception e) {
162 log.error("Failure retrieving statistics from switch " + sw, e);
163 }
164 return groupStats;
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700165 }
166 else if (statType == OFStatsType.GROUP_DESC){
167 log.debug("Switch Group Desc Stats: req sent for all "
Fahad Naeem Khan074892b2014-11-03 14:56:36 -0800168 + "groups in switch {}", sw.getStringId());
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700169 List<OFGroupDescStatsEntryMod> GroupDescStats= new ArrayList<OFGroupDescStatsEntryMod>();
170 req = sw.getFactory().buildGroupDescStatsRequest().setXid
171 (sw.getNextTransactionId()).build();
172 try {
173 future = sw.getStatistics(req);
174 values = future.get(10, TimeUnit.SECONDS);
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800175 for(OFStatsReply value : values){
176 for (OFGroupDescStatsEntry entry : ((OFGroupDescStatsReply)value).getEntries()) {
177 OFGroupDescStatsEntryMod entryMod = new OFGroupDescStatsEntryMod(entry);
178 GroupDescStats.add(entryMod);
179 }
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700180 }
181 log.debug("Switch Group_Desc Stats Entries from switch {} are {}",
182 sw.getStringId(), GroupDescStats);
183 } catch (Exception e) {
184 log.error("Failure retrieving statistics from switch " + sw, e);
185 }
186 return GroupDescStats;
187 }
188 /*else if (statType == OFStatisticsType.AGGREGATE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800189 OFAggregateStatisticsRequest specificReq = new OFAggregateStatisticsRequest();
190 OFMatch match = new OFMatch();
191 match.setWildcards(0xffffffff);
192 specificReq.setMatch(match);
193 specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
194 specificReq.setTableId((byte) 0xff);
Ray Milkey269ffb92014-04-03 14:43:30 -0700195 req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800196 requestLength += specificReq.getLength();
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700197 } /*else if (statType == OFStatisticsType.QUEUE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800198 OFQueueStatisticsRequest specificReq = new OFQueueStatisticsRequest();
Ray Milkeyff735142014-05-22 19:06:02 -0700199 specificReq.setPortNumber(OFPort.OFPP_ALL.getValue());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800200 // LOOK! openflowj does not define OFPQ_ALL! pulled this from openflow.h
201 // note that I haven't seen this work yet though...
202 specificReq.setQueueId(0xffffffff);
Ray Milkey269ffb92014-04-03 14:43:30 -0700203 req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800204 requestLength += specificReq.getLength();
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700205 } else if (statType == OFStatisticsType.DESC ||
Ray Milkey269ffb92014-04-03 14:43:30 -0700206 statType == OFStatisticsType.TABLE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800207 // pass - nothing todo besides set the type above
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700208 }*/
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700209 // XXX S fix when we fix stats
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700210 try {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800211 future = sw.getStatistics(req);
212 values = future.get(10, TimeUnit.SECONDS);
213 } catch (Exception e) {
214 log.error("Failure retrieving statistics from switch " + sw, e);
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700215 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800216 }
217 return values;
218 }
219
Srikanth Vavilapallib7258512014-09-29 13:24:11 -0700220 protected Object getSwitchStatistics(String switchId, OFStatsType statType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800221 return getSwitchStatistics(HexString.toLong(switchId), statType);
222 }
Fahad Naeem Khan074892b2014-11-03 14:56:36 -0800223
224 protected Object getSwitchGroupStats(String switchId, OFStatsType statType, Integer groupId) {
225
226 IFloodlightProviderService floodlightProvider =
227 (IFloodlightProviderService) getContext().getAttributes().
228 get(IFloodlightProviderService.class.getCanonicalName());
229 IOFSwitch sw = floodlightProvider.getSwitches().get(HexString.toLong(switchId));
230 Future<List<OFStatsReply>> future;
231 List<OFStatsReply> values = null;
232 if (sw != null){
233 log.debug("Switch Group Stats: req sent for groupId {} "
234 + "in switch {}",groupId, sw.getStringId());
235 OFStatsRequest<?> req = null;
236 req = sw.getFactory().buildGroupStatsRequest().setXid
237 (sw.getNextTransactionId()).setGroup(OFGroup.of(groupId)).build();
238 List<OFGroupStatsEntryMod> groupStats = new ArrayList<OFGroupStatsEntryMod>();
239 try {
240 future = sw.getStatistics(req);
241 values = future.get(10, TimeUnit.SECONDS);
242 if(values.isEmpty()){
243 log.warn("group with groupId {} not found", groupId);
244 return null;
245 }
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800246 for(OFStatsReply value : values){
247 for (OFGroupStatsEntry entry : ((OFGroupStatsReply)value).getEntries()) {
248 OFGroupStatsEntryMod entryMod = new OFGroupStatsEntryMod(entry);
249 groupStats.add(entryMod);
250 }
Fahad Naeem Khan074892b2014-11-03 14:56:36 -0800251 }
252 log.debug("Switch Group Stats Entries from switch {} are {}",
253 sw.getStringId(), groupStats);
254 } catch (Exception e) {
255 log.error("Failure retrieving statistics from switch " + sw, e);
256 }
257 return groupStats;
258
259 }
260 return null;
261 }
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700262 //TODO: Java doc
263 protected List<?> getSwitchStatisticsForTable(long switchId,
264 OFStatsType statType, String tableType) {
265 IFloodlightProviderService floodlightProvider =
266 (IFloodlightProviderService) getContext().getAttributes().
267 get(IFloodlightProviderService.class.getCanonicalName());
268 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
269 Future<List<OFStatsReply>> future;
270 List<OFStatsReply> values = null;
271 //getting tableId from CPqD driver
272 TableId tableId;
273 if (sw != null) {
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700274 if ((tableId = ((OFSwitchImplSpringOpenTTP) sw).getTableId(tableType)) == null) {
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700275 log.error("Invalid tableType {} " + tableType);
276 return null;
277 }
278 OFStatsRequest<?> req = null;
279 if (statType == OFStatsType.FLOW) {
280 log.debug("Switch Flow Stats req for table {} sent to switch {}",
281 tableType,sw.getStringId());
282 OFMatchV3 match = sw.getFactory().buildMatchV3()
283 .setOxmList(OFOxmList.EMPTY).build();
284 req = sw.getFactory()
285 .buildFlowStatsRequest()
286 .setMatch(match)
287 .setOutPort(OFPort.ANY)
288 .setTableId(tableId)
289 .setXid(sw.getNextTransactionId()).build();
290 List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
291 try {
292 future = sw.getStatistics(req);
293 values = future.get(10, TimeUnit.SECONDS);
Fahad Naeem Khan45385de2014-11-04 15:35:38 -0800294 for(OFStatsReply value : values){
295 for (OFFlowStatsEntry entry : ((OFFlowStatsReply)value).getEntries()) {
296 OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry, sw);
297 flowStats.add(entryMod);
298 }
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700299 }
300 log.debug("Switch flow Stats Entries for table {} from switch {} are {}",
301 tableType, sw.getStringId(), flowStats);
302 } catch (Exception e) {
303 log.error("Failure retrieving per table statistics from switch " + sw, e);
304 }
305 return flowStats;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700306 }
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700307 }
308 //should never get to this point
309 log.error("Failure retrieving {} table statistics from switch {}",tableType, sw);
310 return null;
311 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700312
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800313 protected OFFeaturesReply getSwitchFeaturesReply(long switchId) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700314 IFloodlightProviderService floodlightProvider =
315 (IFloodlightProviderService) getContext().getAttributes().
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700316 get(IFloodlightProviderService.class.getCanonicalName());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800317
318 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700319 //uture<OFFeaturesReply> future;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800320 OFFeaturesReply featuresReply = null;
321 if (sw != null) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700322 // XXX S fix when we fix stats
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700323 try {
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700324 //future = sw.getFeaturesReplyFromSwitch();
325 //featuresReply = future.get(10, TimeUnit.SECONDS);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800326 } catch (Exception e) {
327 log.error("Failure getting features reply from switch" + sw, e);
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700328 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800329 }
330
331 return featuresReply;
332 }
333
334 protected OFFeaturesReply getSwitchFeaturesReply(String switchId) {
335 return getSwitchFeaturesReply(HexString.toLong(switchId));
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -0700336 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800337
338}