blob: 17db4480c49eef130d244fd7771bd9174fa67a2f [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"
24 "github.com/opencord/voltha-lib-go/v2/pkg/log"
25 "github.com/opencord/voltha-protos/v2/go/common"
26 "github.com/opencord/voltha-protos/v2/go/openflow_13"
27 "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) {
291 response := ofp.NewDescStatsReply()
292 response.SetXid(request.GetXid())
293 response.SetVersion(request.GetVersion())
294 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
295
296 resp, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
297 &common.ID{Id: ofc.DeviceID})
298 if err != nil {
299 return nil, err
300 }
301 desc := resp.GetDesc()
302
303 response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256))
304 response.SetHwDesc(PadString(desc.GetHwDesc(), 256))
305 response.SetSwDesc(PadString(desc.GetSwDesc(), 256))
306 response.SetSerialNum(PadString(desc.GetSerialNum(), 32))
307 response.SetDpDesc(PadString(desc.GetDpDesc(), 256))
308 return response, nil
309}
310
311func (ofc *OFClient) handleFlowStatsRequest(request *ofp.FlowStatsRequest) (*ofp.FlowStatsReply, error) {
312 response := ofp.NewFlowStatsReply()
313 response.SetXid(request.GetXid())
314 response.SetVersion(4)
315 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
316 resp, err := ofc.VolthaClient.ListLogicalDeviceFlows(context.Background(),
317 &common.ID{Id: ofc.DeviceID})
318 if err != nil {
319 return nil, err
320 }
321 var flow []*ofp.FlowStatsEntry
322 for _, item := range resp.GetItems() {
323 entry := ofp.NewFlowStatsEntry()
324 entry.SetTableId(uint8(item.GetTableId()))
325 entry.SetDurationSec(item.GetDurationSec())
326 entry.SetDurationNsec(item.GetDurationNsec())
327 entry.SetPriority(uint16(item.GetPriority()))
328 entry.SetIdleTimeout(uint16(item.GetIdleTimeout()))
329 entry.SetHardTimeout(uint16(item.GetHardTimeout()))
330 entry.SetFlags(ofp.FlowModFlags(item.GetFlags()))
331 entry.SetCookie(item.GetCookie())
332 entry.SetPacketCount(item.GetPacketCount())
333 entry.SetByteCount(item.GetByteCount())
334 entrySize := uint16(48)
335 match := ofp.NewMatchV3()
336 pbMatch := item.GetMatch()
337 match.SetType(uint16(pbMatch.GetType()))
338 size := uint16(4)
339 var fields []goloxi.IOxm
340 for _, oxmField := range pbMatch.GetOxmFields() {
341 field := oxmField.GetField()
342 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
343 iOxm, oxmSize := parseOxm(ofbField, ofc.DeviceID)
344 fields = append(fields, iOxm)
345 if oxmSize > 0 {
346 size += 4 //header for oxm
347 }
348 size += oxmSize
349 }
350
351 match.OxmList = fields
352 match.Length = uint16(size)
353 //account for 8 byte alignment
354 if size%8 != 0 {
355 size = ((size / 8) + 1) * 8
356 }
357 entrySize += size
358 entry.SetMatch(*match)
359 var instructions []ofp.IInstruction
360 for _, ofpInstruction := range item.Instructions {
361 instruction, size := parseInstructions(ofpInstruction, ofc.DeviceID)
362 instructions = append(instructions, instruction)
363 entrySize += size
364 }
365 entry.Instructions = instructions
366 entry.Length = entrySize
367 entrySize = 0
368 flow = append(flow, entry)
369 }
370 response.SetEntries(flow)
371 return response, nil
372}
373
374func (ofc *OFClient) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
375 response := ofp.NewAggregateStatsReply()
376 response.SetVersion(request.GetVersion())
377 response.SetXid(request.GetXid())
378 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
379 response.SetFlowCount(0)
380 //TODO wire this to voltha core when it implements
381 return response, nil
382}
383
384func (ofc *OFClient) handleGroupStatsRequest(request *ofp.GroupStatsRequest) (*ofp.GroupStatsReply, error) {
385 response := ofp.NewGroupStatsReply()
386 response.SetVersion(request.GetVersion())
387 response.SetXid(request.GetXid())
388 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
389 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
390 &common.ID{Id: ofc.DeviceID})
391 if err != nil {
392 return nil, err
393 }
394
395 var groupStatsEntries []*ofp.GroupStatsEntry
396 for _, item := range reply.GetItems() {
397 stats := item.GetStats()
398 var entry ofp.GroupStatsEntry
399 entry.SetByteCount(stats.GetByteCount())
400 entry.SetPacketCount(stats.GetPacketCount())
401 entry.SetDurationNsec(stats.GetDurationNsec())
402 entry.SetDurationSec(stats.GetDurationSec())
403 entry.SetRefCount(stats.GetRefCount())
404 entry.SetGroupId(stats.GetGroupId())
405 var bucketStatsList []*ofp.BucketCounter
406 for _, bucketStat := range stats.GetBucketStats() {
407 bucketCounter := ofp.BucketCounter{}
408 bucketCounter.SetPacketCount(bucketStat.GetPacketCount())
409 bucketCounter.SetByteCount(bucketStat.GetByteCount())
410 bucketStatsList = append(bucketStatsList, &bucketCounter)
411 }
412 entry.SetBucketStats(bucketStatsList)
413 groupStatsEntries = append(groupStatsEntries, &entry)
414 }
415 response.SetEntries(groupStatsEntries)
416 return response, nil
417}
418
419func (ofc *OFClient) handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest) (*ofp.GroupDescStatsReply, error) {
420 response := ofp.NewGroupDescStatsReply()
421 response.SetVersion(request.GetVersion())
422 response.SetXid(request.GetXid())
423 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
424 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
425 &common.ID{Id: ofc.DeviceID})
426 if err != nil {
427 return nil, err
428 }
429 var groupDescStatsEntries []*ofp.GroupDescStatsEntry
430 for _, item := range reply.GetItems() {
431 stats := item.GetStats()
432 var groupDesc ofp.GroupDescStatsEntry
433 groupDesc.SetGroupId(stats.GetGroupId())
434 /*
435 buckets := item.g
436 var bucketList []*ofp.Bucket
437 for j:=0;j<len(buckets);j++{
438
439 }
440
441 groupDesc.SetBuckets(bucketList)
442 */
443 groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc)
444 }
445 response.SetEntries(groupDescStatsEntries)
446 return response, nil
447}
448
449func (ofc *OFClient) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
450 response := ofp.NewGroupFeaturesStatsReply()
451 response.SetVersion(request.GetVersion())
452 response.SetXid(request.GetXid())
453 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
454 //TODO wire this to voltha core when it implements
455 return response, nil
456}
457
458func (ofc *OFClient) handleMeterStatsRequest(request *ofp.MeterStatsRequest) (*ofp.MeterStatsReply, error) {
459 response := ofp.NewMeterStatsReply()
460 response.SetVersion(request.GetVersion())
461 response.SetXid(request.GetXid())
462 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
463 resp, err := ofc.VolthaClient.ListLogicalDeviceMeters(context.Background(),
464 &common.ID{Id: ofc.DeviceID})
465 if err != nil {
466 return nil, err
467 }
David K. Bainbridge55376262020-01-22 23:28:27 -0800468 size := uint16(5) // size of stats header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800469 var meterStats []*ofp.MeterStats
470 for _, item := range resp.Items {
David K. Bainbridge55376262020-01-22 23:28:27 -0800471 entrySize := uint16(40) // size of entry header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800472 meterStat := ofp.NewMeterStats()
473 stats := item.Stats
474 meterStat.DurationNsec = stats.DurationNsec
475 meterStat.DurationSec = stats.DurationSec
476 meterStat.ByteInCount = stats.ByteInCount
477 meterStat.FlowCount = stats.FlowCount
478 meterStat.MeterId = stats.MeterId
479 var bandStats []*ofp.MeterBandStats
480 for _, bStat := range stats.BandStats {
481 bandStat := ofp.NewMeterBandStats()
482 bandStat.ByteBandCount = bStat.ByteBandCount
483 bandStat.PacketBandCount = bStat.PacketBandCount
484 bandStats = append(bandStats, bandStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800485 entrySize += uint16(16) // size of each band stat
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800486 }
487 meterStat.SetBandStats(bandStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800488 meterStat.Len = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800489 meterStats = append(meterStats, meterStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800490 size += entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800491 }
492 response.SetEntries(meterStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800493 response.SetLength(size)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800494 return response, nil
495}
496
497func (ofc *OFClient) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
498 response := ofp.NewMeterConfigStatsReply()
499 response.SetVersion(request.GetVersion())
500 response.SetXid(request.GetXid())
501 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
502 //TODO wire this to voltha core when it implements
503 return response, nil
504}
505
506func (ofc *OFClient) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
507 response := ofp.NewTableFeaturesStatsReply()
508 response.SetVersion(request.GetVersion())
509 response.SetXid(request.GetXid())
510 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
511 //TODO wire this to voltha core when it implements
512 return response, nil
513}
514
515func (ofc *OFClient) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
516 var response = ofp.NewTableStatsReply()
517 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
518 response.SetVersion(request.GetVersion())
519 response.SetXid(request.GetXid())
520 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
521 return response, nil
522}
523
524func (ofc *OFClient) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
525 response := ofp.NewQueueStatsReply()
526 response.SetVersion(request.GetVersion())
527 response.SetXid(request.GetXid())
528 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
529 //TODO wire this to voltha core when it implements
530 return response, nil
531}
532
533func (ofc *OFClient) handlePortStatsRequest(request *ofp.PortStatsRequest) (*ofp.PortStatsReply, error) {
534 response := ofp.NewPortStatsReply()
535 response.SetXid(request.GetXid())
536 response.SetVersion(request.GetVersion())
537 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
538 reply, err := ofc.VolthaClient.ListLogicalDevicePorts(context.Background(),
539 &common.ID{Id: ofc.DeviceID})
540 if err != nil {
541 return nil, err
542 }
543 var entries []*ofp.PortStatsEntry
544 if request.GetPortNo() == 0xffffffff { //all ports
545 for _, port := range reply.GetItems() {
546 entries = append(entries, parsePortStats(port))
547 }
548 } else { //find right port that is requested
549 for _, port := range reply.GetItems() {
550 if port.GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
551 entries = append(entries, parsePortStats(port))
552 }
553 }
554 }
555 response.SetEntries(entries)
556 return response, nil
557}
558
559func (ofc *OFClient) handlePortDescStatsRequest(request *ofp.PortDescStatsRequest) (*ofp.PortDescStatsReply, error) {
560 response := ofp.NewPortDescStatsReply()
561 response.SetVersion(request.GetVersion())
562 response.SetXid(request.GetXid())
563 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
564 logicalDevice, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
565 &common.ID{Id: ofc.DeviceID})
566 if err != nil {
567 return nil, err
568 }
569 var entries []*ofp.PortDesc
570 for _, port := range logicalDevice.GetPorts() {
571 ofpPort := port.GetOfpPort()
572 var entry ofp.PortDesc
573 entry.SetPortNo(ofp.Port(ofpPort.GetPortNo()))
574
575 var octets []byte
576 for _, val := range ofpPort.GetHwAddr() {
577 octets = append(octets, byte(val))
578 }
579 hwAddr := net.HardwareAddr(octets)
580 entry.SetHwAddr(hwAddr)
581 entry.SetName(PadString(ofpPort.GetName(), 16))
582 entry.SetConfig(ofp.PortConfig(ofpPort.GetConfig()))
583 entry.SetState(ofp.PortState(ofpPort.GetState()))
584 entry.SetCurr(ofp.PortFeatures(ofpPort.GetCurr()))
585 entry.SetAdvertised(ofp.PortFeatures(ofpPort.GetAdvertised()))
586 entry.SetSupported(ofp.PortFeatures(ofpPort.GetSupported()))
587 entry.SetPeer(ofp.PortFeatures(ofpPort.GetPeer()))
588 entry.SetCurrSpeed(ofpPort.GetCurrSpeed())
589 entry.SetMaxSpeed(ofpPort.GetMaxSpeed())
590
591 entries = append(entries, &entry)
592 }
593
594 response.SetEntries(entries)
595 //TODO call voltha and get port descriptions etc
596 return response, nil
597
598}
599
600func (ofc *OFClient) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
601 response := ofp.NewMeterFeaturesStatsReply()
602 response.SetXid(request.GetXid())
603 response.SetVersion(request.GetVersion())
604 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
605 meterFeatures := ofp.NewMeterFeatures()
606 meterFeatures.Capabilities = ofp.OFPMFKbps
607 meterFeatures.BandTypes = ofp.OFPMBTDrop
608 meterFeatures.MaxMeter = 0xffffffff
609 meterFeatures.MaxBands = 0xff
610 meterFeatures.MaxColor = 0xff
611 response.Features = *meterFeatures
612 return response, nil
613}
614
615func (ofc *OFClient) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
616 response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
617 response.SetVersion(request.GetVersion())
618 response.SetXid(request.GetXid())
619 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
620 //TODO wire this to voltha core when it implements
621 return response, nil
622}