blob: 86c06d65cae7f8d21ee49d9b959df6d1eb6fccd4 [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"
22 "github.com/donNewtonAlpha/goloxi"
23 ofp "github.com/donNewtonAlpha/goloxi/of13"
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -080024 "github.com/opencord/voltha-lib-go/v3/pkg/log"
25 "github.com/opencord/voltha-protos/v3/go/common"
26 "github.com/opencord/voltha-protos/v3/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080027 "net"
28 "unsafe"
29)
30
Jonathan Hart4b110f62020-03-13 17:36:19 -070031func (ofc *OFConnection) handleStatsRequest(request ofp.IHeader, statType uint16) error {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080032 if logger.V(log.DebugLevel) {
33 js, _ := json.Marshal(request)
34 logger.Debugw("handleStatsRequest called",
35 log.Fields{
36 "device-id": ofc.DeviceID,
37 "stat-type": statType,
38 "request": js})
39 }
40
41 switch statType {
42 case ofp.OFPSTDesc:
43 statsReq := request.(*ofp.DescStatsRequest)
44 response, err := ofc.handleDescStatsRequest(statsReq)
45 if err != nil {
46 return err
47 }
48 if logger.V(log.DebugLevel) {
49 reqJs, _ := json.Marshal(statsReq)
50 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080051 logger.Debugw("handle-stats-request-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080052 log.Fields{
53 "device-id": ofc.DeviceID,
54 "request": reqJs,
55 "response": resJs})
56 }
57 return ofc.SendMessage(response)
58 case ofp.OFPSTFlow:
59 statsReq := request.(*ofp.FlowStatsRequest)
60 response, err := ofc.handleFlowStatsRequest(statsReq)
61 if err != nil {
62 return err
63 }
64 response.Length = uint16(unsafe.Sizeof(*response))
65 if logger.V(log.DebugLevel) {
66 reqJs, _ := json.Marshal(statsReq)
67 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080068 logger.Debugw("handle-stats-request-flow",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080069 log.Fields{
Don Newton7fe70f72020-02-21 13:54:11 -050070 "device-id": ofc.DeviceID,
71 "request": reqJs,
72 "response-object": response,
73 "response": resJs})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080074 }
75 return ofc.SendMessage(response)
76
77 case ofp.OFPSTAggregate:
78 statsReq := request.(*ofp.AggregateStatsRequest)
79 response, err := ofc.handleAggregateStatsRequest(statsReq)
80 if err != nil {
81 return err
82 }
83 if logger.V(log.DebugLevel) {
84 reqJs, _ := json.Marshal(statsReq)
85 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080086 logger.Debugw("handle-stats-request-aggregate",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080087 log.Fields{
88 "device-id": ofc.DeviceID,
89 "request": reqJs,
90 "response": resJs})
91 }
92 return ofc.SendMessage(response)
93 case ofp.OFPSTTable:
94 statsReq := request.(*ofp.TableStatsRequest)
95 response, e := ofc.handleTableStatsRequest(statsReq)
96 if logger.V(log.DebugLevel) {
97 reqJs, _ := json.Marshal(statsReq)
98 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080099 logger.Debugw("handle-stats-request-table",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800100 log.Fields{
101 "device-id": ofc.DeviceID,
102 "request": reqJs,
103 "response": resJs})
104 }
105 if e != nil {
106 return e
107 }
108 return ofc.SendMessage(response)
109 case ofp.OFPSTPort:
110 statsReq := request.(*ofp.PortStatsRequest)
111 response, err := ofc.handlePortStatsRequest(statsReq)
112 if err != nil {
113 return err
114 }
115 if logger.V(log.DebugLevel) {
116 reqJs, _ := json.Marshal(statsReq)
117 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800118 logger.Debugw("handle-stats-request-port",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800119 log.Fields{
120 "device-id": ofc.DeviceID,
121 "request": reqJs,
122 "response": resJs})
123 }
124 return ofc.SendMessage(response)
125 case ofp.OFPSTQueue:
126 statsReq := request.(*ofp.QueueStatsRequest)
127 response, err := ofc.handleQueueStatsRequest(statsReq)
128 if err != nil {
129 return err
130 }
131 if logger.V(log.DebugLevel) {
132 reqJs, _ := json.Marshal(statsReq)
133 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800134 logger.Debugw("handle-stats-request-queue",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800135 log.Fields{
136 "device-id": ofc.DeviceID,
137 "request": reqJs,
138 "response": resJs})
139 }
140 return ofc.SendMessage(response)
141 case ofp.OFPSTGroup:
142 statsReq := request.(*ofp.GroupStatsRequest)
143 response, err := ofc.handleGroupStatsRequest(statsReq)
144 if err != nil {
145 return err
146 }
147 if logger.V(log.DebugLevel) {
148 reqJs, _ := json.Marshal(statsReq)
149 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800150 logger.Debugw("handle-stats-request-group",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800151 log.Fields{
152 "device-id": ofc.DeviceID,
153 "request": reqJs,
154 "response": resJs})
155 }
David K. Bainbridgecac73ac2020-02-19 07:00:12 -0800156 return ofc.SendMessage(response)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800157 case ofp.OFPSTGroupDesc:
158 statsReq := request.(*ofp.GroupDescStatsRequest)
159 response, err := ofc.handleGroupStatsDescRequest(statsReq)
160 if err != nil {
161 return err
162 }
163 if logger.V(log.DebugLevel) {
164 reqJs, _ := json.Marshal(statsReq)
165 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800166 logger.Debugw("handle-stats-request-group-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800167 log.Fields{
168 "device-id": ofc.DeviceID,
169 "request": reqJs,
170 "response": resJs})
171 }
172 return ofc.SendMessage(response)
173
174 case ofp.OFPSTGroupFeatures:
175 statsReq := request.(*ofp.GroupFeaturesStatsRequest)
176 response, err := ofc.handleGroupFeatureStatsRequest(statsReq)
177 if err != nil {
178 return err
179 }
180 if logger.V(log.DebugLevel) {
181 reqJs, _ := json.Marshal(statsReq)
182 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800183 logger.Debugw("handle-stats-request-group-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800184 log.Fields{
185 "device-id": ofc.DeviceID,
186 "request": reqJs,
187 "response": resJs})
188 }
189 return ofc.SendMessage(response)
190 case ofp.OFPSTMeter:
191 statsReq := request.(*ofp.MeterStatsRequest)
192 response, err := ofc.handleMeterStatsRequest(statsReq)
193 if err != nil {
194 return err
195 }
196 if logger.V(log.DebugLevel) {
197 reqJs, _ := json.Marshal(statsReq)
198 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800199 logger.Debugw("handle-stats-request-meter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800200 log.Fields{
201 "device-id": ofc.DeviceID,
202 "request": reqJs,
203 "response": resJs})
204 }
205 return ofc.SendMessage(response)
206 case ofp.OFPSTMeterConfig:
207 statsReq := request.(*ofp.MeterConfigStatsRequest)
208 response, err := ofc.handleMeterConfigStatsRequest(statsReq)
209 if err != nil {
210 return err
211 }
212 if logger.V(log.DebugLevel) {
213 reqJs, _ := json.Marshal(statsReq)
214 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800215 logger.Debugw("handle-stats-request-meter-config",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800216 log.Fields{
217 "device-id": ofc.DeviceID,
218 "request": reqJs,
219 "response": resJs})
220 }
221 return ofc.SendMessage(response)
222 case ofp.OFPSTMeterFeatures:
223 statsReq := request.(*ofp.MeterFeaturesStatsRequest)
224 response, err := ofc.handleMeterFeatureStatsRequest(statsReq)
225 if err != nil {
226 return err
227 }
228 if logger.V(log.DebugLevel) {
229 reqJs, _ := json.Marshal(statsReq)
230 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800231 logger.Debugw("handle-stats-request-meter-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800232 log.Fields{
233 "device-id": ofc.DeviceID,
234 "request": reqJs,
235 "response": resJs})
236 }
237 return ofc.SendMessage(response)
238 case ofp.OFPSTTableFeatures:
239 statsReq := request.(*ofp.TableFeaturesStatsRequest)
240 response, err := ofc.handleTableFeaturesStatsRequest(statsReq)
241 if err != nil {
242 return err
243 }
244 if logger.V(log.DebugLevel) {
245 reqJs, _ := json.Marshal(statsReq)
246 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800247 logger.Debugw("handle-stats-request-table-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800248 log.Fields{
249 "device-id": ofc.DeviceID,
250 "request": reqJs,
251 "response": resJs})
252 }
253 return ofc.SendMessage(response)
254 case ofp.OFPSTPortDesc:
255 statsReq := request.(*ofp.PortDescStatsRequest)
256 response, err := ofc.handlePortDescStatsRequest(statsReq)
257 if err != nil {
258 return err
259 }
260 if logger.V(log.DebugLevel) {
261 reqJs, _ := json.Marshal(statsReq)
262 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800263 logger.Debugw("handle-stats-request-port-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800264 log.Fields{
265 "device-id": ofc.DeviceID,
266 "request": reqJs,
267 "response": resJs})
268 }
269 return ofc.SendMessage(response)
270
271 case ofp.OFPSTExperimenter:
272 statsReq := request.(*ofp.ExperimenterStatsRequest)
273 response, err := ofc.handleExperimenterStatsRequest(statsReq)
274 if err != nil {
275 return err
276 }
277 if logger.V(log.DebugLevel) {
278 reqJs, _ := json.Marshal(statsReq)
279 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800280 logger.Debugw("handle-stats-request-experimenter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800281 log.Fields{
282 "device-id": ofc.DeviceID,
283 "request": reqJs,
284 "response": resJs})
285 }
286 return ofc.SendMessage(response)
287 }
288 return nil
289}
290
Jonathan Hart4b110f62020-03-13 17:36:19 -0700291func (ofc *OFConnection) handleDescStatsRequest(request *ofp.DescStatsRequest) (*ofp.DescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800292 if ofc.VolthaClient == nil {
293 return nil, NoVolthaConnectionError
294 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800295 response := ofp.NewDescStatsReply()
296 response.SetXid(request.GetXid())
297 response.SetVersion(request.GetVersion())
298 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
299
300 resp, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
301 &common.ID{Id: ofc.DeviceID})
302 if err != nil {
303 return nil, err
304 }
305 desc := resp.GetDesc()
306
307 response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256))
308 response.SetHwDesc(PadString(desc.GetHwDesc(), 256))
309 response.SetSwDesc(PadString(desc.GetSwDesc(), 256))
310 response.SetSerialNum(PadString(desc.GetSerialNum(), 32))
311 response.SetDpDesc(PadString(desc.GetDpDesc(), 256))
312 return response, nil
313}
314
Jonathan Hart4b110f62020-03-13 17:36:19 -0700315func (ofc *OFConnection) handleFlowStatsRequest(request *ofp.FlowStatsRequest) (*ofp.FlowStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800316 if ofc.VolthaClient == nil {
317 return nil, NoVolthaConnectionError
318 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800319 response := ofp.NewFlowStatsReply()
320 response.SetXid(request.GetXid())
321 response.SetVersion(4)
322 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
323 resp, err := ofc.VolthaClient.ListLogicalDeviceFlows(context.Background(),
324 &common.ID{Id: ofc.DeviceID})
325 if err != nil {
326 return nil, err
327 }
328 var flow []*ofp.FlowStatsEntry
329 for _, item := range resp.GetItems() {
330 entry := ofp.NewFlowStatsEntry()
331 entry.SetTableId(uint8(item.GetTableId()))
332 entry.SetDurationSec(item.GetDurationSec())
333 entry.SetDurationNsec(item.GetDurationNsec())
334 entry.SetPriority(uint16(item.GetPriority()))
335 entry.SetIdleTimeout(uint16(item.GetIdleTimeout()))
336 entry.SetHardTimeout(uint16(item.GetHardTimeout()))
337 entry.SetFlags(ofp.FlowModFlags(item.GetFlags()))
338 entry.SetCookie(item.GetCookie())
339 entry.SetPacketCount(item.GetPacketCount())
340 entry.SetByteCount(item.GetByteCount())
341 entrySize := uint16(48)
342 match := ofp.NewMatchV3()
343 pbMatch := item.GetMatch()
344 match.SetType(uint16(pbMatch.GetType()))
345 size := uint16(4)
346 var fields []goloxi.IOxm
347 for _, oxmField := range pbMatch.GetOxmFields() {
348 field := oxmField.GetField()
349 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
350 iOxm, oxmSize := parseOxm(ofbField, ofc.DeviceID)
351 fields = append(fields, iOxm)
352 if oxmSize > 0 {
353 size += 4 //header for oxm
354 }
355 size += oxmSize
356 }
357
358 match.OxmList = fields
359 match.Length = uint16(size)
360 //account for 8 byte alignment
361 if size%8 != 0 {
362 size = ((size / 8) + 1) * 8
363 }
364 entrySize += size
365 entry.SetMatch(*match)
366 var instructions []ofp.IInstruction
367 for _, ofpInstruction := range item.Instructions {
368 instruction, size := parseInstructions(ofpInstruction, ofc.DeviceID)
369 instructions = append(instructions, instruction)
370 entrySize += size
371 }
372 entry.Instructions = instructions
373 entry.Length = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800374 flow = append(flow, entry)
375 }
376 response.SetEntries(flow)
377 return response, nil
378}
379
Jonathan Hart4b110f62020-03-13 17:36:19 -0700380func (ofc *OFConnection) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800381 response := ofp.NewAggregateStatsReply()
382 response.SetVersion(request.GetVersion())
383 response.SetXid(request.GetXid())
384 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
385 response.SetFlowCount(0)
386 //TODO wire this to voltha core when it implements
387 return response, nil
388}
389
Jonathan Hart4b110f62020-03-13 17:36:19 -0700390func (ofc *OFConnection) handleGroupStatsRequest(request *ofp.GroupStatsRequest) (*ofp.GroupStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800391 if ofc.VolthaClient == nil {
392 return nil, NoVolthaConnectionError
393 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800394 response := ofp.NewGroupStatsReply()
395 response.SetVersion(request.GetVersion())
396 response.SetXid(request.GetXid())
397 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
398 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
399 &common.ID{Id: ofc.DeviceID})
400 if err != nil {
401 return nil, err
402 }
403
404 var groupStatsEntries []*ofp.GroupStatsEntry
405 for _, item := range reply.GetItems() {
406 stats := item.GetStats()
407 var entry ofp.GroupStatsEntry
408 entry.SetByteCount(stats.GetByteCount())
409 entry.SetPacketCount(stats.GetPacketCount())
410 entry.SetDurationNsec(stats.GetDurationNsec())
411 entry.SetDurationSec(stats.GetDurationSec())
412 entry.SetRefCount(stats.GetRefCount())
413 entry.SetGroupId(stats.GetGroupId())
414 var bucketStatsList []*ofp.BucketCounter
415 for _, bucketStat := range stats.GetBucketStats() {
416 bucketCounter := ofp.BucketCounter{}
417 bucketCounter.SetPacketCount(bucketStat.GetPacketCount())
418 bucketCounter.SetByteCount(bucketStat.GetByteCount())
419 bucketStatsList = append(bucketStatsList, &bucketCounter)
420 }
421 entry.SetBucketStats(bucketStatsList)
422 groupStatsEntries = append(groupStatsEntries, &entry)
423 }
424 response.SetEntries(groupStatsEntries)
425 return response, nil
426}
427
Jonathan Hart4b110f62020-03-13 17:36:19 -0700428func (ofc *OFConnection) handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest) (*ofp.GroupDescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800429 if ofc.VolthaClient == nil {
430 return nil, NoVolthaConnectionError
431 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800432 response := ofp.NewGroupDescStatsReply()
433 response.SetVersion(request.GetVersion())
434 response.SetXid(request.GetXid())
435 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
436 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
437 &common.ID{Id: ofc.DeviceID})
438 if err != nil {
439 return nil, err
440 }
441 var groupDescStatsEntries []*ofp.GroupDescStatsEntry
442 for _, item := range reply.GetItems() {
443 stats := item.GetStats()
444 var groupDesc ofp.GroupDescStatsEntry
445 groupDesc.SetGroupId(stats.GetGroupId())
446 /*
447 buckets := item.g
448 var bucketList []*ofp.Bucket
449 for j:=0;j<len(buckets);j++{
450
451 }
452
453 groupDesc.SetBuckets(bucketList)
454 */
455 groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc)
456 }
457 response.SetEntries(groupDescStatsEntries)
458 return response, nil
459}
460
Jonathan Hart4b110f62020-03-13 17:36:19 -0700461func (ofc *OFConnection) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800462 response := ofp.NewGroupFeaturesStatsReply()
463 response.SetVersion(request.GetVersion())
464 response.SetXid(request.GetXid())
465 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
466 //TODO wire this to voltha core when it implements
467 return response, nil
468}
469
Jonathan Hart4b110f62020-03-13 17:36:19 -0700470func (ofc *OFConnection) handleMeterStatsRequest(request *ofp.MeterStatsRequest) (*ofp.MeterStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800471 if ofc.VolthaClient == nil {
472 return nil, NoVolthaConnectionError
473 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800474 response := ofp.NewMeterStatsReply()
475 response.SetVersion(request.GetVersion())
476 response.SetXid(request.GetXid())
477 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
478 resp, err := ofc.VolthaClient.ListLogicalDeviceMeters(context.Background(),
479 &common.ID{Id: ofc.DeviceID})
480 if err != nil {
481 return nil, err
482 }
David K. Bainbridge55376262020-01-22 23:28:27 -0800483 size := uint16(5) // size of stats header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800484 var meterStats []*ofp.MeterStats
485 for _, item := range resp.Items {
David K. Bainbridge55376262020-01-22 23:28:27 -0800486 entrySize := uint16(40) // size of entry header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800487 meterStat := ofp.NewMeterStats()
488 stats := item.Stats
489 meterStat.DurationNsec = stats.DurationNsec
490 meterStat.DurationSec = stats.DurationSec
491 meterStat.ByteInCount = stats.ByteInCount
492 meterStat.FlowCount = stats.FlowCount
493 meterStat.MeterId = stats.MeterId
494 var bandStats []*ofp.MeterBandStats
495 for _, bStat := range stats.BandStats {
496 bandStat := ofp.NewMeterBandStats()
497 bandStat.ByteBandCount = bStat.ByteBandCount
498 bandStat.PacketBandCount = bStat.PacketBandCount
499 bandStats = append(bandStats, bandStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800500 entrySize += uint16(16) // size of each band stat
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800501 }
502 meterStat.SetBandStats(bandStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800503 meterStat.Len = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800504 meterStats = append(meterStats, meterStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800505 size += entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800506 }
507 response.SetEntries(meterStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800508 response.SetLength(size)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800509 return response, nil
510}
511
Jonathan Hart4b110f62020-03-13 17:36:19 -0700512func (ofc *OFConnection) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800513 response := ofp.NewMeterConfigStatsReply()
514 response.SetVersion(request.GetVersion())
515 response.SetXid(request.GetXid())
516 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
517 //TODO wire this to voltha core when it implements
518 return response, nil
519}
520
Jonathan Hart4b110f62020-03-13 17:36:19 -0700521func (ofc *OFConnection) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800522 response := ofp.NewTableFeaturesStatsReply()
523 response.SetVersion(request.GetVersion())
524 response.SetXid(request.GetXid())
525 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
526 //TODO wire this to voltha core when it implements
527 return response, nil
528}
529
Jonathan Hart4b110f62020-03-13 17:36:19 -0700530func (ofc *OFConnection) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800531 var response = ofp.NewTableStatsReply()
532 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
533 response.SetVersion(request.GetVersion())
534 response.SetXid(request.GetXid())
535 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
536 return response, nil
537}
538
Jonathan Hart4b110f62020-03-13 17:36:19 -0700539func (ofc *OFConnection) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800540 response := ofp.NewQueueStatsReply()
541 response.SetVersion(request.GetVersion())
542 response.SetXid(request.GetXid())
543 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
544 //TODO wire this to voltha core when it implements
545 return response, nil
546}
547
Jonathan Hart4b110f62020-03-13 17:36:19 -0700548func (ofc *OFConnection) handlePortStatsRequest(request *ofp.PortStatsRequest) (*ofp.PortStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800549 if ofc.VolthaClient == nil {
550 return nil, NoVolthaConnectionError
551 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800552 response := ofp.NewPortStatsReply()
553 response.SetXid(request.GetXid())
554 response.SetVersion(request.GetVersion())
555 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
556 reply, err := ofc.VolthaClient.ListLogicalDevicePorts(context.Background(),
557 &common.ID{Id: ofc.DeviceID})
558 if err != nil {
559 return nil, err
560 }
561 var entries []*ofp.PortStatsEntry
562 if request.GetPortNo() == 0xffffffff { //all ports
563 for _, port := range reply.GetItems() {
564 entries = append(entries, parsePortStats(port))
565 }
566 } else { //find right port that is requested
567 for _, port := range reply.GetItems() {
568 if port.GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
569 entries = append(entries, parsePortStats(port))
570 }
571 }
572 }
573 response.SetEntries(entries)
574 return response, nil
575}
576
Jonathan Hart4b110f62020-03-13 17:36:19 -0700577func (ofc *OFConnection) handlePortDescStatsRequest(request *ofp.PortDescStatsRequest) (*ofp.PortDescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800578 if ofc.VolthaClient == nil {
579 return nil, NoVolthaConnectionError
580 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800581 response := ofp.NewPortDescStatsReply()
582 response.SetVersion(request.GetVersion())
583 response.SetXid(request.GetXid())
584 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
585 logicalDevice, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
586 &common.ID{Id: ofc.DeviceID})
587 if err != nil {
588 return nil, err
589 }
590 var entries []*ofp.PortDesc
591 for _, port := range logicalDevice.GetPorts() {
592 ofpPort := port.GetOfpPort()
593 var entry ofp.PortDesc
594 entry.SetPortNo(ofp.Port(ofpPort.GetPortNo()))
595
596 var octets []byte
597 for _, val := range ofpPort.GetHwAddr() {
598 octets = append(octets, byte(val))
599 }
600 hwAddr := net.HardwareAddr(octets)
601 entry.SetHwAddr(hwAddr)
602 entry.SetName(PadString(ofpPort.GetName(), 16))
603 entry.SetConfig(ofp.PortConfig(ofpPort.GetConfig()))
604 entry.SetState(ofp.PortState(ofpPort.GetState()))
605 entry.SetCurr(ofp.PortFeatures(ofpPort.GetCurr()))
606 entry.SetAdvertised(ofp.PortFeatures(ofpPort.GetAdvertised()))
607 entry.SetSupported(ofp.PortFeatures(ofpPort.GetSupported()))
608 entry.SetPeer(ofp.PortFeatures(ofpPort.GetPeer()))
609 entry.SetCurrSpeed(ofpPort.GetCurrSpeed())
610 entry.SetMaxSpeed(ofpPort.GetMaxSpeed())
611
612 entries = append(entries, &entry)
613 }
614
615 response.SetEntries(entries)
616 //TODO call voltha and get port descriptions etc
617 return response, nil
618
619}
620
Jonathan Hart4b110f62020-03-13 17:36:19 -0700621func (ofc *OFConnection) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800622 response := ofp.NewMeterFeaturesStatsReply()
623 response.SetXid(request.GetXid())
624 response.SetVersion(request.GetVersion())
625 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
626 meterFeatures := ofp.NewMeterFeatures()
627 meterFeatures.Capabilities = ofp.OFPMFKbps
628 meterFeatures.BandTypes = ofp.OFPMBTDrop
629 meterFeatures.MaxMeter = 0xffffffff
630 meterFeatures.MaxBands = 0xff
631 meterFeatures.MaxColor = 0xff
632 response.Features = *meterFeatures
633 return response, nil
634}
635
Jonathan Hart4b110f62020-03-13 17:36:19 -0700636func (ofc *OFConnection) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800637 response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
638 response.SetVersion(request.GetVersion())
639 response.SetXid(request.GetXid())
640 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
641 //TODO wire this to voltha core when it implements
642 return response, nil
643}