Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 1 | /* |
| 2 | Copyright 2017 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 | |
| 17 | package openflow |
| 18 | |
| 19 | import ( |
| 20 | "context" |
| 21 | "encoding/json" |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 22 | |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 23 | "net" |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 24 | |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 25 | "unsafe" |
| 26 | |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 27 | "github.com/opencord/ofagent-go/settings" |
| 28 | l "github.com/opencord/voltha-lib-go/v2/pkg/log" |
Don Newton | b437c6f | 2019-12-18 11:51:57 -0500 | [diff] [blame] | 29 | "github.com/opencord/voltha-protos/v2/go/openflow_13" |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 30 | |
| 31 | "github.com/donNewtonAlpha/goloxi" |
| 32 | ofp "github.com/donNewtonAlpha/goloxi/of13" |
Don Newton | b437c6f | 2019-12-18 11:51:57 -0500 | [diff] [blame] | 33 | "github.com/opencord/voltha-protos/v2/go/common" |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 34 | ) |
| 35 | |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 36 | func handleStatsRequest(request ofp.IHeader, statType uint16, DeviceID string, client *Client) error { |
| 37 | if settings.GetDebug(DeviceID) { |
| 38 | js, _ := json.Marshal(request) |
| 39 | logger.Debugw("handleStatsRequest called", l.Fields{"DeviceID": DeviceID, "StatType": statType, "rquest": js}) |
| 40 | } |
| 41 | var id = common.ID{Id: DeviceID} |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 42 | switch statType { |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 43 | case ofp.OFPSTDesc: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 44 | statsReq := request.(*ofp.DescStatsRequest) |
| 45 | response, err := handleDescStatsRequest(statsReq, id) |
| 46 | if err != nil { |
| 47 | return err |
| 48 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 49 | if settings.GetDebug(DeviceID) { |
| 50 | reqJs, _ := json.Marshal(statsReq) |
| 51 | resJs, _ := json.Marshal(response) |
| 52 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 53 | } |
| 54 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 55 | case ofp.OFPSTFlow: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 56 | statsReq := request.(*ofp.FlowStatsRequest) |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 57 | response, err := handleFlowStatsRequest(statsReq, id, DeviceID) |
Don Newton | b437c6f | 2019-12-18 11:51:57 -0500 | [diff] [blame] | 58 | if err != nil { |
| 59 | return err |
| 60 | } |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 61 | response.Length = uint16(unsafe.Sizeof(*response)) |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 62 | if settings.GetDebug(DeviceID) { |
| 63 | reqJs, _ := json.Marshal(statsReq) |
| 64 | resJs, _ := json.Marshal(response) |
| 65 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 66 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 67 | return client.SendMessage(response) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 68 | |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 69 | case ofp.OFPSTAggregate: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 70 | statsReq := request.(*ofp.AggregateStatsRequest) |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 71 | response, err := handleAggregateStatsRequest(statsReq, id) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 72 | if err != nil { |
| 73 | return err |
| 74 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 75 | if settings.GetDebug(DeviceID) { |
| 76 | reqJs, _ := json.Marshal(statsReq) |
| 77 | resJs, _ := json.Marshal(response) |
| 78 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 79 | } |
| 80 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 81 | case ofp.OFPSTTable: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 82 | statsReq := request.(*ofp.TableStatsRequest) |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 83 | response, e := handleTableStatsRequest(statsReq, id) |
| 84 | if settings.GetDebug(DeviceID) { |
| 85 | reqJs, _ := json.Marshal(statsReq) |
| 86 | resJs, _ := json.Marshal(response) |
| 87 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 88 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 89 | if e != nil { |
| 90 | return e |
| 91 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 92 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 93 | case ofp.OFPSTPort: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 94 | statsReq := request.(*ofp.PortStatsRequest) |
| 95 | response, err := handlePortStatsRequest(statsReq, id) |
| 96 | if err != nil { |
| 97 | return err |
| 98 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 99 | if settings.GetDebug(DeviceID) { |
| 100 | reqJs, _ := json.Marshal(statsReq) |
| 101 | resJs, _ := json.Marshal(response) |
| 102 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 103 | } |
| 104 | return client.SendMessage(response) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 105 | |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 106 | case ofp.OFPSTQueue: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 107 | statsReq := request.(*ofp.QueueStatsRequest) |
| 108 | response, err := handleQueueStatsRequest(statsReq, id) |
| 109 | if err != nil { |
| 110 | return err |
| 111 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 112 | if settings.GetDebug(DeviceID) { |
| 113 | reqJs, _ := json.Marshal(statsReq) |
| 114 | resJs, _ := json.Marshal(response) |
| 115 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 116 | } |
| 117 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 118 | case ofp.OFPSTGroup: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 119 | statsReq := request.(*ofp.GroupStatsRequest) |
| 120 | response, err := handleGroupStatsRequest(statsReq, id) |
| 121 | if err != nil { |
| 122 | return err |
| 123 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 124 | if settings.GetDebug(DeviceID) { |
| 125 | reqJs, _ := json.Marshal(statsReq) |
| 126 | resJs, _ := json.Marshal(response) |
| 127 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 128 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 129 | client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 130 | case ofp.OFPSTGroupDesc: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 131 | statsReq := request.(*ofp.GroupDescStatsRequest) |
| 132 | response, err := handleGroupStatsDescRequest(statsReq, id) |
| 133 | if err != nil { |
| 134 | return err |
| 135 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 136 | if settings.GetDebug(DeviceID) { |
| 137 | reqJs, _ := json.Marshal(statsReq) |
| 138 | resJs, _ := json.Marshal(response) |
| 139 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 140 | } |
| 141 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 142 | |
| 143 | case ofp.OFPSTGroupFeatures: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 144 | statsReq := request.(*ofp.GroupFeaturesStatsRequest) |
| 145 | response, err := handleGroupFeatureStatsRequest(statsReq, id) |
| 146 | if err != nil { |
| 147 | return err |
| 148 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 149 | if settings.GetDebug(DeviceID) { |
| 150 | reqJs, _ := json.Marshal(statsReq) |
| 151 | resJs, _ := json.Marshal(response) |
| 152 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 153 | } |
| 154 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 155 | case ofp.OFPSTMeter: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 156 | statsReq := request.(*ofp.MeterStatsRequest) |
| 157 | response, err := handleMeterStatsRequest(statsReq, id) |
| 158 | if err != nil { |
| 159 | return err |
| 160 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 161 | if settings.GetDebug(DeviceID) { |
| 162 | reqJs, _ := json.Marshal(statsReq) |
| 163 | resJs, _ := json.Marshal(response) |
| 164 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 165 | } |
| 166 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 167 | case ofp.OFPSTMeterConfig: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 168 | statsReq := request.(*ofp.MeterConfigStatsRequest) |
| 169 | response, err := handleMeterConfigStatsRequest(statsReq, id) |
| 170 | if err != nil { |
| 171 | return err |
| 172 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 173 | if settings.GetDebug(DeviceID) { |
| 174 | reqJs, _ := json.Marshal(statsReq) |
| 175 | resJs, _ := json.Marshal(response) |
| 176 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 177 | } |
| 178 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 179 | case ofp.OFPSTMeterFeatures: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 180 | statsReq := request.(*ofp.MeterFeaturesStatsRequest) |
| 181 | response, err := handleMeterFeatureStatsRequest(statsReq) |
| 182 | if err != nil { |
| 183 | return err |
| 184 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 185 | if settings.GetDebug(DeviceID) { |
| 186 | reqJs, _ := json.Marshal(statsReq) |
| 187 | resJs, _ := json.Marshal(response) |
| 188 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 189 | } |
| 190 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 191 | case ofp.OFPSTTableFeatures: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 192 | statsReq := request.(*ofp.TableFeaturesStatsRequest) |
| 193 | response, err := handleTableFeaturesStatsRequest(statsReq, id) |
| 194 | if err != nil { |
| 195 | return err |
| 196 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 197 | if settings.GetDebug(DeviceID) { |
| 198 | reqJs, _ := json.Marshal(statsReq) |
| 199 | resJs, _ := json.Marshal(response) |
| 200 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 201 | } |
| 202 | return client.SendMessage(response) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 203 | case ofp.OFPSTPortDesc: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 204 | statsReq := request.(*ofp.PortDescStatsRequest) |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 205 | response, err := handlePortDescStatsRequest(statsReq, DeviceID) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 206 | if err != nil { |
| 207 | return err |
| 208 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 209 | if settings.GetDebug(DeviceID) { |
| 210 | reqJs, _ := json.Marshal(statsReq) |
| 211 | resJs, _ := json.Marshal(response) |
| 212 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 213 | } |
| 214 | return client.SendMessage(response) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 215 | |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 216 | case ofp.OFPSTExperimenter: |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 217 | statsReq := request.(*ofp.ExperimenterStatsRequest) |
| 218 | response, err := handleExperimenterStatsRequest(statsReq, id) |
| 219 | if err != nil { |
| 220 | return err |
| 221 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 222 | if settings.GetDebug(DeviceID) { |
| 223 | reqJs, _ := json.Marshal(statsReq) |
| 224 | resJs, _ := json.Marshal(response) |
| 225 | logger.Debugw("HandleStatsRequest GRPC", l.Fields{"DeviceID": DeviceID, "Req": reqJs, "Res": resJs}) |
| 226 | } |
| 227 | return client.SendMessage(response) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 228 | } |
| 229 | return nil |
| 230 | } |
| 231 | |
| 232 | func handleDescStatsRequest(request *ofp.DescStatsRequest, id common.ID) (*ofp.DescStatsReply, error) { |
| 233 | response := ofp.NewDescStatsReply() |
| 234 | response.SetXid(request.GetXid()) |
| 235 | response.SetVersion(request.GetVersion()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 236 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
| 237 | |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 238 | client := *getGrpcClient() |
| 239 | resp, err := client.GetLogicalDevice(context.Background(), &id) |
| 240 | if err != nil { |
| 241 | return nil, err |
| 242 | } |
| 243 | desc := resp.GetDesc() |
| 244 | |
| 245 | response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256)) |
| 246 | response.SetHwDesc(PadString(desc.GetHwDesc(), 256)) |
| 247 | response.SetSwDesc(PadString(desc.GetSwDesc(), 256)) |
| 248 | response.SetSerialNum(PadString(desc.GetSerialNum(), 32)) |
| 249 | response.SetDpDesc(PadString(desc.GetDpDesc(), 256)) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 250 | return response, nil |
| 251 | } |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 252 | func handleFlowStatsRequest(request *ofp.FlowStatsRequest, id common.ID, DeviceID string) (*ofp.FlowStatsReply, error) { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 253 | response := ofp.NewFlowStatsReply() |
| 254 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 255 | response.SetVersion(4) |
| 256 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 257 | client := *getGrpcClient() |
| 258 | resp, err := client.ListLogicalDeviceFlows(context.Background(), &id) |
| 259 | if err != nil { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 260 | return nil, err |
| 261 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 262 | var flow []*ofp.FlowStatsEntry |
| 263 | items := resp.GetItems() |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 264 | for i := 0; i < len(items); i++ { |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 265 | item := items[i] |
| 266 | entry := ofp.NewFlowStatsEntry() |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 267 | entry.SetTableId(uint8(item.GetTableId())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 268 | entry.SetDurationSec(item.GetDurationSec()) |
| 269 | entry.SetDurationNsec(item.GetDurationNsec()) |
| 270 | entry.SetPriority(uint16(item.GetPriority())) |
| 271 | entry.SetIdleTimeout(uint16(item.GetIdleTimeout())) |
| 272 | entry.SetHardTimeout(uint16(item.GetHardTimeout())) |
| 273 | entry.SetFlags(ofp.FlowModFlags(item.GetFlags())) |
| 274 | entry.SetCookie(item.GetCookie()) |
| 275 | entry.SetPacketCount(item.GetPacketCount()) |
| 276 | entry.SetByteCount(item.GetByteCount()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 277 | var entrySize uint16 |
| 278 | entrySize = 48 |
| 279 | match := ofp.NewMatchV3() |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 280 | pbMatch := item.GetMatch() |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 281 | var fields []goloxi.IOxm |
| 282 | match.SetType(uint16(pbMatch.GetType())) |
| 283 | oxFields := pbMatch.GetOxmFields() |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 284 | var size uint16 |
| 285 | size = 4 |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 286 | for i := 0; i < len(oxFields); i++ { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 287 | oxmField := oxFields[i] |
| 288 | field := oxmField.GetField() |
| 289 | ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 290 | iOxm, oxmSize := parseOxm(ofbField, DeviceID) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 291 | fields = append(fields, iOxm) |
| 292 | if oxmSize > 0 { |
| 293 | size += 4 //header for oxm |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 294 | } |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 295 | size += oxmSize |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 296 | } |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 297 | |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 298 | match.OxmList = fields |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 299 | match.Length = uint16(size) |
| 300 | //account for 8 byte alignment |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 301 | if size%8 != 0 { |
| 302 | size = ((size / 8) + 1) * 8 |
| 303 | } |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 304 | entrySize += size |
| 305 | entry.SetMatch(*match) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 306 | var instructions []ofp.IInstruction |
| 307 | ofpInstructions := item.Instructions |
| 308 | for i := 0; i < len(ofpInstructions); i++ { |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 309 | instruction, size := parseInstructions(ofpInstructions[i], DeviceID) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 310 | instructions = append(instructions, instruction) |
| 311 | entrySize += size |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 312 | } |
| 313 | entry.Instructions = instructions |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 314 | entry.Length = entrySize |
| 315 | entrySize = 0 |
| 316 | flow = append(flow, entry) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 317 | } |
| 318 | response.SetEntries(flow) |
| 319 | return response, nil |
| 320 | } |
| 321 | func handleAggregateStatsRequest(request *ofp.AggregateStatsRequest, id common.ID) (*ofp.AggregateStatsReply, error) { |
| 322 | response := ofp.NewAggregateStatsReply() |
| 323 | response.SetVersion(request.GetVersion()) |
| 324 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 325 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 326 | response.SetFlowCount(0) |
| 327 | //TODO wire this to voltha core when it implements |
| 328 | return response, nil |
| 329 | } |
| 330 | func handleGroupStatsRequest(request *ofp.GroupStatsRequest, id common.ID) (*ofp.GroupStatsReply, error) { |
| 331 | response := ofp.NewGroupStatsReply() |
| 332 | response.SetVersion(request.GetVersion()) |
| 333 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 334 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 335 | client := *getGrpcClient() |
| 336 | reply, err := client.ListLogicalDeviceFlowGroups(context.Background(), &id) |
| 337 | if err != nil { |
| 338 | return nil, err |
| 339 | } |
| 340 | |
| 341 | var groupStatsEntries []*ofp.GroupStatsEntry |
| 342 | items := reply.GetItems() |
| 343 | for i := 0; i < len(items); i++ { |
| 344 | item := items[i].GetStats() |
| 345 | var entry ofp.GroupStatsEntry |
| 346 | entry.SetByteCount(item.GetByteCount()) |
| 347 | entry.SetPacketCount(item.GetPacketCount()) |
| 348 | entry.SetDurationNsec(item.GetDurationNsec()) |
| 349 | entry.SetDurationSec(item.GetDurationSec()) |
| 350 | entry.SetRefCount(item.GetRefCount()) |
| 351 | entry.SetGroupId(item.GetGroupId()) |
| 352 | bucketStats := item.GetBucketStats() |
| 353 | var bucketStatsList []*ofp.BucketCounter |
| 354 | for j := 0; j < len(bucketStats); j++ { |
| 355 | bucketStat := bucketStats[i] |
| 356 | var bucketCounter ofp.BucketCounter |
| 357 | bucketCounter.SetPacketCount(bucketStat.GetPacketCount()) |
| 358 | bucketCounter.SetByteCount(bucketStat.GetByteCount()) |
| 359 | bucketStatsList = append(bucketStatsList, &bucketCounter) |
| 360 | } |
| 361 | entry.SetBucketStats(bucketStatsList) |
| 362 | groupStatsEntries = append(groupStatsEntries, &entry) |
| 363 | } |
| 364 | response.SetEntries(groupStatsEntries) |
| 365 | return response, nil |
| 366 | } |
| 367 | func handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest, id common.ID) (*ofp.GroupDescStatsReply, error) { |
| 368 | response := ofp.NewGroupDescStatsReply() |
| 369 | response.SetVersion(request.GetVersion()) |
| 370 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 371 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 372 | client := *getGrpcClient() |
| 373 | reply, err := client.ListLogicalDeviceFlowGroups(context.Background(), &id) |
| 374 | if err != nil { |
| 375 | return nil, err |
| 376 | } |
| 377 | entries := reply.GetItems() |
| 378 | var groupDescStatsEntries []*ofp.GroupDescStatsEntry |
| 379 | for i := 0; i < len(entries); i++ { |
| 380 | item := entries[i].GetStats() |
| 381 | var groupDesc ofp.GroupDescStatsEntry |
| 382 | groupDesc.SetGroupId(item.GetGroupId()) |
| 383 | /* |
| 384 | buckets := item.g |
| 385 | var bucketList []*ofp.Bucket |
| 386 | for j:=0;j<len(buckets);j++{ |
| 387 | |
| 388 | } |
| 389 | |
| 390 | groupDesc.SetBuckets(bucketList) |
| 391 | */ |
| 392 | groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc) |
| 393 | } |
| 394 | response.SetEntries(groupDescStatsEntries) |
| 395 | return response, nil |
| 396 | } |
| 397 | func handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest, id common.ID) (*ofp.GroupFeaturesStatsReply, error) { |
| 398 | response := ofp.NewGroupFeaturesStatsReply() |
| 399 | response.SetVersion(request.GetVersion()) |
| 400 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 401 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 402 | //TODO wire this to voltha core when it implements |
| 403 | return response, nil |
| 404 | } |
| 405 | func handleMeterStatsRequest(request *ofp.MeterStatsRequest, id common.ID) (*ofp.MeterStatsReply, error) { |
| 406 | response := ofp.NewMeterStatsReply() |
| 407 | response.SetVersion(request.GetVersion()) |
| 408 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 409 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
| 410 | client := *getGrpcClient() |
| 411 | resp, err := client.ListLogicalDeviceMeters(context.Background(), &id) |
| 412 | if err != nil { |
| 413 | return nil, err |
| 414 | } |
| 415 | size := uint16(40) |
| 416 | items := resp.Items |
| 417 | var meterStats []*ofp.MeterStats |
| 418 | for i := 0; i < len(items); i++ { |
| 419 | meterStat := ofp.NewMeterStats() |
| 420 | item := items[i] |
| 421 | stats := item.Stats |
| 422 | meterStat.DurationNsec = stats.DurationNsec |
| 423 | meterStat.DurationSec = stats.DurationSec |
| 424 | meterStat.ByteInCount = stats.ByteInCount |
| 425 | meterStat.FlowCount = stats.FlowCount |
| 426 | meterStat.MeterId = stats.MeterId |
| 427 | var bandStats []*ofp.MeterBandStats |
| 428 | bStats := stats.BandStats |
| 429 | for j := 0; j < len(bStats); j++ { |
| 430 | bStat := bStats[j] |
| 431 | bandStat := ofp.NewMeterBandStats() |
| 432 | bandStat.ByteBandCount = bStat.ByteBandCount |
| 433 | bandStat.PacketBandCount = bStat.PacketBandCount |
| 434 | bandStats = append(bandStats, bandStat) |
| 435 | size += 16 |
| 436 | } |
| 437 | meterStat.SetBandStats(bandStats) |
| 438 | meterStat.Len = size |
| 439 | meterStats = append(meterStats, meterStat) |
| 440 | } |
| 441 | response.SetEntries(meterStats) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 442 | return response, nil |
| 443 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 444 | func handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest, id common.ID) (*ofp.MeterConfigStatsReply, error) { |
| 445 | response := ofp.NewMeterConfigStatsReply() |
| 446 | response.SetVersion(request.GetVersion()) |
| 447 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 448 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 449 | //TODO wire this to voltha core when it implements |
| 450 | return response, nil |
| 451 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 452 | func handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest, id common.ID) (*ofp.TableFeaturesStatsReply, error) { |
| 453 | response := ofp.NewTableFeaturesStatsReply() |
| 454 | response.SetVersion(request.GetVersion()) |
| 455 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 456 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 457 | //TODO wire this to voltha core when it implements |
| 458 | return response, nil |
| 459 | } |
| 460 | func handleTableStatsRequest(request *ofp.TableStatsRequest, id common.ID) (*ofp.TableStatsReply, error) { |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 461 | var response = ofp.NewTableStatsReply() |
| 462 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
| 463 | response.SetVersion(request.GetVersion()) |
| 464 | response.SetXid(request.GetXid()) |
| 465 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
| 466 | return response, nil |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 467 | } |
| 468 | func handleQueueStatsRequest(request *ofp.QueueStatsRequest, id common.ID) (*ofp.QueueStatsReply, error) { |
| 469 | response := ofp.NewQueueStatsReply() |
| 470 | response.SetVersion(request.GetVersion()) |
| 471 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 472 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 473 | //TODO wire this to voltha core when it implements |
| 474 | return response, nil |
| 475 | } |
| 476 | func handlePortStatsRequest(request *ofp.PortStatsRequest, id common.ID) (*ofp.PortStatsReply, error) { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 477 | response := ofp.NewPortStatsReply() |
| 478 | response.SetXid(request.GetXid()) |
| 479 | response.SetVersion(request.GetVersion()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 480 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 481 | client := *getGrpcClient() |
| 482 | reply, err := client.ListLogicalDevicePorts(context.Background(), &id) |
| 483 | //reply,err := client.GetLogicalDevicePort(context.Background(),&id) |
| 484 | if err != nil { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 485 | return nil, err |
| 486 | } |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 487 | ports := reply.GetItems() |
| 488 | var entries []*ofp.PortStatsEntry |
| 489 | if request.GetPortNo() == 0xffffffff { //all ports |
| 490 | for i := 0; i < len(ports); i++ { |
| 491 | port := ports[i] |
| 492 | entry := parsePortStats(port) |
| 493 | entries = append(entries, &entry) |
| 494 | } |
| 495 | } else { //find right port that is requested |
| 496 | for i := 0; i < len(ports); i++ { |
| 497 | if ports[i].GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) { |
| 498 | entry := parsePortStats(ports[i]) |
| 499 | entries = append(entries, &entry) |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | response.SetEntries(entries) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 504 | return response, nil |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 505 | } |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 506 | |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 507 | func handlePortDescStatsRequest(request *ofp.PortDescStatsRequest, DeviceID string) (*ofp.PortDescStatsReply, error) { |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 508 | response := ofp.NewPortDescStatsReply() |
| 509 | response.SetVersion(request.GetVersion()) |
| 510 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 511 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 512 | var grpcClient = *getGrpcClient() |
Don Newton | 7577f07 | 2020-01-06 12:41:11 -0500 | [diff] [blame] | 513 | var id = common.ID{Id: DeviceID} |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 514 | logicalDevice, err := grpcClient.GetLogicalDevice(context.Background(), &id) |
| 515 | if err != nil { |
| 516 | return nil, err |
| 517 | } |
| 518 | ports := logicalDevice.GetPorts() |
| 519 | var entries []*ofp.PortDesc |
| 520 | for i := 0; i < len(ports); i++ { |
| 521 | var entry ofp.PortDesc |
| 522 | port := ports[i].GetOfpPort() |
| 523 | entry.SetPortNo(ofp.Port(port.GetPortNo())) |
| 524 | |
| 525 | intArray := port.GetHwAddr() |
| 526 | var octets []byte |
| 527 | for i := 0; i < len(intArray); i++ { |
| 528 | octets = append(octets, byte(intArray[i])) |
| 529 | } |
| 530 | hwAddr := net.HardwareAddr(octets) |
| 531 | entry.SetHwAddr(hwAddr) |
| 532 | entry.SetName(PadString(port.GetName(), 16)) |
| 533 | entry.SetConfig(ofp.PortConfig(port.GetConfig())) |
| 534 | entry.SetState(ofp.PortState(port.GetState())) |
| 535 | entry.SetCurr(ofp.PortFeatures(port.GetCurr())) |
| 536 | entry.SetAdvertised(ofp.PortFeatures(port.GetAdvertised())) |
| 537 | entry.SetSupported(ofp.PortFeatures(port.GetSupported())) |
| 538 | entry.SetPeer(ofp.PortFeatures(port.GetPeer())) |
| 539 | entry.SetCurrSpeed(port.GetCurrSpeed()) |
| 540 | entry.SetMaxSpeed(port.GetMaxSpeed()) |
| 541 | |
| 542 | entries = append(entries, &entry) |
| 543 | } |
| 544 | |
| 545 | response.SetEntries(entries) |
| 546 | //TODO call voltha and get port descriptions etc |
| 547 | return response, nil |
| 548 | |
| 549 | } |
| 550 | func handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) { |
| 551 | response := ofp.NewMeterFeaturesStatsReply() |
| 552 | response.SetXid(request.GetXid()) |
| 553 | response.SetVersion(request.GetVersion()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 554 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
| 555 | meterFeatures := ofp.NewMeterFeatures() |
| 556 | meterFeatures.Capabilities = ofp.OFPMFKbps |
| 557 | meterFeatures.BandTypes = ofp.OFPMBTDrop |
| 558 | meterFeatures.MaxMeter = 0xffffffff |
| 559 | meterFeatures.MaxBands = 0xff |
| 560 | meterFeatures.MaxColor = 0xff |
| 561 | response.Features = *meterFeatures |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 562 | return response, nil |
| 563 | } |
| 564 | func handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest, id common.ID) (*ofp.ExperimenterStatsReply, error) { |
| 565 | response := ofp.NewExperimenterStatsReply(request.GetExperimenter()) |
| 566 | response.SetVersion(request.GetVersion()) |
| 567 | response.SetXid(request.GetXid()) |
Don Newton | e0d34a8 | 2019-11-14 10:58:06 -0500 | [diff] [blame] | 568 | response.SetFlags(ofp.StatsReplyFlags(request.GetFlags())) |
Don Newton | 98fd881 | 2019-09-23 15:15:02 -0400 | [diff] [blame] | 569 | //TODO wire this to voltha core when it implements |
| 570 | return response, nil |
| 571 | } |