blob: 613b476581fa30a2683590de0cfa2f7a796247d8 [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 }
David K. Bainbridgecac73ac2020-02-19 07:00:12 -0800155 return ofc.SendMessage(response)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800156 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
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800373 flow = append(flow, entry)
374 }
375 response.SetEntries(flow)
376 return response, nil
377}
378
379func (ofc *OFClient) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
380 response := ofp.NewAggregateStatsReply()
381 response.SetVersion(request.GetVersion())
382 response.SetXid(request.GetXid())
383 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
384 response.SetFlowCount(0)
385 //TODO wire this to voltha core when it implements
386 return response, nil
387}
388
389func (ofc *OFClient) handleGroupStatsRequest(request *ofp.GroupStatsRequest) (*ofp.GroupStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800390 if ofc.VolthaClient == nil {
391 return nil, NoVolthaConnectionError
392 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800393 response := ofp.NewGroupStatsReply()
394 response.SetVersion(request.GetVersion())
395 response.SetXid(request.GetXid())
396 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
397 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
398 &common.ID{Id: ofc.DeviceID})
399 if err != nil {
400 return nil, err
401 }
402
403 var groupStatsEntries []*ofp.GroupStatsEntry
404 for _, item := range reply.GetItems() {
405 stats := item.GetStats()
406 var entry ofp.GroupStatsEntry
407 entry.SetByteCount(stats.GetByteCount())
408 entry.SetPacketCount(stats.GetPacketCount())
409 entry.SetDurationNsec(stats.GetDurationNsec())
410 entry.SetDurationSec(stats.GetDurationSec())
411 entry.SetRefCount(stats.GetRefCount())
412 entry.SetGroupId(stats.GetGroupId())
413 var bucketStatsList []*ofp.BucketCounter
414 for _, bucketStat := range stats.GetBucketStats() {
415 bucketCounter := ofp.BucketCounter{}
416 bucketCounter.SetPacketCount(bucketStat.GetPacketCount())
417 bucketCounter.SetByteCount(bucketStat.GetByteCount())
418 bucketStatsList = append(bucketStatsList, &bucketCounter)
419 }
420 entry.SetBucketStats(bucketStatsList)
421 groupStatsEntries = append(groupStatsEntries, &entry)
422 }
423 response.SetEntries(groupStatsEntries)
424 return response, nil
425}
426
427func (ofc *OFClient) handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest) (*ofp.GroupDescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800428 if ofc.VolthaClient == nil {
429 return nil, NoVolthaConnectionError
430 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800431 response := ofp.NewGroupDescStatsReply()
432 response.SetVersion(request.GetVersion())
433 response.SetXid(request.GetXid())
434 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
435 reply, err := ofc.VolthaClient.ListLogicalDeviceFlowGroups(context.Background(),
436 &common.ID{Id: ofc.DeviceID})
437 if err != nil {
438 return nil, err
439 }
440 var groupDescStatsEntries []*ofp.GroupDescStatsEntry
441 for _, item := range reply.GetItems() {
442 stats := item.GetStats()
443 var groupDesc ofp.GroupDescStatsEntry
444 groupDesc.SetGroupId(stats.GetGroupId())
445 /*
446 buckets := item.g
447 var bucketList []*ofp.Bucket
448 for j:=0;j<len(buckets);j++{
449
450 }
451
452 groupDesc.SetBuckets(bucketList)
453 */
454 groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc)
455 }
456 response.SetEntries(groupDescStatsEntries)
457 return response, nil
458}
459
460func (ofc *OFClient) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
461 response := ofp.NewGroupFeaturesStatsReply()
462 response.SetVersion(request.GetVersion())
463 response.SetXid(request.GetXid())
464 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
465 //TODO wire this to voltha core when it implements
466 return response, nil
467}
468
469func (ofc *OFClient) handleMeterStatsRequest(request *ofp.MeterStatsRequest) (*ofp.MeterStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800470 if ofc.VolthaClient == nil {
471 return nil, NoVolthaConnectionError
472 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800473 response := ofp.NewMeterStatsReply()
474 response.SetVersion(request.GetVersion())
475 response.SetXid(request.GetXid())
476 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
477 resp, err := ofc.VolthaClient.ListLogicalDeviceMeters(context.Background(),
478 &common.ID{Id: ofc.DeviceID})
479 if err != nil {
480 return nil, err
481 }
David K. Bainbridge55376262020-01-22 23:28:27 -0800482 size := uint16(5) // size of stats header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800483 var meterStats []*ofp.MeterStats
484 for _, item := range resp.Items {
David K. Bainbridge55376262020-01-22 23:28:27 -0800485 entrySize := uint16(40) // size of entry header
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800486 meterStat := ofp.NewMeterStats()
487 stats := item.Stats
488 meterStat.DurationNsec = stats.DurationNsec
489 meterStat.DurationSec = stats.DurationSec
490 meterStat.ByteInCount = stats.ByteInCount
491 meterStat.FlowCount = stats.FlowCount
492 meterStat.MeterId = stats.MeterId
493 var bandStats []*ofp.MeterBandStats
494 for _, bStat := range stats.BandStats {
495 bandStat := ofp.NewMeterBandStats()
496 bandStat.ByteBandCount = bStat.ByteBandCount
497 bandStat.PacketBandCount = bStat.PacketBandCount
498 bandStats = append(bandStats, bandStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800499 entrySize += uint16(16) // size of each band stat
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800500 }
501 meterStat.SetBandStats(bandStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800502 meterStat.Len = entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800503 meterStats = append(meterStats, meterStat)
David K. Bainbridge55376262020-01-22 23:28:27 -0800504 size += entrySize
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800505 }
506 response.SetEntries(meterStats)
David K. Bainbridge55376262020-01-22 23:28:27 -0800507 response.SetLength(size)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800508 return response, nil
509}
510
511func (ofc *OFClient) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
512 response := ofp.NewMeterConfigStatsReply()
513 response.SetVersion(request.GetVersion())
514 response.SetXid(request.GetXid())
515 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
516 //TODO wire this to voltha core when it implements
517 return response, nil
518}
519
520func (ofc *OFClient) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
521 response := ofp.NewTableFeaturesStatsReply()
522 response.SetVersion(request.GetVersion())
523 response.SetXid(request.GetXid())
524 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
525 //TODO wire this to voltha core when it implements
526 return response, nil
527}
528
529func (ofc *OFClient) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
530 var response = ofp.NewTableStatsReply()
531 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
532 response.SetVersion(request.GetVersion())
533 response.SetXid(request.GetXid())
534 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
535 return response, nil
536}
537
538func (ofc *OFClient) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
539 response := ofp.NewQueueStatsReply()
540 response.SetVersion(request.GetVersion())
541 response.SetXid(request.GetXid())
542 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
543 //TODO wire this to voltha core when it implements
544 return response, nil
545}
546
547func (ofc *OFClient) handlePortStatsRequest(request *ofp.PortStatsRequest) (*ofp.PortStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800548 if ofc.VolthaClient == nil {
549 return nil, NoVolthaConnectionError
550 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800551 response := ofp.NewPortStatsReply()
552 response.SetXid(request.GetXid())
553 response.SetVersion(request.GetVersion())
554 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
555 reply, err := ofc.VolthaClient.ListLogicalDevicePorts(context.Background(),
556 &common.ID{Id: ofc.DeviceID})
557 if err != nil {
558 return nil, err
559 }
560 var entries []*ofp.PortStatsEntry
561 if request.GetPortNo() == 0xffffffff { //all ports
562 for _, port := range reply.GetItems() {
563 entries = append(entries, parsePortStats(port))
564 }
565 } else { //find right port that is requested
566 for _, port := range reply.GetItems() {
567 if port.GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
568 entries = append(entries, parsePortStats(port))
569 }
570 }
571 }
572 response.SetEntries(entries)
573 return response, nil
574}
575
576func (ofc *OFClient) handlePortDescStatsRequest(request *ofp.PortDescStatsRequest) (*ofp.PortDescStatsReply, error) {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800577 if ofc.VolthaClient == nil {
578 return nil, NoVolthaConnectionError
579 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800580 response := ofp.NewPortDescStatsReply()
581 response.SetVersion(request.GetVersion())
582 response.SetXid(request.GetXid())
583 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
584 logicalDevice, err := ofc.VolthaClient.GetLogicalDevice(context.Background(),
585 &common.ID{Id: ofc.DeviceID})
586 if err != nil {
587 return nil, err
588 }
589 var entries []*ofp.PortDesc
590 for _, port := range logicalDevice.GetPorts() {
591 ofpPort := port.GetOfpPort()
592 var entry ofp.PortDesc
593 entry.SetPortNo(ofp.Port(ofpPort.GetPortNo()))
594
595 var octets []byte
596 for _, val := range ofpPort.GetHwAddr() {
597 octets = append(octets, byte(val))
598 }
599 hwAddr := net.HardwareAddr(octets)
600 entry.SetHwAddr(hwAddr)
601 entry.SetName(PadString(ofpPort.GetName(), 16))
602 entry.SetConfig(ofp.PortConfig(ofpPort.GetConfig()))
603 entry.SetState(ofp.PortState(ofpPort.GetState()))
604 entry.SetCurr(ofp.PortFeatures(ofpPort.GetCurr()))
605 entry.SetAdvertised(ofp.PortFeatures(ofpPort.GetAdvertised()))
606 entry.SetSupported(ofp.PortFeatures(ofpPort.GetSupported()))
607 entry.SetPeer(ofp.PortFeatures(ofpPort.GetPeer()))
608 entry.SetCurrSpeed(ofpPort.GetCurrSpeed())
609 entry.SetMaxSpeed(ofpPort.GetMaxSpeed())
610
611 entries = append(entries, &entry)
612 }
613
614 response.SetEntries(entries)
615 //TODO call voltha and get port descriptions etc
616 return response, nil
617
618}
619
620func (ofc *OFClient) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
621 response := ofp.NewMeterFeaturesStatsReply()
622 response.SetXid(request.GetXid())
623 response.SetVersion(request.GetVersion())
624 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
625 meterFeatures := ofp.NewMeterFeatures()
626 meterFeatures.Capabilities = ofp.OFPMFKbps
627 meterFeatures.BandTypes = ofp.OFPMBTDrop
628 meterFeatures.MaxMeter = 0xffffffff
629 meterFeatures.MaxBands = 0xff
630 meterFeatures.MaxColor = 0xff
631 response.Features = *meterFeatures
632 return response, nil
633}
634
635func (ofc *OFClient) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
636 response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
637 response.SetVersion(request.GetVersion())
638 response.SetXid(request.GetXid())
639 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
640 //TODO wire this to voltha core when it implements
641 return response, nil
642}