blob: fd78c1f2ede96dde849685c04ef0946a6372d8b0 [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;
44import org.projectfloodlight.openflow.types.OFPort;
45import org.projectfloodlight.openflow.types.TableId;
46import org.projectfloodlight.openflow.util.HexString;
47import org.restlet.resource.ResourceException;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080048import org.restlet.resource.ServerResource;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080051
52/**
53 * Base class for server resources related to switches
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070054 *
Ray Milkey269ffb92014-04-03 14:43:30 -070055 * @author readams
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080056 */
Ray Milkeyff735142014-05-22 19:06:02 -070057
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080058public class SwitchResourceBase extends ServerResource {
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070059 protected final static Logger log = LoggerFactory.getLogger(SwitchResourceBase.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070060
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080061 public enum REQUESTTYPE {
62 OFSTATS,
63 OFFEATURES
64 }
Ray Milkey269ffb92014-04-03 14:43:30 -070065
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080066 @Override
67 protected void doInit() throws ResourceException {
68 super.doInit();
Ray Milkey269ffb92014-04-03 14:43:30 -070069
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080070 }
Ray Milkey269ffb92014-04-03 14:43:30 -070071
72 @LogMessageDoc(level = "ERROR",
73 message = "Failure retrieving statistics from switch {switch}",
74 explanation = "An error occurred while retrieving statistics" +
75 "from the switch",
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070076 recommendation = LogMessageDoc.CHECK_SWITCH + " " +
77 LogMessageDoc.GENERIC_ACTION)
78
79 protected List<?> getSwitchStatistics(long switchId,
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070080 OFStatsType statType) {
Ray Milkey269ffb92014-04-03 14:43:30 -070081 IFloodlightProviderService floodlightProvider =
82 (IFloodlightProviderService) getContext().getAttributes().
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -070083 get(IFloodlightProviderService.class.getCanonicalName());
Ray Milkey269ffb92014-04-03 14:43:30 -070084
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080085 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070086 Future<List<OFStatsReply>> future;
87 List<OFStatsReply> values = null;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080088 if (sw != null) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070089 OFStatsRequest<?> req = null;
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070090 if (statType == OFStatsType.FLOW) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070091 log.debug("Switch Flow Stats req sent for switch {}",
92 sw.getStringId());
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -070093 OFMatchV3 match = sw.getFactory().buildMatchV3()
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070094 .setOxmList(OFOxmList.EMPTY).build();
95 req = sw.getFactory()
96 .buildFlowStatsRequest()
97 .setMatch(match)
98 .setOutPort(OFPort.ANY)
99 .setTableId(TableId.ALL)
100 .setXid(sw.getNextTransactionId()).build();
Fahad Naeem Khand89448d2014-10-06 18:40:45 -0700101 List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
102 try {
103 future = sw.getStatistics(req);
104 values = future.get(10, TimeUnit.SECONDS);
Fahad Naeem Khand89448d2014-10-06 18:40:45 -0700105 for (OFFlowStatsEntry entry : ((OFFlowStatsReply)values.get(0)).getEntries()) {
106 OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry);
107 flowStats.add(entryMod);
108 }
109 log.debug("Switch flow Stats Entries from switch {} are {}",
110 sw.getStringId(), flowStats);
111 } catch (Exception e) {
112 log.error("Failure retrieving statistics from switch " + sw, e);
113 }
114 return flowStats;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700115 }
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700116 else if (statType == OFStatsType.PORT){
117 log.debug("Switch Port Stats: req sent for all "
118 + "ports in switch {}", sw.getStringId());
119 List<OFPortStatsEntryMod> portStats = null;
120 req = sw.getFactory()
121 .buildPortStatsRequest()
122 .setPortNo(OFPort.ANY).setXid
123 (sw.getNextTransactionId()).build();
124 try {
125 future = sw.getStatistics(req);
126 values = future.get(10, TimeUnit.SECONDS);
127 portStats = new ArrayList<OFPortStatsEntryMod>();
128 for (OFPortStatsEntry entry : ((OFPortStatsReply)values.get(0)).getEntries()) {
129 OFPortStatsEntryMod entryMod = new OFPortStatsEntryMod(entry);
130 portStats.add(entryMod);
131 }
132 log.debug("Switch Port Stats Entries from switch {} are {}",
133 sw.getStringId(), portStats);
134 } catch (Exception e) {
135 log.error("Failure retrieving statistics from switch " + sw, e);
136 }
137 return portStats;
138 }
139 else if (statType == OFStatsType.GROUP){
140 log.debug("Switch Group Stats: req sent for all "
141 + "ports in switch {}", sw.getStringId());
142 req = sw.getFactory().buildGroupStatsRequest().setXid
143 (sw.getNextTransactionId()).build();
Fahad Naeem Khan8a8daf22014-10-06 14:07:43 -0700144 List<OFGroupStatsEntryMod> groupStats = new ArrayList<OFGroupStatsEntryMod>();
145 try {
146 future = sw.getStatistics(req);
147 values = future.get(10, TimeUnit.SECONDS);
148 for (OFGroupStatsEntry entry : ((OFGroupStatsReply)values.get(0)).getEntries()) {
149 OFGroupStatsEntryMod entryMod = new OFGroupStatsEntryMod(entry);
150 groupStats.add(entryMod);
151 }
152 log.debug("Switch Group Stats Entries from switch {} are {}",
153 sw.getStringId(), groupStats);
154 } catch (Exception e) {
155 log.error("Failure retrieving statistics from switch " + sw, e);
156 }
157 return groupStats;
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700158 }
159 else if (statType == OFStatsType.GROUP_DESC){
160 log.debug("Switch Group Desc Stats: req sent for all "
161 + "ports in switch {}", sw.getStringId());
162 List<OFGroupDescStatsEntryMod> GroupDescStats= new ArrayList<OFGroupDescStatsEntryMod>();
163 req = sw.getFactory().buildGroupDescStatsRequest().setXid
164 (sw.getNextTransactionId()).build();
165 try {
166 future = sw.getStatistics(req);
167 values = future.get(10, TimeUnit.SECONDS);
168 for (OFGroupDescStatsEntry entry : ((OFGroupDescStatsReply)values.get(0)).getEntries()) {
169 OFGroupDescStatsEntryMod entryMod = new OFGroupDescStatsEntryMod(entry);
170 GroupDescStats.add(entryMod);
171 }
172 log.debug("Switch Group_Desc Stats Entries from switch {} are {}",
173 sw.getStringId(), GroupDescStats);
174 } catch (Exception e) {
175 log.error("Failure retrieving statistics from switch " + sw, e);
176 }
177 return GroupDescStats;
178 }
179 /*else if (statType == OFStatisticsType.AGGREGATE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800180 OFAggregateStatisticsRequest specificReq = new OFAggregateStatisticsRequest();
181 OFMatch match = new OFMatch();
182 match.setWildcards(0xffffffff);
183 specificReq.setMatch(match);
184 specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
185 specificReq.setTableId((byte) 0xff);
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800187 requestLength += specificReq.getLength();
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700188 } /*else if (statType == OFStatisticsType.QUEUE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800189 OFQueueStatisticsRequest specificReq = new OFQueueStatisticsRequest();
Ray Milkeyff735142014-05-22 19:06:02 -0700190 specificReq.setPortNumber(OFPort.OFPP_ALL.getValue());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800191 // LOOK! openflowj does not define OFPQ_ALL! pulled this from openflow.h
192 // note that I haven't seen this work yet though...
193 specificReq.setQueueId(0xffffffff);
Ray Milkey269ffb92014-04-03 14:43:30 -0700194 req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800195 requestLength += specificReq.getLength();
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700196 } else if (statType == OFStatisticsType.DESC ||
Ray Milkey269ffb92014-04-03 14:43:30 -0700197 statType == OFStatisticsType.TABLE) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800198 // pass - nothing todo besides set the type above
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700199 }*/
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700200 // XXX S fix when we fix stats
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700201 try {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800202 future = sw.getStatistics(req);
203 values = future.get(10, TimeUnit.SECONDS);
204 } catch (Exception e) {
205 log.error("Failure retrieving statistics from switch " + sw, e);
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700206 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800207 }
208 return values;
209 }
210
Srikanth Vavilapallib7258512014-09-29 13:24:11 -0700211 protected Object getSwitchStatistics(String switchId, OFStatsType statType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800212 return getSwitchStatistics(HexString.toLong(switchId), statType);
213 }
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700214 //TODO: Java doc
215 protected List<?> getSwitchStatisticsForTable(long switchId,
216 OFStatsType statType, String tableType) {
217 IFloodlightProviderService floodlightProvider =
218 (IFloodlightProviderService) getContext().getAttributes().
219 get(IFloodlightProviderService.class.getCanonicalName());
220 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
221 Future<List<OFStatsReply>> future;
222 List<OFStatsReply> values = null;
223 //getting tableId from CPqD driver
224 TableId tableId;
225 if (sw != null) {
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700226 if ((tableId = ((OFSwitchImplSpringOpenTTP) sw).getTableId(tableType)) == null) {
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700227 log.error("Invalid tableType {} " + tableType);
228 return null;
229 }
230 OFStatsRequest<?> req = null;
231 if (statType == OFStatsType.FLOW) {
232 log.debug("Switch Flow Stats req for table {} sent to switch {}",
233 tableType,sw.getStringId());
234 OFMatchV3 match = sw.getFactory().buildMatchV3()
235 .setOxmList(OFOxmList.EMPTY).build();
236 req = sw.getFactory()
237 .buildFlowStatsRequest()
238 .setMatch(match)
239 .setOutPort(OFPort.ANY)
240 .setTableId(tableId)
241 .setXid(sw.getNextTransactionId()).build();
242 List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
243 try {
244 future = sw.getStatistics(req);
245 values = future.get(10, TimeUnit.SECONDS);
246 for (OFFlowStatsEntry entry : ((OFFlowStatsReply)values.get(0)).getEntries()) {
247 OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry);
248 flowStats.add(entryMod);
249 }
250 log.debug("Switch flow Stats Entries for table {} from switch {} are {}",
251 tableType, sw.getStringId(), flowStats);
252 } catch (Exception e) {
253 log.error("Failure retrieving per table statistics from switch " + sw, e);
254 }
255 return flowStats;
Srikanth Vavilapalli8a661e72014-10-27 15:40:22 -0700256 }
Fahad Naeem Khand563af62014-10-08 17:37:25 -0700257 }
258 //should never get to this point
259 log.error("Failure retrieving {} table statistics from switch {}",tableType, sw);
260 return null;
261 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700262
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800263 protected OFFeaturesReply getSwitchFeaturesReply(long switchId) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700264 IFloodlightProviderService floodlightProvider =
265 (IFloodlightProviderService) getContext().getAttributes().
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700266 get(IFloodlightProviderService.class.getCanonicalName());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800267
268 IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700269 //uture<OFFeaturesReply> future;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800270 OFFeaturesReply featuresReply = null;
271 if (sw != null) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700272 // XXX S fix when we fix stats
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700273 try {
Fahad Naeem Khan9ae7fa12014-10-03 14:30:55 -0700274 //future = sw.getFeaturesReplyFromSwitch();
275 //featuresReply = future.get(10, TimeUnit.SECONDS);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800276 } catch (Exception e) {
277 log.error("Failure getting features reply from switch" + sw, e);
Jonathan Hartc78b8f62014-08-07 22:31:09 -0700278 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800279 }
280
281 return featuresReply;
282 }
283
284 protected OFFeaturesReply getSwitchFeaturesReply(String switchId) {
285 return getSwitchFeaturesReply(HexString.toLong(switchId));
Srikanth Vavilapallia0e6d582014-09-28 22:42:34 -0700286 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800287
288}