blob: 97d389b51adead78667d67907998bc661356c259 [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
31func (ofc *OFClient) handleStatsRequest(request ofp.IHeader, statType uint16) error {
32 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{
70 "device-id": ofc.DeviceID,
71 "request": reqJs,
72 "response": resJs})
73 }
74 return ofc.SendMessage(response)
75
76 case ofp.OFPSTAggregate:
77 statsReq := request.(*ofp.AggregateStatsRequest)
78 response, err := ofc.handleAggregateStatsRequest(statsReq)
79 if err != nil {
80 return err
81 }
82 if logger.V(log.DebugLevel) {
83 reqJs, _ := json.Marshal(statsReq)
84 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080085 logger.Debugw("handle-stats-request-aggregate",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080086 log.Fields{
87 "device-id": ofc.DeviceID,
88 "request": reqJs,
89 "response": resJs})
90 }
91 return ofc.SendMessage(response)
92 case ofp.OFPSTTable:
93 statsReq := request.(*ofp.TableStatsRequest)
94 response, e := ofc.handleTableStatsRequest(statsReq)
95 if logger.V(log.DebugLevel) {
96 reqJs, _ := json.Marshal(statsReq)
97 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080098 logger.Debugw("handle-stats-request-table",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080099 log.Fields{
100 "device-id": ofc.DeviceID,
101 "request": reqJs,
102 "response": resJs})
103 }
104 if e != nil {
105 return e
106 }
107 return ofc.SendMessage(response)
108 case ofp.OFPSTPort:
109 statsReq := request.(*ofp.PortStatsRequest)
110 response, err := ofc.handlePortStatsRequest(statsReq)
111 if err != nil {
112 return err
113 }
114 if logger.V(log.DebugLevel) {
115 reqJs, _ := json.Marshal(statsReq)
116 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800117 logger.Debugw("handle-stats-request-port",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800118 log.Fields{
119 "device-id": ofc.DeviceID,
120 "request": reqJs,
121 "response": resJs})
122 }
123 return ofc.SendMessage(response)
124 case ofp.OFPSTQueue:
125 statsReq := request.(*ofp.QueueStatsRequest)
126 response, err := ofc.handleQueueStatsRequest(statsReq)
127 if err != nil {
128 return err
129 }
130 if logger.V(log.DebugLevel) {
131 reqJs, _ := json.Marshal(statsReq)
132 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800133 logger.Debugw("handle-stats-request-queue",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800134 log.Fields{
135 "device-id": ofc.DeviceID,
136 "request": reqJs,
137 "response": resJs})
138 }
139 return ofc.SendMessage(response)
140 case ofp.OFPSTGroup:
141 statsReq := request.(*ofp.GroupStatsRequest)
142 response, err := ofc.handleGroupStatsRequest(statsReq)
143 if err != nil {
144 return err
145 }
146 if logger.V(log.DebugLevel) {
147 reqJs, _ := json.Marshal(statsReq)
148 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800149 logger.Debugw("handle-stats-request-group",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800150 log.Fields{
151 "device-id": ofc.DeviceID,
152 "request": reqJs,
153 "response": resJs})
154 }
155 ofc.SendMessage(response)
156 case ofp.OFPSTGroupDesc:
157 statsReq := request.(*ofp.GroupDescStatsRequest)
158 response, err := ofc.handleGroupStatsDescRequest(statsReq)
159 if err != nil {
160 return err
161 }
162 if logger.V(log.DebugLevel) {
163 reqJs, _ := json.Marshal(statsReq)
164 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800165 logger.Debugw("handle-stats-request-group-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800166 log.Fields{
167 "device-id": ofc.DeviceID,
168 "request": reqJs,
169 "response": resJs})
170 }
171 return ofc.SendMessage(response)
172
173 case ofp.OFPSTGroupFeatures:
174 statsReq := request.(*ofp.GroupFeaturesStatsRequest)
175 response, err := ofc.handleGroupFeatureStatsRequest(statsReq)
176 if err != nil {
177 return err
178 }
179 if logger.V(log.DebugLevel) {
180 reqJs, _ := json.Marshal(statsReq)
181 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800182 logger.Debugw("handle-stats-request-group-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800183 log.Fields{
184 "device-id": ofc.DeviceID,
185 "request": reqJs,
186 "response": resJs})
187 }
188 return ofc.SendMessage(response)
189 case ofp.OFPSTMeter:
190 statsReq := request.(*ofp.MeterStatsRequest)
191 response, err := ofc.handleMeterStatsRequest(statsReq)
192 if err != nil {
193 return err
194 }
195 if logger.V(log.DebugLevel) {
196 reqJs, _ := json.Marshal(statsReq)
197 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800198 logger.Debugw("handle-stats-request-meter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800199 log.Fields{
200 "device-id": ofc.DeviceID,
201 "request": reqJs,
202 "response": resJs})
203 }
204 return ofc.SendMessage(response)
205 case ofp.OFPSTMeterConfig:
206 statsReq := request.(*ofp.MeterConfigStatsRequest)
207 response, err := ofc.handleMeterConfigStatsRequest(statsReq)
208 if err != nil {
209 return err
210 }
211 if logger.V(log.DebugLevel) {
212 reqJs, _ := json.Marshal(statsReq)
213 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800214 logger.Debugw("handle-stats-request-meter-config",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800215 log.Fields{
216 "device-id": ofc.DeviceID,
217 "request": reqJs,
218 "response": resJs})
219 }
220 return ofc.SendMessage(response)
221 case ofp.OFPSTMeterFeatures:
222 statsReq := request.(*ofp.MeterFeaturesStatsRequest)
223 response, err := ofc.handleMeterFeatureStatsRequest(statsReq)
224 if err != nil {
225 return err
226 }
227 if logger.V(log.DebugLevel) {
228 reqJs, _ := json.Marshal(statsReq)
229 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800230 logger.Debugw("handle-stats-request-meter-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800231 log.Fields{
232 "device-id": ofc.DeviceID,
233 "request": reqJs,
234 "response": resJs})
235 }
236 return ofc.SendMessage(response)
237 case ofp.OFPSTTableFeatures:
238 statsReq := request.(*ofp.TableFeaturesStatsRequest)
239 response, err := ofc.handleTableFeaturesStatsRequest(statsReq)
240 if err != nil {
241 return err
242 }
243 if logger.V(log.DebugLevel) {
244 reqJs, _ := json.Marshal(statsReq)
245 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800246 logger.Debugw("handle-stats-request-table-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800247 log.Fields{
248 "device-id": ofc.DeviceID,
249 "request": reqJs,
250 "response": resJs})
251 }
252 return ofc.SendMessage(response)
253 case ofp.OFPSTPortDesc:
254 statsReq := request.(*ofp.PortDescStatsRequest)
255 response, err := ofc.handlePortDescStatsRequest(statsReq)
256 if err != nil {
257 return err
258 }
259 if logger.V(log.DebugLevel) {
260 reqJs, _ := json.Marshal(statsReq)
261 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800262 logger.Debugw("handle-stats-request-port-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800263 log.Fields{
264 "device-id": ofc.DeviceID,
265 "request": reqJs,
266 "response": resJs})
267 }
268 return ofc.SendMessage(response)
269
270 case ofp.OFPSTExperimenter:
271 statsReq := request.(*ofp.ExperimenterStatsRequest)
272 response, err := ofc.handleExperimenterStatsRequest(statsReq)
273 if err != nil {
274 return err
275 }
276 if logger.V(log.DebugLevel) {
277 reqJs, _ := json.Marshal(statsReq)
278 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800279 logger.Debugw("handle-stats-request-experimenter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800280 log.Fields{
281 "device-id": ofc.DeviceID,
282 "request": reqJs,
283 "response": resJs})
284 }
285 return ofc.SendMessage(response)
286 }
287 return nil
288}
289
290func (ofc *OFClient) handleDescStatsRequest(request *ofp.DescStatsRequest) (*ofp.DescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800291 if ofc.VolthaClient == nil {
292 return nil, NoVolthaConnectionError
293 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800294 response := ofp.NewDescStatsReply()
295 response.SetXid(request.GetXid())
296 response.SetVersion(request.GetVersion())
297 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
298
299 resp, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
300 &common.ID{Id: ofc.DeviceID})
301 if err != nil {
302 return nil, err
303 }
304 desc := resp.GetDesc()
305
306 response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256))
307 response.SetHwDesc(PadString(desc.GetHwDesc(), 256))
308 response.SetSwDesc(PadString(desc.GetSwDesc(), 256))
309 response.SetSerialNum(PadString(desc.GetSerialNum(), 32))
310 response.SetDpDesc(PadString(desc.GetDpDesc(), 256))
311 return response, nil
312}
313
314func (ofc *OFClient) handleFlowStatsRequest(request *ofp.FlowStatsRequest) (*ofp.FlowStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800315 if ofc.VolthaClient == nil {
316 return nil, NoVolthaConnectionError
317 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800318 response := ofp.NewFlowStatsReply()
319 response.SetXid(request.GetXid())
320 response.SetVersion(4)
321 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
322 resp, err := ofc.VolthaClient.ListLogicalDeviceFlows(context.Background(),
323 &common.ID{Id: ofc.DeviceID})
324 if err != nil {
325 return nil, err
326 }
327 var flow []*ofp.FlowStatsEntry
328 for _, item := range resp.GetItems() {
329 entry := ofp.NewFlowStatsEntry()
330 entry.SetTableId(uint8(item.GetTableId()))
331 entry.SetDurationSec(item.GetDurationSec())
332 entry.SetDurationNsec(item.GetDurationNsec())
333 entry.SetPriority(uint16(item.GetPriority()))
334 entry.SetIdleTimeout(uint16(item.GetIdleTimeout()))
335 entry.SetHardTimeout(uint16(item.GetHardTimeout()))
336 entry.SetFlags(ofp.FlowModFlags(item.GetFlags()))
337 entry.SetCookie(item.GetCookie())
338 entry.SetPacketCount(item.GetPacketCount())
339 entry.SetByteCount(item.GetByteCount())
340 entrySize := uint16(48)
341 match := ofp.NewMatchV3()
342 pbMatch := item.GetMatch()
343 match.SetType(uint16(pbMatch.GetType()))
344 size := uint16(4)
345 var fields []goloxi.IOxm
346 for _, oxmField := range pbMatch.GetOxmFields() {
347 field := oxmField.GetField()
348 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
349 iOxm, oxmSize := parseOxm(ofbField, ofc.DeviceID)
350 fields = append(fields, iOxm)
351 if oxmSize > 0 {
352 size += 4 //header for oxm
353 }
354 size += oxmSize
355 }
356
357 match.OxmList = fields
358 match.Length = uint16(size)
359 //account for 8 byte alignment
360 if size%8 != 0 {
361 size = ((size / 8) + 1) * 8
362 }
363 entrySize += size
364 entry.SetMatch(*match)
365 var instructions []ofp.IInstruction
366 for _, ofpInstruction := range item.Instructions {
367 instruction, size := parseInstructions(ofpInstruction, ofc.DeviceID)
368 instructions = append(instructions, instruction)
369 entrySize += size
370 }
371 entry.Instructions = instructions
372 entry.Length = entrySize
373 entrySize = 0
374 flow = append(flow, entry)
375 }
376 response.SetEntries(flow)
377 return response, nil
378}
379
380func (ofc *OFClient) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
381 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
390func (ofc *OFClient) 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
428func (ofc *OFClient) 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
461func (ofc *OFClient) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
462 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
470func (ofc *OFClient) 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
512func (ofc *OFClient) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
513 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
521func (ofc *OFClient) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
522 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
530func (ofc *OFClient) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
531 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
539func (ofc *OFClient) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
540 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
548func (ofc *OFClient) 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
577func (ofc *OFClient) 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
621func (ofc *OFClient) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
622 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
636func (ofc *OFClient) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
637 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}