blob: 246bc802baead7134f102caf9d09abd27d20ad27 [file] [log] [blame]
David K. Bainbridge157bdab2020-01-16 14:38:05 -08001/*
2 Copyright 2020 the original author or authors.
3
4 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
7
8 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.
15*/
16
17package openflow
18
19import (
20 "context"
21 "encoding/json"
David Bainbridgef8ce7d22020-04-08 12:49:41 -070022 "net"
23 "unsafe"
24
David K. Bainbridge157bdab2020-01-16 14:38:05 -080025 "github.com/donNewtonAlpha/goloxi"
26 ofp "github.com/donNewtonAlpha/goloxi/of13"
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -080027 "github.com/opencord/voltha-lib-go/v3/pkg/log"
28 "github.com/opencord/voltha-protos/v3/go/common"
29 "github.com/opencord/voltha-protos/v3/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080030)
31
Jonathan Hart4b110f62020-03-13 17:36:19 -070032func (ofc *OFConnection) handleStatsRequest(request ofp.IHeader, statType uint16) error {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080033 if logger.V(log.DebugLevel) {
34 js, _ := json.Marshal(request)
35 logger.Debugw("handleStatsRequest called",
36 log.Fields{
37 "device-id": ofc.DeviceID,
38 "stat-type": statType,
39 "request": js})
40 }
41
42 switch statType {
43 case ofp.OFPSTDesc:
44 statsReq := request.(*ofp.DescStatsRequest)
45 response, err := ofc.handleDescStatsRequest(statsReq)
46 if err != nil {
47 return err
48 }
49 if logger.V(log.DebugLevel) {
50 reqJs, _ := json.Marshal(statsReq)
51 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080052 logger.Debugw("handle-stats-request-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080053 log.Fields{
54 "device-id": ofc.DeviceID,
55 "request": reqJs,
56 "response": resJs})
57 }
58 return ofc.SendMessage(response)
59 case ofp.OFPSTFlow:
60 statsReq := request.(*ofp.FlowStatsRequest)
61 response, err := ofc.handleFlowStatsRequest(statsReq)
62 if err != nil {
63 return err
64 }
65 response.Length = uint16(unsafe.Sizeof(*response))
66 if logger.V(log.DebugLevel) {
67 reqJs, _ := json.Marshal(statsReq)
68 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080069 logger.Debugw("handle-stats-request-flow",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080070 log.Fields{
Don Newton7fe70f72020-02-21 13:54:11 -050071 "device-id": ofc.DeviceID,
72 "request": reqJs,
73 "response-object": response,
74 "response": resJs})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080075 }
76 return ofc.SendMessage(response)
77
78 case ofp.OFPSTAggregate:
79 statsReq := request.(*ofp.AggregateStatsRequest)
80 response, err := ofc.handleAggregateStatsRequest(statsReq)
81 if err != nil {
82 return err
83 }
84 if logger.V(log.DebugLevel) {
85 reqJs, _ := json.Marshal(statsReq)
86 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080087 logger.Debugw("handle-stats-request-aggregate",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080088 log.Fields{
89 "device-id": ofc.DeviceID,
90 "request": reqJs,
91 "response": resJs})
92 }
93 return ofc.SendMessage(response)
94 case ofp.OFPSTTable:
95 statsReq := request.(*ofp.TableStatsRequest)
96 response, e := ofc.handleTableStatsRequest(statsReq)
97 if logger.V(log.DebugLevel) {
98 reqJs, _ := json.Marshal(statsReq)
99 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800100 logger.Debugw("handle-stats-request-table",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800101 log.Fields{
102 "device-id": ofc.DeviceID,
103 "request": reqJs,
104 "response": resJs})
105 }
106 if e != nil {
107 return e
108 }
109 return ofc.SendMessage(response)
110 case ofp.OFPSTPort:
111 statsReq := request.(*ofp.PortStatsRequest)
112 response, err := ofc.handlePortStatsRequest(statsReq)
113 if err != nil {
114 return err
115 }
116 if logger.V(log.DebugLevel) {
117 reqJs, _ := json.Marshal(statsReq)
118 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800119 logger.Debugw("handle-stats-request-port",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800120 log.Fields{
121 "device-id": ofc.DeviceID,
122 "request": reqJs,
123 "response": resJs})
124 }
125 return ofc.SendMessage(response)
126 case ofp.OFPSTQueue:
127 statsReq := request.(*ofp.QueueStatsRequest)
128 response, err := ofc.handleQueueStatsRequest(statsReq)
129 if err != nil {
130 return err
131 }
132 if logger.V(log.DebugLevel) {
133 reqJs, _ := json.Marshal(statsReq)
134 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800135 logger.Debugw("handle-stats-request-queue",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800136 log.Fields{
137 "device-id": ofc.DeviceID,
138 "request": reqJs,
139 "response": resJs})
140 }
141 return ofc.SendMessage(response)
142 case ofp.OFPSTGroup:
143 statsReq := request.(*ofp.GroupStatsRequest)
144 response, err := ofc.handleGroupStatsRequest(statsReq)
145 if err != nil {
146 return err
147 }
148 if logger.V(log.DebugLevel) {
149 reqJs, _ := json.Marshal(statsReq)
150 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800151 logger.Debugw("handle-stats-request-group",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800152 log.Fields{
153 "device-id": ofc.DeviceID,
154 "request": reqJs,
155 "response": resJs})
156 }
David K. Bainbridgecac73ac2020-02-19 07:00:12 -0800157 return ofc.SendMessage(response)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800158 case ofp.OFPSTGroupDesc:
159 statsReq := request.(*ofp.GroupDescStatsRequest)
160 response, err := ofc.handleGroupStatsDescRequest(statsReq)
161 if err != nil {
162 return err
163 }
164 if logger.V(log.DebugLevel) {
165 reqJs, _ := json.Marshal(statsReq)
166 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800167 logger.Debugw("handle-stats-request-group-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800168 log.Fields{
169 "device-id": ofc.DeviceID,
170 "request": reqJs,
171 "response": resJs})
172 }
173 return ofc.SendMessage(response)
174
175 case ofp.OFPSTGroupFeatures:
176 statsReq := request.(*ofp.GroupFeaturesStatsRequest)
177 response, err := ofc.handleGroupFeatureStatsRequest(statsReq)
178 if err != nil {
179 return err
180 }
181 if logger.V(log.DebugLevel) {
182 reqJs, _ := json.Marshal(statsReq)
183 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800184 logger.Debugw("handle-stats-request-group-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800185 log.Fields{
186 "device-id": ofc.DeviceID,
187 "request": reqJs,
188 "response": resJs})
189 }
190 return ofc.SendMessage(response)
191 case ofp.OFPSTMeter:
192 statsReq := request.(*ofp.MeterStatsRequest)
193 response, err := ofc.handleMeterStatsRequest(statsReq)
194 if err != nil {
195 return err
196 }
197 if logger.V(log.DebugLevel) {
198 reqJs, _ := json.Marshal(statsReq)
199 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800200 logger.Debugw("handle-stats-request-meter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800201 log.Fields{
202 "device-id": ofc.DeviceID,
203 "request": reqJs,
204 "response": resJs})
205 }
206 return ofc.SendMessage(response)
207 case ofp.OFPSTMeterConfig:
208 statsReq := request.(*ofp.MeterConfigStatsRequest)
209 response, err := ofc.handleMeterConfigStatsRequest(statsReq)
210 if err != nil {
211 return err
212 }
213 if logger.V(log.DebugLevel) {
214 reqJs, _ := json.Marshal(statsReq)
215 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800216 logger.Debugw("handle-stats-request-meter-config",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800217 log.Fields{
218 "device-id": ofc.DeviceID,
219 "request": reqJs,
220 "response": resJs})
221 }
222 return ofc.SendMessage(response)
223 case ofp.OFPSTMeterFeatures:
224 statsReq := request.(*ofp.MeterFeaturesStatsRequest)
225 response, err := ofc.handleMeterFeatureStatsRequest(statsReq)
226 if err != nil {
227 return err
228 }
229 if logger.V(log.DebugLevel) {
230 reqJs, _ := json.Marshal(statsReq)
231 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800232 logger.Debugw("handle-stats-request-meter-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800233 log.Fields{
234 "device-id": ofc.DeviceID,
235 "request": reqJs,
236 "response": resJs})
237 }
238 return ofc.SendMessage(response)
239 case ofp.OFPSTTableFeatures:
240 statsReq := request.(*ofp.TableFeaturesStatsRequest)
241 response, err := ofc.handleTableFeaturesStatsRequest(statsReq)
242 if err != nil {
243 return err
244 }
245 if logger.V(log.DebugLevel) {
246 reqJs, _ := json.Marshal(statsReq)
247 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800248 logger.Debugw("handle-stats-request-table-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800249 log.Fields{
250 "device-id": ofc.DeviceID,
251 "request": reqJs,
252 "response": resJs})
253 }
254 return ofc.SendMessage(response)
255 case ofp.OFPSTPortDesc:
256 statsReq := request.(*ofp.PortDescStatsRequest)
257 response, err := ofc.handlePortDescStatsRequest(statsReq)
258 if err != nil {
259 return err
260 }
261 if logger.V(log.DebugLevel) {
262 reqJs, _ := json.Marshal(statsReq)
263 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800264 logger.Debugw("handle-stats-request-port-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800265 log.Fields{
266 "device-id": ofc.DeviceID,
267 "request": reqJs,
268 "response": resJs})
269 }
270 return ofc.SendMessage(response)
271
272 case ofp.OFPSTExperimenter:
273 statsReq := request.(*ofp.ExperimenterStatsRequest)
274 response, err := ofc.handleExperimenterStatsRequest(statsReq)
275 if err != nil {
276 return err
277 }
278 if logger.V(log.DebugLevel) {
279 reqJs, _ := json.Marshal(statsReq)
280 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800281 logger.Debugw("handle-stats-request-experimenter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800282 log.Fields{
283 "device-id": ofc.DeviceID,
284 "request": reqJs,
285 "response": resJs})
286 }
287 return ofc.SendMessage(response)
288 }
289 return nil
290}
291
Jonathan Hart4b110f62020-03-13 17:36:19 -0700292func (ofc *OFConnection) handleDescStatsRequest(request *ofp.DescStatsRequest) (*ofp.DescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700293 volthaClient := ofc.VolthaClient.Get()
294 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800295 return nil, NoVolthaConnectionError
296 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800297 response := ofp.NewDescStatsReply()
298 response.SetXid(request.GetXid())
299 response.SetVersion(request.GetVersion())
300 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
301
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700302 resp, err := volthaClient.GetLogicalDevice(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800303 &common.ID{Id: ofc.DeviceID})
304 if err != nil {
305 return nil, err
306 }
307 desc := resp.GetDesc()
308
309 response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256))
310 response.SetHwDesc(PadString(desc.GetHwDesc(), 256))
311 response.SetSwDesc(PadString(desc.GetSwDesc(), 256))
312 response.SetSerialNum(PadString(desc.GetSerialNum(), 32))
313 response.SetDpDesc(PadString(desc.GetDpDesc(), 256))
314 return response, nil
315}
316
Jonathan Hart4b110f62020-03-13 17:36:19 -0700317func (ofc *OFConnection) handleFlowStatsRequest(request *ofp.FlowStatsRequest) (*ofp.FlowStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700318 volthaClient := ofc.VolthaClient.Get()
319 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800320 return nil, NoVolthaConnectionError
321 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800322 response := ofp.NewFlowStatsReply()
323 response.SetXid(request.GetXid())
324 response.SetVersion(4)
325 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700326 resp, err := volthaClient.ListLogicalDeviceFlows(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800327 &common.ID{Id: ofc.DeviceID})
328 if err != nil {
329 return nil, err
330 }
331 var flow []*ofp.FlowStatsEntry
332 for _, item := range resp.GetItems() {
333 entry := ofp.NewFlowStatsEntry()
334 entry.SetTableId(uint8(item.GetTableId()))
335 entry.SetDurationSec(item.GetDurationSec())
336 entry.SetDurationNsec(item.GetDurationNsec())
337 entry.SetPriority(uint16(item.GetPriority()))
338 entry.SetIdleTimeout(uint16(item.GetIdleTimeout()))
339 entry.SetHardTimeout(uint16(item.GetHardTimeout()))
340 entry.SetFlags(ofp.FlowModFlags(item.GetFlags()))
341 entry.SetCookie(item.GetCookie())
342 entry.SetPacketCount(item.GetPacketCount())
343 entry.SetByteCount(item.GetByteCount())
344 entrySize := uint16(48)
345 match := ofp.NewMatchV3()
346 pbMatch := item.GetMatch()
347 match.SetType(uint16(pbMatch.GetType()))
348 size := uint16(4)
349 var fields []goloxi.IOxm
350 for _, oxmField := range pbMatch.GetOxmFields() {
351 field := oxmField.GetField()
352 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
353 iOxm, oxmSize := parseOxm(ofbField, ofc.DeviceID)
354 fields = append(fields, iOxm)
355 if oxmSize > 0 {
356 size += 4 //header for oxm
357 }
358 size += oxmSize
359 }
360
361 match.OxmList = fields
362 match.Length = uint16(size)
363 //account for 8 byte alignment
364 if size%8 != 0 {
365 size = ((size / 8) + 1) * 8
366 }
367 entrySize += size
368 entry.SetMatch(*match)
369 var instructions []ofp.IInstruction
370 for _, ofpInstruction := range item.Instructions {
371 instruction, size := parseInstructions(ofpInstruction, ofc.DeviceID)
372 instructions = append(instructions, instruction)
373 entrySize += size
374 }
375 entry.Instructions = instructions
376 entry.Length = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800377 flow = append(flow, entry)
378 }
379 response.SetEntries(flow)
380 return response, nil
381}
382
Jonathan Hart4b110f62020-03-13 17:36:19 -0700383func (ofc *OFConnection) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800384 response := ofp.NewAggregateStatsReply()
385 response.SetVersion(request.GetVersion())
386 response.SetXid(request.GetXid())
387 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
388 response.SetFlowCount(0)
389 //TODO wire this to voltha core when it implements
390 return response, nil
391}
392
Jonathan Hart4b110f62020-03-13 17:36:19 -0700393func (ofc *OFConnection) handleGroupStatsRequest(request *ofp.GroupStatsRequest) (*ofp.GroupStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700394 volthaClient := ofc.VolthaClient.Get()
395 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800396 return nil, NoVolthaConnectionError
397 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800398 response := ofp.NewGroupStatsReply()
399 response.SetVersion(request.GetVersion())
400 response.SetXid(request.GetXid())
401 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700402 reply, err := volthaClient.ListLogicalDeviceFlowGroups(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800403 &common.ID{Id: ofc.DeviceID})
404 if err != nil {
405 return nil, err
406 }
407
408 var groupStatsEntries []*ofp.GroupStatsEntry
409 for _, item := range reply.GetItems() {
410 stats := item.GetStats()
411 var entry ofp.GroupStatsEntry
412 entry.SetByteCount(stats.GetByteCount())
413 entry.SetPacketCount(stats.GetPacketCount())
414 entry.SetDurationNsec(stats.GetDurationNsec())
415 entry.SetDurationSec(stats.GetDurationSec())
416 entry.SetRefCount(stats.GetRefCount())
417 entry.SetGroupId(stats.GetGroupId())
418 var bucketStatsList []*ofp.BucketCounter
419 for _, bucketStat := range stats.GetBucketStats() {
420 bucketCounter := ofp.BucketCounter{}
421 bucketCounter.SetPacketCount(bucketStat.GetPacketCount())
422 bucketCounter.SetByteCount(bucketStat.GetByteCount())
423 bucketStatsList = append(bucketStatsList, &bucketCounter)
424 }
425 entry.SetBucketStats(bucketStatsList)
426 groupStatsEntries = append(groupStatsEntries, &entry)
427 }
428 response.SetEntries(groupStatsEntries)
429 return response, nil
430}
431
Jonathan Hart4b110f62020-03-13 17:36:19 -0700432func (ofc *OFConnection) handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest) (*ofp.GroupDescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700433 volthaClient := ofc.VolthaClient.Get()
434 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800435 return nil, NoVolthaConnectionError
436 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800437 response := ofp.NewGroupDescStatsReply()
438 response.SetVersion(request.GetVersion())
439 response.SetXid(request.GetXid())
440 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700441 reply, err := volthaClient.ListLogicalDeviceFlowGroups(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800442 &common.ID{Id: ofc.DeviceID})
443 if err != nil {
444 return nil, err
445 }
446 var groupDescStatsEntries []*ofp.GroupDescStatsEntry
447 for _, item := range reply.GetItems() {
448 stats := item.GetStats()
449 var groupDesc ofp.GroupDescStatsEntry
450 groupDesc.SetGroupId(stats.GetGroupId())
451 /*
452 buckets := item.g
453 var bucketList []*ofp.Bucket
454 for j:=0;j<len(buckets);j++{
455
456 }
457
458 groupDesc.SetBuckets(bucketList)
459 */
460 groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc)
461 }
462 response.SetEntries(groupDescStatsEntries)
463 return response, nil
464}
465
Jonathan Hart4b110f62020-03-13 17:36:19 -0700466func (ofc *OFConnection) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800467 response := ofp.NewGroupFeaturesStatsReply()
468 response.SetVersion(request.GetVersion())
469 response.SetXid(request.GetXid())
470 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
471 //TODO wire this to voltha core when it implements
472 return response, nil
473}
474
Jonathan Hart4b110f62020-03-13 17:36:19 -0700475func (ofc *OFConnection) handleMeterStatsRequest(request *ofp.MeterStatsRequest) (*ofp.MeterStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700476 volthaClient := ofc.VolthaClient.Get()
477 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800478 return nil, NoVolthaConnectionError
479 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800480 response := ofp.NewMeterStatsReply()
481 response.SetVersion(request.GetVersion())
482 response.SetXid(request.GetXid())
483 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700484 resp, err := volthaClient.ListLogicalDeviceMeters(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800485 &common.ID{Id: ofc.DeviceID})
486 if err != nil {
487 return nil, err
488 }
David K. Bainbridge55376262020-01-22 23:28:27 -0800489 size := uint16(5) // size of stats header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800490 var meterStats []*ofp.MeterStats
491 for _, item := range resp.Items {
David K. Bainbridge55376262020-01-22 23:28:27 -0800492 entrySize := uint16(40) // size of entry header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800493 meterStat := ofp.NewMeterStats()
494 stats := item.Stats
495 meterStat.DurationNsec = stats.DurationNsec
496 meterStat.DurationSec = stats.DurationSec
497 meterStat.ByteInCount = stats.ByteInCount
498 meterStat.FlowCount = stats.FlowCount
499 meterStat.MeterId = stats.MeterId
500 var bandStats []*ofp.MeterBandStats
501 for _, bStat := range stats.BandStats {
502 bandStat := ofp.NewMeterBandStats()
503 bandStat.ByteBandCount = bStat.ByteBandCount
504 bandStat.PacketBandCount = bStat.PacketBandCount
505 bandStats = append(bandStats, bandStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800506 entrySize += uint16(16) // size of each band stat
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800507 }
508 meterStat.SetBandStats(bandStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800509 meterStat.Len = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800510 meterStats = append(meterStats, meterStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800511 size += entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800512 }
513 response.SetEntries(meterStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800514 response.SetLength(size)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800515 return response, nil
516}
517
Jonathan Hart4b110f62020-03-13 17:36:19 -0700518func (ofc *OFConnection) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800519 response := ofp.NewMeterConfigStatsReply()
520 response.SetVersion(request.GetVersion())
521 response.SetXid(request.GetXid())
522 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
523 //TODO wire this to voltha core when it implements
524 return response, nil
525}
526
Jonathan Hart4b110f62020-03-13 17:36:19 -0700527func (ofc *OFConnection) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800528 response := ofp.NewTableFeaturesStatsReply()
529 response.SetVersion(request.GetVersion())
530 response.SetXid(request.GetXid())
531 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
532 //TODO wire this to voltha core when it implements
533 return response, nil
534}
535
Jonathan Hart4b110f62020-03-13 17:36:19 -0700536func (ofc *OFConnection) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800537 var response = ofp.NewTableStatsReply()
538 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
539 response.SetVersion(request.GetVersion())
540 response.SetXid(request.GetXid())
541 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
542 return response, nil
543}
544
Jonathan Hart4b110f62020-03-13 17:36:19 -0700545func (ofc *OFConnection) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800546 response := ofp.NewQueueStatsReply()
547 response.SetVersion(request.GetVersion())
548 response.SetXid(request.GetXid())
549 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
550 //TODO wire this to voltha core when it implements
551 return response, nil
552}
553
Jonathan Hart4b110f62020-03-13 17:36:19 -0700554func (ofc *OFConnection) handlePortStatsRequest(request *ofp.PortStatsRequest) (*ofp.PortStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700555 volthaClient := ofc.VolthaClient.Get()
556 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800557 return nil, NoVolthaConnectionError
558 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800559 response := ofp.NewPortStatsReply()
560 response.SetXid(request.GetXid())
561 response.SetVersion(request.GetVersion())
562 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700563 reply, err := volthaClient.ListLogicalDevicePorts(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800564 &common.ID{Id: ofc.DeviceID})
565 if err != nil {
566 return nil, err
567 }
568 var entries []*ofp.PortStatsEntry
569 if request.GetPortNo() == 0xffffffff { //all ports
570 for _, port := range reply.GetItems() {
571 entries = append(entries, parsePortStats(port))
572 }
573 } else { //find right port that is requested
574 for _, port := range reply.GetItems() {
575 if port.GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
576 entries = append(entries, parsePortStats(port))
577 }
578 }
579 }
580 response.SetEntries(entries)
581 return response, nil
582}
583
Jonathan Hart4b110f62020-03-13 17:36:19 -0700584func (ofc *OFConnection) handlePortDescStatsRequest(request *ofp.PortDescStatsRequest) (*ofp.PortDescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700585 volthaClient := ofc.VolthaClient.Get()
586 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800587 return nil, NoVolthaConnectionError
588 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800589 response := ofp.NewPortDescStatsReply()
590 response.SetVersion(request.GetVersion())
591 response.SetXid(request.GetXid())
592 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700593 logicalDevice, err := volthaClient.GetLogicalDevice(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800594 &common.ID{Id: ofc.DeviceID})
595 if err != nil {
596 return nil, err
597 }
598 var entries []*ofp.PortDesc
599 for _, port := range logicalDevice.GetPorts() {
600 ofpPort := port.GetOfpPort()
601 var entry ofp.PortDesc
602 entry.SetPortNo(ofp.Port(ofpPort.GetPortNo()))
603
604 var octets []byte
605 for _, val := range ofpPort.GetHwAddr() {
606 octets = append(octets, byte(val))
607 }
608 hwAddr := net.HardwareAddr(octets)
609 entry.SetHwAddr(hwAddr)
610 entry.SetName(PadString(ofpPort.GetName(), 16))
611 entry.SetConfig(ofp.PortConfig(ofpPort.GetConfig()))
612 entry.SetState(ofp.PortState(ofpPort.GetState()))
613 entry.SetCurr(ofp.PortFeatures(ofpPort.GetCurr()))
614 entry.SetAdvertised(ofp.PortFeatures(ofpPort.GetAdvertised()))
615 entry.SetSupported(ofp.PortFeatures(ofpPort.GetSupported()))
616 entry.SetPeer(ofp.PortFeatures(ofpPort.GetPeer()))
617 entry.SetCurrSpeed(ofpPort.GetCurrSpeed())
618 entry.SetMaxSpeed(ofpPort.GetMaxSpeed())
619
620 entries = append(entries, &entry)
621 }
622
623 response.SetEntries(entries)
624 //TODO call voltha and get port descriptions etc
625 return response, nil
626
627}
628
Jonathan Hart4b110f62020-03-13 17:36:19 -0700629func (ofc *OFConnection) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800630 response := ofp.NewMeterFeaturesStatsReply()
631 response.SetXid(request.GetXid())
632 response.SetVersion(request.GetVersion())
633 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
634 meterFeatures := ofp.NewMeterFeatures()
635 meterFeatures.Capabilities = ofp.OFPMFKbps
636 meterFeatures.BandTypes = ofp.OFPMBTDrop
637 meterFeatures.MaxMeter = 0xffffffff
638 meterFeatures.MaxBands = 0xff
639 meterFeatures.MaxColor = 0xff
640 response.Features = *meterFeatures
641 return response, nil
642}
643
Jonathan Hart4b110f62020-03-13 17:36:19 -0700644func (ofc *OFConnection) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800645 response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
646 response.SetVersion(request.GetVersion())
647 response.SetXid(request.GetXid())
648 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
649 //TODO wire this to voltha core when it implements
650 return response, nil
651}