blob: 8330d1045454ebf3c7d4e4431a9dc50b4fe2e8d8 [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"
Jonathan Hart828908c2020-04-15 14:23:45 -070022 "github.com/opencord/goloxi"
23 ofp "github.com/opencord/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"
Jonathan Hart828908c2020-04-15 14:23:45 -070027 "net"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080028)
29
Jonathan Hart4b110f62020-03-13 17:36:19 -070030func (ofc *OFConnection) handleStatsRequest(request ofp.IHeader, statType uint16) error {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080031 if logger.V(log.DebugLevel) {
32 js, _ := json.Marshal(request)
33 logger.Debugw("handleStatsRequest called",
34 log.Fields{
35 "device-id": ofc.DeviceID,
36 "stat-type": statType,
37 "request": js})
38 }
39
40 switch statType {
41 case ofp.OFPSTDesc:
42 statsReq := request.(*ofp.DescStatsRequest)
43 response, err := ofc.handleDescStatsRequest(statsReq)
44 if err != nil {
45 return err
46 }
47 if logger.V(log.DebugLevel) {
48 reqJs, _ := json.Marshal(statsReq)
49 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080050 logger.Debugw("handle-stats-request-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080051 log.Fields{
52 "device-id": ofc.DeviceID,
53 "request": reqJs,
54 "response": resJs})
55 }
56 return ofc.SendMessage(response)
57 case ofp.OFPSTFlow:
58 statsReq := request.(*ofp.FlowStatsRequest)
59 response, err := ofc.handleFlowStatsRequest(statsReq)
60 if err != nil {
61 return err
62 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -080063 if logger.V(log.DebugLevel) {
64 reqJs, _ := json.Marshal(statsReq)
65 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080066 logger.Debugw("handle-stats-request-flow",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080067 log.Fields{
Don Newton7fe70f72020-02-21 13:54:11 -050068 "device-id": ofc.DeviceID,
69 "request": reqJs,
70 "response-object": response,
71 "response": resJs})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080072 }
73 return ofc.SendMessage(response)
74
75 case ofp.OFPSTAggregate:
76 statsReq := request.(*ofp.AggregateStatsRequest)
77 response, err := ofc.handleAggregateStatsRequest(statsReq)
78 if err != nil {
79 return err
80 }
81 if logger.V(log.DebugLevel) {
82 reqJs, _ := json.Marshal(statsReq)
83 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080084 logger.Debugw("handle-stats-request-aggregate",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080085 log.Fields{
86 "device-id": ofc.DeviceID,
87 "request": reqJs,
88 "response": resJs})
89 }
90 return ofc.SendMessage(response)
91 case ofp.OFPSTTable:
92 statsReq := request.(*ofp.TableStatsRequest)
93 response, e := ofc.handleTableStatsRequest(statsReq)
94 if logger.V(log.DebugLevel) {
95 reqJs, _ := json.Marshal(statsReq)
96 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -080097 logger.Debugw("handle-stats-request-table",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080098 log.Fields{
99 "device-id": ofc.DeviceID,
100 "request": reqJs,
101 "response": resJs})
102 }
103 if e != nil {
104 return e
105 }
106 return ofc.SendMessage(response)
107 case ofp.OFPSTPort:
108 statsReq := request.(*ofp.PortStatsRequest)
109 response, err := ofc.handlePortStatsRequest(statsReq)
110 if err != nil {
111 return err
112 }
113 if logger.V(log.DebugLevel) {
114 reqJs, _ := json.Marshal(statsReq)
115 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800116 logger.Debugw("handle-stats-request-port",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800117 log.Fields{
118 "device-id": ofc.DeviceID,
119 "request": reqJs,
120 "response": resJs})
121 }
122 return ofc.SendMessage(response)
123 case ofp.OFPSTQueue:
124 statsReq := request.(*ofp.QueueStatsRequest)
125 response, err := ofc.handleQueueStatsRequest(statsReq)
126 if err != nil {
127 return err
128 }
129 if logger.V(log.DebugLevel) {
130 reqJs, _ := json.Marshal(statsReq)
131 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800132 logger.Debugw("handle-stats-request-queue",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800133 log.Fields{
134 "device-id": ofc.DeviceID,
135 "request": reqJs,
136 "response": resJs})
137 }
138 return ofc.SendMessage(response)
139 case ofp.OFPSTGroup:
140 statsReq := request.(*ofp.GroupStatsRequest)
141 response, err := ofc.handleGroupStatsRequest(statsReq)
142 if err != nil {
143 return err
144 }
145 if logger.V(log.DebugLevel) {
146 reqJs, _ := json.Marshal(statsReq)
147 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800148 logger.Debugw("handle-stats-request-group",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800149 log.Fields{
150 "device-id": ofc.DeviceID,
151 "request": reqJs,
152 "response": resJs})
153 }
David K. Bainbridgecac73ac2020-02-19 07:00:12 -0800154 return ofc.SendMessage(response)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800155 case ofp.OFPSTGroupDesc:
156 statsReq := request.(*ofp.GroupDescStatsRequest)
157 response, err := ofc.handleGroupStatsDescRequest(statsReq)
158 if err != nil {
159 return err
160 }
161 if logger.V(log.DebugLevel) {
162 reqJs, _ := json.Marshal(statsReq)
163 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800164 logger.Debugw("handle-stats-request-group-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800165 log.Fields{
166 "device-id": ofc.DeviceID,
167 "request": reqJs,
168 "response": resJs})
169 }
170 return ofc.SendMessage(response)
171
172 case ofp.OFPSTGroupFeatures:
173 statsReq := request.(*ofp.GroupFeaturesStatsRequest)
174 response, err := ofc.handleGroupFeatureStatsRequest(statsReq)
175 if err != nil {
176 return err
177 }
178 if logger.V(log.DebugLevel) {
179 reqJs, _ := json.Marshal(statsReq)
180 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800181 logger.Debugw("handle-stats-request-group-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800182 log.Fields{
183 "device-id": ofc.DeviceID,
184 "request": reqJs,
185 "response": resJs})
186 }
187 return ofc.SendMessage(response)
188 case ofp.OFPSTMeter:
189 statsReq := request.(*ofp.MeterStatsRequest)
190 response, err := ofc.handleMeterStatsRequest(statsReq)
191 if err != nil {
192 return err
193 }
194 if logger.V(log.DebugLevel) {
195 reqJs, _ := json.Marshal(statsReq)
196 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800197 logger.Debugw("handle-stats-request-meter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800198 log.Fields{
199 "device-id": ofc.DeviceID,
200 "request": reqJs,
201 "response": resJs})
202 }
203 return ofc.SendMessage(response)
204 case ofp.OFPSTMeterConfig:
205 statsReq := request.(*ofp.MeterConfigStatsRequest)
206 response, err := ofc.handleMeterConfigStatsRequest(statsReq)
207 if err != nil {
208 return err
209 }
210 if logger.V(log.DebugLevel) {
211 reqJs, _ := json.Marshal(statsReq)
212 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800213 logger.Debugw("handle-stats-request-meter-config",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800214 log.Fields{
215 "device-id": ofc.DeviceID,
216 "request": reqJs,
217 "response": resJs})
218 }
219 return ofc.SendMessage(response)
220 case ofp.OFPSTMeterFeatures:
221 statsReq := request.(*ofp.MeterFeaturesStatsRequest)
222 response, err := ofc.handleMeterFeatureStatsRequest(statsReq)
223 if err != nil {
224 return err
225 }
226 if logger.V(log.DebugLevel) {
227 reqJs, _ := json.Marshal(statsReq)
228 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800229 logger.Debugw("handle-stats-request-meter-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800230 log.Fields{
231 "device-id": ofc.DeviceID,
232 "request": reqJs,
233 "response": resJs})
234 }
235 return ofc.SendMessage(response)
236 case ofp.OFPSTTableFeatures:
237 statsReq := request.(*ofp.TableFeaturesStatsRequest)
238 response, err := ofc.handleTableFeaturesStatsRequest(statsReq)
239 if err != nil {
240 return err
241 }
242 if logger.V(log.DebugLevel) {
243 reqJs, _ := json.Marshal(statsReq)
244 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800245 logger.Debugw("handle-stats-request-table-features",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800246 log.Fields{
247 "device-id": ofc.DeviceID,
248 "request": reqJs,
249 "response": resJs})
250 }
251 return ofc.SendMessage(response)
252 case ofp.OFPSTPortDesc:
253 statsReq := request.(*ofp.PortDescStatsRequest)
254 response, err := ofc.handlePortDescStatsRequest(statsReq)
255 if err != nil {
256 return err
257 }
258 if logger.V(log.DebugLevel) {
259 reqJs, _ := json.Marshal(statsReq)
260 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800261 logger.Debugw("handle-stats-request-port-desc",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800262 log.Fields{
263 "device-id": ofc.DeviceID,
264 "request": reqJs,
265 "response": resJs})
266 }
267 return ofc.SendMessage(response)
268
269 case ofp.OFPSTExperimenter:
270 statsReq := request.(*ofp.ExperimenterStatsRequest)
271 response, err := ofc.handleExperimenterStatsRequest(statsReq)
272 if err != nil {
273 return err
274 }
275 if logger.V(log.DebugLevel) {
276 reqJs, _ := json.Marshal(statsReq)
277 resJs, _ := json.Marshal(response)
David K. Bainbridge55376262020-01-22 23:28:27 -0800278 logger.Debugw("handle-stats-request-experimenter",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800279 log.Fields{
280 "device-id": ofc.DeviceID,
281 "request": reqJs,
282 "response": resJs})
283 }
284 return ofc.SendMessage(response)
285 }
286 return nil
287}
288
Jonathan Hart4b110f62020-03-13 17:36:19 -0700289func (ofc *OFConnection) handleDescStatsRequest(request *ofp.DescStatsRequest) (*ofp.DescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700290 volthaClient := ofc.VolthaClient.Get()
291 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800292 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
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700299 resp, err := volthaClient.GetLogicalDevice(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800300 &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
Jonathan Hart4b110f62020-03-13 17:36:19 -0700314func (ofc *OFConnection) handleFlowStatsRequest(request *ofp.FlowStatsRequest) (*ofp.FlowStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700315 volthaClient := ofc.VolthaClient.Get()
316 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800317 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()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700323 resp, err := volthaClient.ListLogicalDeviceFlows(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800324 &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())
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800341 match := ofp.NewMatchV3()
342 pbMatch := item.GetMatch()
343 match.SetType(uint16(pbMatch.GetType()))
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800344 var fields []goloxi.IOxm
345 for _, oxmField := range pbMatch.GetOxmFields() {
346 field := oxmField.GetField()
347 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
Jonathan Hart828908c2020-04-15 14:23:45 -0700348 iOxm := parseOxm(ofbField)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800349 fields = append(fields, iOxm)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800350 }
351
352 match.OxmList = fields
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800353 entry.SetMatch(*match)
354 var instructions []ofp.IInstruction
355 for _, ofpInstruction := range item.Instructions {
Jonathan Hart828908c2020-04-15 14:23:45 -0700356 instruction := parseInstructions(ofpInstruction)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800357 instructions = append(instructions, instruction)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800358 }
359 entry.Instructions = instructions
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800360 flow = append(flow, entry)
361 }
362 response.SetEntries(flow)
363 return response, nil
364}
365
Jonathan Hart4b110f62020-03-13 17:36:19 -0700366func (ofc *OFConnection) handleAggregateStatsRequest(request *ofp.AggregateStatsRequest) (*ofp.AggregateStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800367 response := ofp.NewAggregateStatsReply()
368 response.SetVersion(request.GetVersion())
369 response.SetXid(request.GetXid())
370 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
371 response.SetFlowCount(0)
372 //TODO wire this to voltha core when it implements
373 return response, nil
374}
375
Jonathan Hart4b110f62020-03-13 17:36:19 -0700376func (ofc *OFConnection) handleGroupStatsRequest(request *ofp.GroupStatsRequest) (*ofp.GroupStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700377 volthaClient := ofc.VolthaClient.Get()
378 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800379 return nil, NoVolthaConnectionError
380 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800381 response := ofp.NewGroupStatsReply()
382 response.SetVersion(request.GetVersion())
383 response.SetXid(request.GetXid())
384 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700385 reply, err := volthaClient.ListLogicalDeviceFlowGroups(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800386 &common.ID{Id: ofc.DeviceID})
387 if err != nil {
388 return nil, err
389 }
390
391 var groupStatsEntries []*ofp.GroupStatsEntry
392 for _, item := range reply.GetItems() {
393 stats := item.GetStats()
394 var entry ofp.GroupStatsEntry
395 entry.SetByteCount(stats.GetByteCount())
396 entry.SetPacketCount(stats.GetPacketCount())
397 entry.SetDurationNsec(stats.GetDurationNsec())
398 entry.SetDurationSec(stats.GetDurationSec())
399 entry.SetRefCount(stats.GetRefCount())
400 entry.SetGroupId(stats.GetGroupId())
401 var bucketStatsList []*ofp.BucketCounter
Jonathan Hart60c5d772020-03-30 18:28:40 -0700402 // TODO fix this when API handler is fixed in the core
403 // Core doesn't return any buckets in the Stats object, so just
404 // fill out an empty BucketCounter for each bucket in the group Desc for now.
405 for range item.GetDesc().GetBuckets() {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800406 bucketCounter := ofp.BucketCounter{}
Jonathan Hart60c5d772020-03-30 18:28:40 -0700407 bucketCounter.SetPacketCount(0)
408 bucketCounter.SetByteCount(0)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800409 bucketStatsList = append(bucketStatsList, &bucketCounter)
410 }
411 entry.SetBucketStats(bucketStatsList)
412 groupStatsEntries = append(groupStatsEntries, &entry)
413 }
414 response.SetEntries(groupStatsEntries)
415 return response, nil
416}
417
Jonathan Hart4b110f62020-03-13 17:36:19 -0700418func (ofc *OFConnection) handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest) (*ofp.GroupDescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700419 volthaClient := ofc.VolthaClient.Get()
420 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800421 return nil, NoVolthaConnectionError
422 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800423 response := ofp.NewGroupDescStatsReply()
424 response.SetVersion(request.GetVersion())
425 response.SetXid(request.GetXid())
426 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700427 reply, err := volthaClient.ListLogicalDeviceFlowGroups(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800428 &common.ID{Id: ofc.DeviceID})
429 if err != nil {
430 return nil, err
431 }
432 var groupDescStatsEntries []*ofp.GroupDescStatsEntry
433 for _, item := range reply.GetItems() {
Jonathan Hart60c5d772020-03-30 18:28:40 -0700434 desc := item.GetDesc()
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800435
Jonathan Hart60c5d772020-03-30 18:28:40 -0700436 buckets := volthaBucketsToOpenflow(desc.Buckets)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800437
Jonathan Hart60c5d772020-03-30 18:28:40 -0700438 groupDesc := &ofp.GroupDescStatsEntry{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700439 GroupType: volthaGroupTypeToOpenflow(desc.Type),
440 GroupId: desc.GroupId,
441 Buckets: buckets,
442 }
443 groupDescStatsEntries = append(groupDescStatsEntries, groupDesc)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800444 }
445 response.SetEntries(groupDescStatsEntries)
446 return response, nil
447}
448
Jonathan Hart4b110f62020-03-13 17:36:19 -0700449func (ofc *OFConnection) handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest) (*ofp.GroupFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800450 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
Jonathan Hart4b110f62020-03-13 17:36:19 -0700458func (ofc *OFConnection) handleMeterStatsRequest(request *ofp.MeterStatsRequest) (*ofp.MeterStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700459 volthaClient := ofc.VolthaClient.Get()
460 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800461 return nil, NoVolthaConnectionError
462 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800463 response := ofp.NewMeterStatsReply()
464 response.SetVersion(request.GetVersion())
465 response.SetXid(request.GetXid())
466 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700467 resp, err := volthaClient.ListLogicalDeviceMeters(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800468 &common.ID{Id: ofc.DeviceID})
469 if err != nil {
470 return nil, err
471 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800472 var meterStats []*ofp.MeterStats
473 for _, item := range resp.Items {
474 meterStat := ofp.NewMeterStats()
475 stats := item.Stats
476 meterStat.DurationNsec = stats.DurationNsec
477 meterStat.DurationSec = stats.DurationSec
478 meterStat.ByteInCount = stats.ByteInCount
479 meterStat.FlowCount = stats.FlowCount
480 meterStat.MeterId = stats.MeterId
481 var bandStats []*ofp.MeterBandStats
482 for _, bStat := range stats.BandStats {
483 bandStat := ofp.NewMeterBandStats()
484 bandStat.ByteBandCount = bStat.ByteBandCount
485 bandStat.PacketBandCount = bStat.PacketBandCount
486 bandStats = append(bandStats, bandStat)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800487 }
488 meterStat.SetBandStats(bandStats)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800489 meterStats = append(meterStats, meterStat)
490 }
491 response.SetEntries(meterStats)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800492 return response, nil
493}
494
Jonathan Hart4b110f62020-03-13 17:36:19 -0700495func (ofc *OFConnection) handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest) (*ofp.MeterConfigStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800496 response := ofp.NewMeterConfigStatsReply()
497 response.SetVersion(request.GetVersion())
498 response.SetXid(request.GetXid())
499 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
500 //TODO wire this to voltha core when it implements
501 return response, nil
502}
503
Jonathan Hart4b110f62020-03-13 17:36:19 -0700504func (ofc *OFConnection) handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest) (*ofp.TableFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800505 response := ofp.NewTableFeaturesStatsReply()
506 response.SetVersion(request.GetVersion())
507 response.SetXid(request.GetXid())
508 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
509 //TODO wire this to voltha core when it implements
510 return response, nil
511}
512
Jonathan Hart4b110f62020-03-13 17:36:19 -0700513func (ofc *OFConnection) handleTableStatsRequest(request *ofp.TableStatsRequest) (*ofp.TableStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800514 var response = ofp.NewTableStatsReply()
515 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
516 response.SetVersion(request.GetVersion())
517 response.SetXid(request.GetXid())
518 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
519 return response, nil
520}
521
Jonathan Hart4b110f62020-03-13 17:36:19 -0700522func (ofc *OFConnection) handleQueueStatsRequest(request *ofp.QueueStatsRequest) (*ofp.QueueStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800523 response := ofp.NewQueueStatsReply()
524 response.SetVersion(request.GetVersion())
525 response.SetXid(request.GetXid())
526 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
527 //TODO wire this to voltha core when it implements
528 return response, nil
529}
530
Jonathan Hart4b110f62020-03-13 17:36:19 -0700531func (ofc *OFConnection) handlePortStatsRequest(request *ofp.PortStatsRequest) (*ofp.PortStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700532 volthaClient := ofc.VolthaClient.Get()
533 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800534 return nil, NoVolthaConnectionError
535 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800536 response := ofp.NewPortStatsReply()
537 response.SetXid(request.GetXid())
538 response.SetVersion(request.GetVersion())
539 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700540 reply, err := volthaClient.ListLogicalDevicePorts(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800541 &common.ID{Id: ofc.DeviceID})
542 if err != nil {
543 return nil, err
544 }
545 var entries []*ofp.PortStatsEntry
546 if request.GetPortNo() == 0xffffffff { //all ports
547 for _, port := range reply.GetItems() {
548 entries = append(entries, parsePortStats(port))
549 }
550 } else { //find right port that is requested
551 for _, port := range reply.GetItems() {
552 if port.GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
553 entries = append(entries, parsePortStats(port))
554 }
555 }
556 }
557 response.SetEntries(entries)
558 return response, nil
559}
560
Jonathan Hart4b110f62020-03-13 17:36:19 -0700561func (ofc *OFConnection) handlePortDescStatsRequest(request *ofp.PortDescStatsRequest) (*ofp.PortDescStatsReply, error) {
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700562 volthaClient := ofc.VolthaClient.Get()
563 if volthaClient == nil {
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800564 return nil, NoVolthaConnectionError
565 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800566 response := ofp.NewPortDescStatsReply()
567 response.SetVersion(request.GetVersion())
568 response.SetXid(request.GetXid())
569 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700570 logicalDevice, err := volthaClient.GetLogicalDevice(context.Background(),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800571 &common.ID{Id: ofc.DeviceID})
572 if err != nil {
573 return nil, err
574 }
575 var entries []*ofp.PortDesc
576 for _, port := range logicalDevice.GetPorts() {
577 ofpPort := port.GetOfpPort()
578 var entry ofp.PortDesc
579 entry.SetPortNo(ofp.Port(ofpPort.GetPortNo()))
580
581 var octets []byte
582 for _, val := range ofpPort.GetHwAddr() {
583 octets = append(octets, byte(val))
584 }
585 hwAddr := net.HardwareAddr(octets)
586 entry.SetHwAddr(hwAddr)
587 entry.SetName(PadString(ofpPort.GetName(), 16))
588 entry.SetConfig(ofp.PortConfig(ofpPort.GetConfig()))
589 entry.SetState(ofp.PortState(ofpPort.GetState()))
590 entry.SetCurr(ofp.PortFeatures(ofpPort.GetCurr()))
591 entry.SetAdvertised(ofp.PortFeatures(ofpPort.GetAdvertised()))
592 entry.SetSupported(ofp.PortFeatures(ofpPort.GetSupported()))
593 entry.SetPeer(ofp.PortFeatures(ofpPort.GetPeer()))
594 entry.SetCurrSpeed(ofpPort.GetCurrSpeed())
595 entry.SetMaxSpeed(ofpPort.GetMaxSpeed())
596
597 entries = append(entries, &entry)
598 }
599
600 response.SetEntries(entries)
601 //TODO call voltha and get port descriptions etc
602 return response, nil
603
604}
605
Jonathan Hart4b110f62020-03-13 17:36:19 -0700606func (ofc *OFConnection) handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800607 response := ofp.NewMeterFeaturesStatsReply()
608 response.SetXid(request.GetXid())
609 response.SetVersion(request.GetVersion())
610 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
611 meterFeatures := ofp.NewMeterFeatures()
612 meterFeatures.Capabilities = ofp.OFPMFKbps
613 meterFeatures.BandTypes = ofp.OFPMBTDrop
614 meterFeatures.MaxMeter = 0xffffffff
615 meterFeatures.MaxBands = 0xff
616 meterFeatures.MaxColor = 0xff
617 response.Features = *meterFeatures
618 return response, nil
619}
620
Jonathan Hart4b110f62020-03-13 17:36:19 -0700621func (ofc *OFConnection) handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest) (*ofp.ExperimenterStatsReply, error) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800622 response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
623 response.SetVersion(request.GetVersion())
624 response.SetXid(request.GetXid())
625 response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
626 //TODO wire this to voltha core when it implements
627 return response, nil
628}